Branch data Line data Source code
1 : : // Copyright (C) 2020-2025 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_AST_RESOLVE_TYPE_H
20 : : #define RUST_AST_RESOLVE_TYPE_H
21 : :
22 : : #include "rust-ast-resolve-base.h"
23 : : #include "rust-ast-resolve-expr.h"
24 : : #include "rust-diagnostics.h"
25 : : #include "rust-hir-map.h"
26 : : #include "rust-path.h"
27 : : #include "rust-type.h"
28 : : #include "util/rust-hir-map.h"
29 : :
30 : : namespace Rust {
31 : : namespace Resolver {
32 : :
33 : : class ResolveRelativeTypePath
34 : : {
35 : : public:
36 : : static bool go (AST::TypePath &path, NodeId &resolved_node_id);
37 : : };
38 : :
39 : 171 : class ResolveRelativeQualTypePath : public ResolverBase
40 : : {
41 : : using ResolverBase::visit;
42 : :
43 : : public:
44 : : static bool go (AST::QualifiedPathInType &path);
45 : :
46 : : void visit (AST::TypePathSegmentGeneric &seg) override;
47 : :
48 : : void visit (AST::TypePathSegment &seg) override;
49 : :
50 : : protected:
51 : : bool resolve_qual_seg (AST::QualifiedPathType &seg);
52 : :
53 : : private:
54 : : ResolveRelativeQualTypePath ();
55 : :
56 : : bool failure_flag;
57 : : };
58 : :
59 : 56420 : class ResolveType : public ResolverBase
60 : : {
61 : : using Rust::Resolver::ResolverBase::visit;
62 : :
63 : : public:
64 : : static NodeId go (AST::Type &type);
65 : :
66 : : void visit (AST::BareFunctionType &fntype) override;
67 : : void visit (AST::TupleType &tuple) override;
68 : : void visit (AST::TypePath &path) override;
69 : : void visit (AST::QualifiedPathInType &path) override;
70 : : void visit (AST::ArrayType &type) override;
71 : : void visit (AST::ReferenceType &type) override;
72 : : void visit (AST::InferredType &type) override;
73 : : void visit (AST::NeverType &type) override;
74 : : void visit (AST::RawPointerType &type) override;
75 : : void visit (AST::TraitObjectTypeOneBound &type) override;
76 : : void visit (AST::TraitObjectType &type) override;
77 : : void visit (AST::ParenthesisedType &type) override;
78 : : void visit (AST::SliceType &type) override;
79 : : void visit (AST::ImplTraitType &type) override;
80 : : void visit (AST::ImplTraitTypeOneBound &type) override;
81 : :
82 : : private:
83 : 56420 : ResolveType () : ResolverBase () {}
84 : : };
85 : :
86 : 959 : class ResolveTypeBound : public ResolverBase
87 : : {
88 : : using Rust::Resolver::ResolverBase::visit;
89 : :
90 : : public:
91 : 959 : static NodeId go (AST::TypeParamBound &type)
92 : : {
93 : 1918 : ResolveTypeBound resolver;
94 : 959 : type.accept_vis (resolver);
95 : 959 : return resolver.resolved_node;
96 : 959 : };
97 : :
98 : 947 : void visit (AST::TraitBound &bound) override
99 : : {
100 : 947 : resolved_node = ResolveType::go (bound.get_type_path ());
101 : 947 : }
102 : :
103 : : private:
104 : 959 : ResolveTypeBound () : ResolverBase () {}
105 : : };
106 : :
107 : 8327 : class ResolveGenericParams : public ResolverBase
108 : : {
109 : : using Rust::Resolver::ResolverBase::visit;
110 : :
111 : : public:
112 : 5660 : static void go (std::vector<std::unique_ptr<AST::GenericParam>> ¶ms,
113 : : const CanonicalPath &prefix,
114 : : const CanonicalPath &canonical_prefix)
115 : : {
116 : 11320 : ResolveGenericParams resolver (prefix, canonical_prefix);
117 : :
118 : : // this needs to be done in two phases as they can be used and defined later
119 : : // in bounds
120 : 9411 : for (auto ¶m : params)
121 : 3751 : param->accept_vis (resolver);
122 : :
123 : 5660 : resolver.first_pass = false;
124 : :
125 : 9411 : for (auto ¶m : params)
126 : 3751 : param->accept_vis (resolver);
127 : 5660 : }
128 : :
129 : 2667 : static void go_single (AST::GenericParam ¶m, const CanonicalPath &prefix,
130 : : const CanonicalPath &canonical_prefix)
131 : : {
132 : 5334 : ResolveGenericParams resolver (prefix, canonical_prefix);
133 : :
134 : 2667 : param.accept_vis (resolver);
135 : 2667 : resolver.first_pass = false;
136 : 2667 : param.accept_vis (resolver);
137 : 2667 : }
138 : :
139 : 54 : void visit (AST::ConstGenericParam ¶m) override
140 : : {
141 : 54 : if (first_pass)
142 : 27 : ResolveType::go (param.get_type ());
143 : 27 : else if (param.has_default_value ())
144 : 15 : ResolveExpr::go (param.get_default_value ().get_expression (), prefix,
145 : : canonical_prefix);
146 : 54 : }
147 : :
148 : 12434 : void visit (AST::TypeParam ¶m) override
149 : : {
150 : 12434 : if (first_pass)
151 : : {
152 : : // if it has a type lets resolve it
153 : 6217 : if (param.has_type ())
154 : 155 : ResolveType::go (param.get_type ());
155 : :
156 : 6217 : auto seg = CanonicalPath::new_seg (
157 : 6217 : param.get_node_id (), param.get_type_representation ().as_string ());
158 : 6217 : resolver->get_type_scope ().insert (
159 : : seg, param.get_node_id (), param.get_locus (), false,
160 : : Rib::ItemType::Type,
161 : 0 : [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
162 : 0 : rust_error_at (param.get_locus (),
163 : : "generic param defined multiple times");
164 : 0 : rust_error_at (locus, "was defined here");
165 : 0 : });
166 : :
167 : 6217 : mappings.insert_canonical_path (param.get_node_id (), seg);
168 : 6217 : }
169 : 6217 : else if (param.has_type_param_bounds ())
170 : : {
171 : 671 : for (auto &bound : param.get_type_param_bounds ())
172 : 339 : ResolveTypeBound::go (*bound);
173 : : }
174 : 12434 : }
175 : :
176 : : private:
177 : 8327 : ResolveGenericParams (const CanonicalPath &prefix,
178 : : const CanonicalPath &canonical_prefix)
179 : 16654 : : ResolverBase (), first_pass (true), prefix (prefix),
180 : 8327 : canonical_prefix (canonical_prefix)
181 : : {}
182 : :
183 : : bool first_pass;
184 : : const CanonicalPath &prefix;
185 : : const CanonicalPath &canonical_prefix;
186 : : };
187 : :
188 : 100 : class ResolveWhereClause : public ResolverBase
189 : : {
190 : : using Rust::Resolver::ResolverBase::visit;
191 : :
192 : : public:
193 : 100 : static void Resolve (AST::WhereClause &where_clause)
194 : : {
195 : 200 : ResolveWhereClause r;
196 : 202 : for (auto &clause : where_clause.get_items ())
197 : 102 : clause->accept_vis (r);
198 : 100 : }
199 : :
200 : 100 : void visit (AST::TypeBoundWhereClauseItem &item) override
201 : : {
202 : 100 : ResolveType::go (item.get_type ());
203 : 100 : if (item.has_type_param_bounds ())
204 : : {
205 : 200 : for (auto &bound : item.get_type_param_bounds ())
206 : : {
207 : 100 : ResolveTypeBound::go (*bound);
208 : : }
209 : : }
210 : 100 : }
211 : :
212 : : private:
213 : 100 : ResolveWhereClause () : ResolverBase () {}
214 : : };
215 : :
216 : 9065 : class ResolveTypeToCanonicalPath : public ResolverBase
217 : : {
218 : : using Rust::Resolver::ResolverBase::visit;
219 : :
220 : : public:
221 : : static bool go (AST::Type &type, CanonicalPath &result);
222 : :
223 : : void visit (AST::TypePath &path) override;
224 : :
225 : : void visit (AST::ReferenceType &type) override;
226 : :
227 : : void visit (AST::RawPointerType &type) override;
228 : :
229 : : void visit (AST::SliceType &type) override;
230 : :
231 : : void visit (AST::TraitObjectTypeOneBound &type) override;
232 : :
233 : : void visit (AST::TraitObjectType &type) override;
234 : :
235 : : void visit (AST::NeverType &type) override;
236 : :
237 : : void visit (AST::TupleType &type) override;
238 : :
239 : : private:
240 : : ResolveTypeToCanonicalPath ();
241 : :
242 : : CanonicalPath result;
243 : : };
244 : :
245 : 3344 : class ResolveGenericArgs : public ResolverBase
246 : : {
247 : : using Rust::Resolver::ResolverBase::visit;
248 : :
249 : : public:
250 : : static void go (AST::GenericArgs &generic_args);
251 : : static void go (AST::GenericArgs &generic_args, const CanonicalPath &prefix,
252 : : const CanonicalPath &canonical_prefix);
253 : :
254 : : private:
255 : 3344 : ResolveGenericArgs (const CanonicalPath &prefix,
256 : : const CanonicalPath &canonical_prefix)
257 : 3344 : : ResolverBase (), prefix (prefix), canonical_prefix (canonical_prefix)
258 : : {}
259 : :
260 : : bool is_type_name (const CanonicalPath &path);
261 : : bool is_const_value_name (const CanonicalPath &path);
262 : :
263 : : /**
264 : : * Resolve a disambiguated generic arg
265 : : */
266 : : void disambiguate (AST::GenericArg &arg);
267 : :
268 : : /**
269 : : * Resolve a disambiguated generic arg
270 : : */
271 : : void resolve_disambiguated_generic (AST::GenericArg &arg);
272 : :
273 : : const CanonicalPath &prefix;
274 : : const CanonicalPath &canonical_prefix;
275 : : };
276 : :
277 : : } // namespace Resolver
278 : : } // namespace Rust
279 : :
280 : : #endif // RUST_AST_RESOLVE_TYPE_H
|