]>
Commit | Line | Data |
---|---|---|
83ffe9cd | 1 | // Copyright (C) 2020-2023 Free Software Foundation, Inc. |
85a8fe00 PH |
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-ast-full.h" | |
25 | ||
26 | namespace Rust { | |
27 | namespace Resolver { | |
28 | ||
29 | class ResolveRelativeTypePath | |
30 | { | |
31 | public: | |
32 | static bool go (AST::TypePath &path, NodeId &resolved_node_id); | |
33 | }; | |
34 | ||
35 | class ResolveRelativeQualTypePath : public ResolverBase | |
36 | { | |
37 | using ResolverBase::visit; | |
38 | ||
39 | public: | |
40 | static bool go (AST::QualifiedPathInType &path); | |
41 | ||
42 | void visit (AST::TypePathSegmentGeneric &seg) override; | |
43 | ||
44 | void visit (AST::TypePathSegment &seg) override; | |
45 | ||
46 | protected: | |
47 | bool resolve_qual_seg (AST::QualifiedPathType &seg); | |
48 | ||
49 | private: | |
50 | ResolveRelativeQualTypePath (); | |
51 | ||
52 | bool failure_flag; | |
53 | }; | |
54 | ||
55 | class ResolveType : public ResolverBase | |
56 | { | |
57 | using Rust::Resolver::ResolverBase::visit; | |
58 | ||
59 | public: | |
60 | static NodeId go (AST::Type *type) | |
61 | { | |
62 | ResolveType resolver; | |
63 | type->accept_vis (resolver); | |
64 | return resolver.resolved_node; | |
65 | } | |
66 | ||
67 | void visit (AST::BareFunctionType &fntype) override | |
68 | { | |
69 | for (auto ¶m : fntype.get_function_params ()) | |
70 | ResolveType::go (param.get_type ().get ()); | |
71 | ||
72 | if (fntype.has_return_type ()) | |
73 | ResolveType::go (fntype.get_return_type ().get ()); | |
74 | } | |
75 | ||
76 | void visit (AST::TupleType &tuple) override | |
77 | { | |
78 | if (tuple.is_unit_type ()) | |
79 | { | |
80 | resolved_node = resolver->get_unit_type_node_id (); | |
81 | return; | |
82 | } | |
83 | ||
84 | for (auto &elem : tuple.get_elems ()) | |
85 | ResolveType::go (elem.get ()); | |
86 | } | |
87 | ||
88 | void visit (AST::TypePath &path) override | |
89 | { | |
90 | ResolveRelativeTypePath::go (path, resolved_node); | |
91 | } | |
92 | ||
93 | void visit (AST::QualifiedPathInType &path) override | |
94 | { | |
95 | ResolveRelativeQualTypePath::go (path); | |
96 | } | |
97 | ||
98 | void visit (AST::ArrayType &type) override; | |
99 | ||
100 | void visit (AST::ReferenceType &type) override; | |
101 | ||
102 | void visit (AST::InferredType &type) override; | |
103 | ||
104 | void visit (AST::NeverType &type) override; | |
105 | ||
106 | void visit (AST::RawPointerType &type) override; | |
107 | ||
108 | void visit (AST::TraitObjectTypeOneBound &type) override; | |
109 | ||
110 | void visit (AST::TraitObjectType &type) override; | |
111 | ||
112 | void visit (AST::SliceType &type) override; | |
113 | ||
114 | private: | |
115 | ResolveType () : ResolverBase () {} | |
116 | }; | |
117 | ||
118 | class ResolveTypeBound : public ResolverBase | |
119 | { | |
120 | using Rust::Resolver::ResolverBase::visit; | |
121 | ||
122 | public: | |
123 | static NodeId go (AST::TypeParamBound *type) | |
124 | { | |
125 | ResolveTypeBound resolver; | |
126 | type->accept_vis (resolver); | |
127 | return resolver.resolved_node; | |
128 | }; | |
129 | ||
130 | void visit (AST::TraitBound &bound) override | |
131 | { | |
132 | resolved_node = ResolveType::go (&bound.get_type_path ()); | |
133 | } | |
134 | ||
135 | private: | |
136 | ResolveTypeBound () : ResolverBase () {} | |
137 | }; | |
138 | ||
139 | class ResolveGenericParam : public ResolverBase | |
140 | { | |
141 | using Rust::Resolver::ResolverBase::visit; | |
142 | ||
143 | public: | |
144 | static NodeId go (AST::GenericParam *param, const CanonicalPath &prefix, | |
145 | const CanonicalPath &canonical_prefix) | |
146 | { | |
147 | ResolveGenericParam resolver (prefix, canonical_prefix); | |
148 | param->accept_vis (resolver); | |
149 | return resolver.resolved_node; | |
150 | } | |
151 | ||
152 | void visit (AST::ConstGenericParam ¶m) override | |
153 | { | |
154 | ResolveType::go (param.get_type ().get ()); | |
155 | ||
156 | if (param.has_default_value ()) | |
157 | ResolveExpr::go (param.get_default_value ().get_expression ().get (), | |
158 | prefix, canonical_prefix); | |
159 | ||
160 | ok = true; | |
161 | } | |
162 | ||
163 | void visit (AST::TypeParam ¶m) override | |
164 | { | |
165 | // if it has a type lets resolve it | |
166 | if (param.has_type ()) | |
167 | ResolveType::go (param.get_type ().get ()); | |
168 | ||
169 | if (param.has_type_param_bounds ()) | |
170 | { | |
171 | for (auto &bound : param.get_type_param_bounds ()) | |
172 | { | |
173 | ResolveTypeBound::go (bound.get ()); | |
174 | } | |
175 | } | |
176 | ||
177 | auto seg = CanonicalPath::new_seg (param.get_node_id (), | |
178 | param.get_type_representation ()); | |
179 | resolver->get_type_scope ().insert ( | |
180 | seg, param.get_node_id (), param.get_locus (), false, | |
181 | [&] (const CanonicalPath &, NodeId, Location locus) -> void { | |
182 | rust_error_at (param.get_locus (), | |
183 | "generic param redefined multiple times"); | |
184 | rust_error_at (locus, "was defined here"); | |
185 | }); | |
186 | ||
187 | mappings->insert_canonical_path (param.get_node_id (), seg); | |
188 | } | |
189 | ||
190 | private: | |
191 | ResolveGenericParam (const CanonicalPath &prefix, | |
192 | const CanonicalPath &canonical_prefix) | |
193 | : ResolverBase (), ok (false), prefix (prefix), | |
194 | canonical_prefix (canonical_prefix) | |
195 | {} | |
196 | ||
197 | bool ok; | |
198 | const CanonicalPath &prefix; | |
199 | const CanonicalPath &canonical_prefix; | |
200 | }; | |
201 | ||
202 | class ResolveWhereClause : public ResolverBase | |
203 | { | |
204 | using Rust::Resolver::ResolverBase::visit; | |
205 | ||
206 | public: | |
207 | static void Resolve (AST::WhereClause &where_clause) | |
208 | { | |
209 | ResolveWhereClause r; | |
210 | for (auto &clause : where_clause.get_items ()) | |
211 | clause->accept_vis (r); | |
212 | } | |
213 | ||
214 | void visit (AST::TypeBoundWhereClauseItem &item) override | |
215 | { | |
216 | ResolveType::go (item.get_type ().get ()); | |
217 | if (item.has_type_param_bounds ()) | |
218 | { | |
219 | for (auto &bound : item.get_type_param_bounds ()) | |
220 | { | |
221 | ResolveTypeBound::go (bound.get ()); | |
222 | } | |
223 | } | |
224 | } | |
225 | ||
226 | private: | |
227 | ResolveWhereClause () : ResolverBase () {} | |
228 | }; | |
229 | ||
230 | class ResolveTypeToCanonicalPath : public ResolverBase | |
231 | { | |
232 | using Rust::Resolver::ResolverBase::visit; | |
233 | ||
234 | public: | |
235 | static bool go (AST::Type *type, CanonicalPath &result); | |
236 | ||
237 | void visit (AST::TypePath &path) override; | |
238 | ||
239 | void visit (AST::ReferenceType &type) override; | |
240 | ||
241 | void visit (AST::RawPointerType &type) override; | |
242 | ||
243 | void visit (AST::SliceType &type) override; | |
244 | ||
245 | void visit (AST::TraitObjectTypeOneBound &type) override; | |
246 | ||
247 | void visit (AST::TraitObjectType &type) override; | |
248 | ||
249 | private: | |
250 | ResolveTypeToCanonicalPath (); | |
251 | ||
252 | CanonicalPath result; | |
253 | }; | |
254 | ||
255 | class ResolveGenericArgs : public ResolverBase | |
256 | { | |
257 | using Rust::Resolver::ResolverBase::visit; | |
258 | ||
259 | public: | |
260 | static void go (AST::GenericArgs &generic_args); | |
261 | static void go (AST::GenericArgs &generic_args, const CanonicalPath &prefix, | |
262 | const CanonicalPath &canonical_prefix); | |
263 | ||
264 | private: | |
265 | ResolveGenericArgs (const CanonicalPath &prefix, | |
266 | const CanonicalPath &canonical_prefix) | |
267 | : ResolverBase (), prefix (prefix), canonical_prefix (canonical_prefix) | |
268 | {} | |
269 | ||
270 | bool is_type_name (const CanonicalPath &path); | |
271 | bool is_const_value_name (const CanonicalPath &path); | |
272 | ||
273 | /** | |
274 | * Resolve a disambiguated generic arg | |
275 | */ | |
276 | void disambiguate (AST::GenericArg &arg); | |
277 | ||
278 | /** | |
279 | * Resolve a disambiguated generic arg | |
280 | */ | |
281 | void resolve_disambiguated_generic (AST::GenericArg &arg); | |
282 | ||
283 | const CanonicalPath &prefix; | |
284 | const CanonicalPath &canonical_prefix; | |
285 | }; | |
286 | ||
287 | } // namespace Resolver | |
288 | } // namespace Rust | |
289 | ||
290 | #endif // RUST_AST_RESOLVE_TYPE_H |