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 : #include "rust-hir-impl-trait-context.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 16469 : 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_t locus);
47 :
48 : TraitItemReference (TraitItemReference const &other);
49 :
50 : TraitItemReference &operator= (TraitItemReference const &other);
51 :
52 3616 : static TraitItemReference error ()
53 : {
54 3616 : return TraitItemReference ("", false, ERROR, nullptr, nullptr, {},
55 3616 : UNDEF_LOCATION);
56 : }
57 :
58 672 : static TraitItemReference &error_node ()
59 : {
60 686 : static TraitItemReference error = TraitItemReference::error ();
61 672 : return error;
62 : }
63 :
64 : bool is_error () const;
65 :
66 : std::string as_string () const;
67 :
68 299 : static std::string trait_item_type_as_string (TraitItemType ty)
69 : {
70 299 : switch (ty)
71 : {
72 239 : case FN:
73 239 : return "FN";
74 0 : case CONST:
75 0 : return "CONST";
76 60 : case TYPE:
77 60 : return "TYPE";
78 0 : case ERROR:
79 0 : return "ERROR";
80 : }
81 0 : 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_t 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 (const TraitReference *tref);
106 :
107 : void resolve_default_function_body (const TraitReference *tref);
108 :
109 : bool is_object_safe () const;
110 :
111 : private:
112 : TyTy::ErrorType *get_error () const;
113 :
114 : TyTy::BaseType *get_type_from_typealias (/*const*/
115 : HIR::TraitItemType &type) const;
116 :
117 : TyTy::BaseType *
118 : get_type_from_constant (/*const*/ HIR::TraitItemConst &constant) const;
119 :
120 : TyTy::BaseType *get_type_from_fn (/*const*/ HIR::TraitItemFunc &fn) const;
121 :
122 : bool is_item_resolved () const;
123 : void resolve_item (const TraitReference *tref, HIR::TraitItemType &type);
124 : void resolve_item (const TraitReference *tref, HIR::TraitItemConst &constant);
125 : void resolve_item (const TraitReference *tref, HIR::TraitItemFunc &func);
126 :
127 : std::string identifier;
128 : bool optional_flag;
129 : TraitItemType type;
130 : HIR::TraitItem *hir_trait_item;
131 : std::vector<TyTy::SubstitutionParamMapping> inherited_substitutions;
132 : location_t locus;
133 :
134 : TyTy::BaseType
135 : *self; // this is the implict Self TypeParam required for methods
136 : Resolver::TypeCheckContext *context;
137 : };
138 :
139 : // this wraps up the HIR::Trait so we can do analysis on it
140 :
141 : class TraitReference
142 : {
143 : public:
144 : TraitReference (const HIR::Trait *hir_trait_ref,
145 : std::vector<TraitItemReference> item_refs,
146 : std::vector<TyTy::TypeBoundPredicate> super_traits,
147 : std::vector<TyTy::SubstitutionParamMapping> substs);
148 :
149 : TraitReference (TraitReference const &other);
150 :
151 : TraitReference &operator= (TraitReference const &other);
152 :
153 4167 : TraitReference (TraitReference &&other) = default;
154 : TraitReference &operator= (TraitReference &&other) = default;
155 :
156 2087 : static TraitReference error ()
157 : {
158 2087 : return TraitReference (nullptr, {}, {}, {});
159 : }
160 :
161 : bool is_error () const;
162 :
163 196407 : static TraitReference &error_node ()
164 : {
165 198494 : static TraitReference trait_error_node = TraitReference::error ();
166 196407 : return trait_error_node;
167 : }
168 :
169 : location_t get_locus () const;
170 :
171 : std::string get_name () const;
172 :
173 : std::string as_string () const;
174 :
175 : const HIR::Trait *get_hir_trait_ref () const;
176 :
177 : const Analysis::NodeMapping &get_mappings () const;
178 :
179 : DefId get_defid () const;
180 :
181 : bool lookup_hir_trait_item (const HIR::TraitItem &item,
182 : TraitItemReference **ref);
183 :
184 : bool lookup_trait_item (const std::string &ident, TraitItemReference **ref);
185 :
186 : bool lookup_trait_item_by_type (const std::string &ident,
187 : TraitItemReference::TraitItemType type,
188 : TraitItemReference **ref);
189 :
190 : bool lookup_trait_item_by_type (const std::string &ident,
191 : TraitItemReference::TraitItemType type,
192 : const TraitItemReference **ref) const;
193 :
194 : bool lookup_hir_trait_item (const HIR::TraitItem &item,
195 : const TraitItemReference **ref) const;
196 :
197 : bool lookup_trait_item (const std::string &ident,
198 : const TraitItemReference **ref,
199 : bool lookup_supers = true) const;
200 :
201 : const TraitItemReference *
202 : lookup_trait_item (const std::string &ident,
203 : TraitItemReference::TraitItemType type) const;
204 :
205 : size_t size () const;
206 :
207 : const std::vector<TraitItemReference> &get_trait_items () const;
208 :
209 : void get_trait_items_and_supers (
210 : std::vector<const TraitItemReference *> &result) const;
211 :
212 : void on_resolved ();
213 :
214 : void resolve_default_function_bodies ();
215 :
216 : bool is_equal (const TraitReference &other) const;
217 :
218 : std::vector<TyTy::TypeBoundPredicate> get_super_traits () const;
219 :
220 : bool is_object_safe (bool emit_error, location_t locus) const;
221 :
222 : bool trait_has_generics () const;
223 :
224 : std::vector<TyTy::SubstitutionParamMapping> &get_trait_substs ();
225 :
226 : const std::vector<TyTy::SubstitutionParamMapping> &get_trait_substs () const;
227 :
228 : bool satisfies_bound (const TraitReference &reference) const;
229 :
230 : private:
231 : const HIR::Trait *hir_trait_ref;
232 : std::vector<TraitItemReference> item_refs;
233 : std::vector<TyTy::TypeBoundPredicate> super_traits;
234 : std::vector<TyTy::SubstitutionParamMapping> trait_substs;
235 : };
236 :
237 : class AssociatedImplTrait
238 : {
239 : public:
240 : AssociatedImplTrait (TraitReference *trait,
241 : TyTy::TypeBoundPredicate predicate, HIR::ImplBlock *impl,
242 : TyTy::BaseType *self, ImplTraitContextFrame frame);
243 :
244 : TyTy::TypeBoundPredicate &get_predicate ();
245 :
246 : HIR::ImplBlock *get_impl_block ();
247 :
248 : location_t get_locus () const;
249 :
250 : TyTy::BaseType *get_self ();
251 : const TyTy::BaseType *get_self () const;
252 :
253 : ImplTraitContextFrame get_frame () const;
254 :
255 : TyTy::SubstitutionArgumentMappings
256 : bind_impl_for_projection (TyTy::ProjectionType &proj, location_t locus);
257 :
258 : TyTy::SubstitutionArgumentMappings
259 : bind_impl_for_bound (TyTy::BaseType *receiver,
260 : const TyTy::TypeBoundPredicate &bound, location_t locus,
261 : bool emit_error = false);
262 :
263 : private:
264 : TraitReference *trait;
265 : TyTy::TypeBoundPredicate predicate;
266 : HIR::ImplBlock *impl;
267 : TyTy::BaseType *self;
268 : Resolver::TypeCheckContext *context;
269 : ImplTraitContextFrame frame;
270 : };
271 :
272 : } // namespace Resolver
273 : } // namespace Rust
274 :
275 : #endif // RUST_HIR_TRAIT_REF_H
|