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