1 // Copyright (C) 2021-2023 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-hir-type-check-util.h"
24 #include "rust-tyty-visitor.h"
25
26 namespace Rust {
27 namespace Resolver {
28
29 // Data Objects for the associated trait items in a structure we can work with
30 // https://doc.rust-lang.org/edition-guide/rust-2018/trait-system/associated-constants.html
31 class TypeCheckContext;
32 class TraitItemReference
33 {
34 public:
35 enum TraitItemType
36 {
37 FN,
38 CONST,
39 TYPE,
40 ERROR
41 };
42
43 TraitItemReference (std::string identifier, bool optional, TraitItemType type,
44 HIR::TraitItem *hir_trait_item, TyTy::BaseType *self,
45 std::vector<TyTy::SubstitutionParamMapping> substitutions,
46 Location locus);
47
48 TraitItemReference (TraitItemReference const &other);
49
50 TraitItemReference &operator= (TraitItemReference const &other);
51
52 static TraitItemReference error ()
53 {
54 return TraitItemReference ("", false, ERROR, nullptr, nullptr, {},
55 Location ());
56 }
57
58 static TraitItemReference &error_node ()
59 {
60 static TraitItemReference error = TraitItemReference::error ();
61 return error;
62 }
63
64 bool is_error () const;
65
66 std::string as_string () const;
67
68 static std::string trait_item_type_as_string (TraitItemType ty)
69 {
70 switch (ty)
71 {
72 case FN:
73 return "FN";
74 case CONST:
75 return "CONST";
76 case TYPE:
77 return "TYPE";
78 case ERROR:
79 return "ERROR";
80 }
81 return "ERROR";
82 }
83
84 bool is_optional () const;
85
86 std::string get_identifier () const;
87
88 TraitItemType get_trait_item_type () const;
89
90 HIR::TraitItem *get_hir_trait_item () const;
91
92 Location get_locus () const;
93
94 const Analysis::NodeMapping get_mappings () const;
95
96 TyTy::BaseType *get_tyty () const;
97
98 Analysis::NodeMapping get_parent_trait_mappings () const;
99
100 // this is called when the trait is completed resolution and gives the items
101 // a chance to run their specific type resolution passes. If we call their
102 // resolution on construction it can lead to a case where the trait being
103 // resolved recursively trying to resolve the trait itself infinitely since
104 // the trait will not be stored in its own map yet
105 void on_resolved ();
106
107 void associated_type_set (TyTy::BaseType *ty) const;
108
109 void associated_type_reset (bool only_projections) const;
110
111 bool is_object_safe () const;
112
113 private:
114 TyTy::ErrorType *get_error () const;
115
116 TyTy::BaseType *get_type_from_typealias (/*const*/
117 HIR::TraitItemType &type) const;
118
119 TyTy::BaseType *
120 get_type_from_constant (/*const*/ HIR::TraitItemConst &constant) const;
121
122 TyTy::BaseType *get_type_from_fn (/*const*/ HIR::TraitItemFunc &fn) const;
123
124 bool is_item_resolved () const;
125 void resolve_item (HIR::TraitItemType &type);
126 void resolve_item (HIR::TraitItemConst &constant);
127 void resolve_item (HIR::TraitItemFunc &func);
128
129 std::string identifier;
130 bool optional_flag;
131 TraitItemType type;
132 HIR::TraitItem *hir_trait_item;
133 std::vector<TyTy::SubstitutionParamMapping> inherited_substitutions;
134 Location locus;
135
136 TyTy::BaseType
137 *self; // this is the implict Self TypeParam required for methods
138 Resolver::TypeCheckContext *context;
139 };
140
141 // this wraps up the HIR::Trait so we can do analysis on it
142
143 class TraitReference
144 {
145 public:
146 TraitReference (const HIR::Trait *hir_trait_ref,
147 std::vector<TraitItemReference> item_refs,
148 std::vector<const TraitReference *> super_traits,
149 std::vector<TyTy::SubstitutionParamMapping> substs);
150
151 TraitReference (TraitReference const &other);
152
153 TraitReference &operator= (TraitReference const &other);
154
155 TraitReference (TraitReference &&other) = default;
156 TraitReference &operator= (TraitReference &&other) = default;
157
158 static TraitReference error ()
159 {
160 return TraitReference (nullptr, {}, {}, {});
161 }
162
163 bool is_error () const;
164
165 static TraitReference &error_node ()
166 {
167 static TraitReference trait_error_node = TraitReference::error ();
168 return trait_error_node;
169 }
170
171 Location get_locus () const;
172
173 std::string get_name () const;
174
175 std::string as_string () const;
176
177 const HIR::Trait *get_hir_trait_ref () const;
178
179 const Analysis::NodeMapping &get_mappings () const;
180
181 DefId get_defid () const;
182
183 bool lookup_hir_trait_item (const HIR::TraitItem &item,
184 TraitItemReference **ref);
185
186 bool lookup_trait_item (const std::string &ident, TraitItemReference **ref);
187
188 bool lookup_trait_item_by_type (const std::string &ident,
189 TraitItemReference::TraitItemType type,
190 TraitItemReference **ref);
191
192 bool lookup_trait_item_by_type (const std::string &ident,
193 TraitItemReference::TraitItemType type,
194 const TraitItemReference **ref) const;
195
196 bool lookup_hir_trait_item (const HIR::TraitItem &item,
197 const TraitItemReference **ref) const;
198
199 bool lookup_trait_item (const std::string &ident,
200 const TraitItemReference **ref) 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 const std::vector<const TraitReference *> get_super_traits () const;
222
223 bool is_object_safe (bool emit_error, Location locus) const;
224
225 bool trait_has_generics () const;
226
227 std::vector<TyTy::SubstitutionParamMapping> get_trait_substs () const;
228
229 bool satisfies_bound (const TraitReference &reference) const;
230
231 private:
232 const HIR::Trait *hir_trait_ref;
233 std::vector<TraitItemReference> item_refs;
234 std::vector<const TraitReference *> super_traits;
235 std::vector<TyTy::SubstitutionParamMapping> trait_substs;
236 };
237
238 class AssociatedImplTrait
239 {
240 public:
241 AssociatedImplTrait (TraitReference *trait, HIR::ImplBlock *impl,
242 TyTy::BaseType *self,
243 Resolver::TypeCheckContext *context);
244
245 TraitReference *get_trait ();
246
247 HIR::ImplBlock *get_impl_block ();
248
249 TyTy::BaseType *get_self ();
250 const TyTy::BaseType *get_self () const;
251
252 TyTy::BaseType *
253 setup_associated_types (const TyTy::BaseType *self,
254 const TyTy::TypeBoundPredicate &bound);
255
256 void reset_associated_types ();
257
258 private:
259 TraitReference *trait;
260 HIR::ImplBlock *impl;
261 TyTy::BaseType *self;
262 Resolver::TypeCheckContext *context;
263 };
264
265 } // namespace Resolver
266 } // namespace Rust
267
268 #endif // RUST_HIR_TRAIT_REF_H