Line data Source code
1 : // Copyright (C) 2021-2026 Free Software Foundation, Inc.
2 :
3 : // This file is part of GCC.
4 :
5 : // GCC is free software; you can redistribute it and/or modify it under
6 : // the terms of the GNU General Public License as published by the Free
7 : // Software Foundation; either version 3, or (at your option) any later
8 : // version.
9 :
10 : // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 : // WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 : // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 : // for more details.
14 :
15 : // You should have received a copy of the GNU General Public License
16 : // along with GCC; see the file COPYING3. If not see
17 : // <http://www.gnu.org/licenses/>.
18 :
19 : #ifndef RUST_HIR_TRAIT_REF_H
20 : #define RUST_HIR_TRAIT_REF_H
21 :
22 : #include "rust-hir-full.h"
23 : #include "rust-tyty-visitor.h"
24 :
25 : namespace Rust {
26 : namespace Resolver {
27 :
28 : // Data Objects for the associated trait items in a structure we can work with
29 : // https://doc.rust-lang.org/edition-guide/rust-2018/trait-system/associated-constants.html
30 : class TypeCheckContext;
31 15148 : class TraitItemReference
32 : {
33 : public:
34 : enum TraitItemType
35 : {
36 : FN,
37 : CONST,
38 : TYPE,
39 : ERROR
40 : };
41 :
42 : TraitItemReference (std::string identifier, bool optional, TraitItemType type,
43 : HIR::TraitItem *hir_trait_item, TyTy::BaseType *self,
44 : std::vector<TyTy::SubstitutionParamMapping> substitutions,
45 : location_t locus);
46 :
47 : TraitItemReference (TraitItemReference const &other);
48 :
49 : TraitItemReference &operator= (TraitItemReference const &other);
50 :
51 3624 : static TraitItemReference error ()
52 : {
53 3624 : return TraitItemReference ("", false, ERROR, nullptr, nullptr, {},
54 3624 : UNDEF_LOCATION);
55 : }
56 :
57 130047 : static TraitItemReference &error_node ()
58 : {
59 130361 : static TraitItemReference error = TraitItemReference::error ();
60 130047 : return error;
61 : }
62 :
63 : bool is_error () const;
64 :
65 : std::string as_string () const;
66 :
67 5930 : static std::string trait_item_type_as_string (TraitItemType ty)
68 : {
69 5930 : switch (ty)
70 : {
71 5189 : case FN:
72 5189 : return "FN";
73 36 : case CONST:
74 36 : return "CONST";
75 705 : case TYPE:
76 705 : return "TYPE";
77 0 : case ERROR:
78 0 : return "ERROR";
79 : }
80 0 : return "ERROR";
81 : }
82 :
83 : bool is_optional () const;
84 :
85 : std::string get_identifier () const;
86 :
87 : TraitItemType get_trait_item_type () const;
88 :
89 : HIR::TraitItem *get_hir_trait_item () const;
90 :
91 : location_t get_locus () const;
92 :
93 : const Analysis::NodeMapping get_mappings () const;
94 :
95 : TyTy::BaseType *get_tyty () const;
96 :
97 : Analysis::NodeMapping get_parent_trait_mappings () const;
98 :
99 : // this is called when the trait is completed resolution and gives the items
100 : // a chance to run their specific type resolution passes. If we call their
101 : // resolution on construction it can lead to a case where the trait being
102 : // resolved recursively trying to resolve the trait itself infinitely since
103 : // the trait will not be stored in its own map yet
104 : void on_resolved ();
105 :
106 : void associated_type_set (TyTy::BaseType *ty) const;
107 :
108 : void associated_type_reset (bool only_projections) const;
109 :
110 : bool is_object_safe () const;
111 :
112 : private:
113 : TyTy::ErrorType *get_error () const;
114 :
115 : TyTy::BaseType *get_type_from_typealias (/*const*/
116 : HIR::TraitItemType &type) const;
117 :
118 : TyTy::BaseType *
119 : get_type_from_constant (/*const*/ HIR::TraitItemConst &constant) const;
120 :
121 : TyTy::BaseType *get_type_from_fn (/*const*/ HIR::TraitItemFunc &fn) const;
122 :
123 : bool is_item_resolved () const;
124 : void resolve_item (HIR::TraitItemType &type);
125 : void resolve_item (HIR::TraitItemConst &constant);
126 : void resolve_item (HIR::TraitItemFunc &func);
127 :
128 : std::string identifier;
129 : bool optional_flag;
130 : TraitItemType type;
131 : HIR::TraitItem *hir_trait_item;
132 : std::vector<TyTy::SubstitutionParamMapping> inherited_substitutions;
133 : location_t locus;
134 :
135 : TyTy::BaseType
136 : *self; // this is the implict Self TypeParam required for methods
137 : Resolver::TypeCheckContext *context;
138 : };
139 :
140 : // this wraps up the HIR::Trait so we can do analysis on it
141 :
142 : class TraitReference
143 : {
144 : public:
145 : TraitReference (const HIR::Trait *hir_trait_ref,
146 : std::vector<TraitItemReference> item_refs,
147 : std::vector<TyTy::TypeBoundPredicate> super_traits,
148 : std::vector<TyTy::SubstitutionParamMapping> substs);
149 :
150 : TraitReference (TraitReference const &other);
151 :
152 : TraitReference &operator= (TraitReference const &other);
153 :
154 3680 : TraitReference (TraitReference &&other) = default;
155 : TraitReference &operator= (TraitReference &&other) = default;
156 :
157 1797 : static TraitReference error ()
158 : {
159 1797 : return TraitReference (nullptr, {}, {}, {});
160 : }
161 :
162 : bool is_error () const;
163 :
164 579368 : static TraitReference &error_node ()
165 : {
166 581165 : static TraitReference trait_error_node = TraitReference::error ();
167 579368 : return trait_error_node;
168 : }
169 :
170 : location_t get_locus () const;
171 :
172 : std::string get_name () const;
173 :
174 : std::string as_string () const;
175 :
176 : const HIR::Trait *get_hir_trait_ref () const;
177 :
178 : const Analysis::NodeMapping &get_mappings () const;
179 :
180 : DefId get_defid () const;
181 :
182 : bool lookup_hir_trait_item (const HIR::TraitItem &item,
183 : TraitItemReference **ref);
184 :
185 : bool lookup_trait_item (const std::string &ident, TraitItemReference **ref);
186 :
187 : bool lookup_trait_item_by_type (const std::string &ident,
188 : TraitItemReference::TraitItemType type,
189 : TraitItemReference **ref);
190 :
191 : bool lookup_trait_item_by_type (const std::string &ident,
192 : TraitItemReference::TraitItemType type,
193 : const TraitItemReference **ref) const;
194 :
195 : bool lookup_hir_trait_item (const HIR::TraitItem &item,
196 : const TraitItemReference **ref) const;
197 :
198 : bool lookup_trait_item (const std::string &ident,
199 : const TraitItemReference **ref,
200 : bool lookup_supers = true) const;
201 :
202 : const TraitItemReference *
203 : lookup_trait_item (const std::string &ident,
204 : TraitItemReference::TraitItemType type) const;
205 :
206 : size_t size () const;
207 :
208 : const std::vector<TraitItemReference> &get_trait_items () const;
209 :
210 : void get_trait_items_and_supers (
211 : std::vector<const TraitItemReference *> &result) const;
212 :
213 : void on_resolved ();
214 :
215 : void clear_associated_types () const;
216 :
217 : void clear_associated_type_projections () const;
218 :
219 : bool is_equal (const TraitReference &other) const;
220 :
221 : std::vector<TyTy::TypeBoundPredicate> get_super_traits () const;
222 :
223 : bool is_object_safe (bool emit_error, location_t locus) const;
224 :
225 : bool trait_has_generics () const;
226 :
227 : std::vector<TyTy::SubstitutionParamMapping> &get_trait_substs ();
228 :
229 : const std::vector<TyTy::SubstitutionParamMapping> &get_trait_substs () const;
230 :
231 : bool satisfies_bound (const TraitReference &reference) const;
232 :
233 : private:
234 : const HIR::Trait *hir_trait_ref;
235 : std::vector<TraitItemReference> item_refs;
236 : std::vector<TyTy::TypeBoundPredicate> super_traits;
237 : std::vector<TyTy::SubstitutionParamMapping> trait_substs;
238 : };
239 :
240 4651 : class AssociatedImplTrait
241 : {
242 : public:
243 : AssociatedImplTrait (TraitReference *trait,
244 : TyTy::TypeBoundPredicate predicate, HIR::ImplBlock *impl,
245 : TyTy::BaseType *self,
246 : Resolver::TypeCheckContext *context);
247 :
248 : TyTy::TypeBoundPredicate &get_predicate ();
249 :
250 : HIR::ImplBlock *get_impl_block ();
251 :
252 : location_t get_locus () const;
253 :
254 : TyTy::BaseType *get_self ();
255 : const TyTy::BaseType *get_self () const;
256 :
257 : void setup_raw_associated_types ();
258 :
259 : TyTy::BaseType *setup_associated_types (
260 : const TyTy::BaseType *self, const TyTy::TypeBoundPredicate &bound,
261 : TyTy::SubstitutionArgumentMappings *args = nullptr, bool infer = true);
262 :
263 : void reset_associated_types ();
264 :
265 : private:
266 : TraitReference *trait;
267 : TyTy::TypeBoundPredicate predicate;
268 : HIR::ImplBlock *impl;
269 : TyTy::BaseType *self;
270 : Resolver::TypeCheckContext *context;
271 : };
272 :
273 : } // namespace Resolver
274 : } // namespace Rust
275 :
276 : #endif // RUST_HIR_TRAIT_REF_H
|