]> gcc.gnu.org Git - gcc.git/blob - gcc/rust/resolve/rust-ast-resolve-type.h
resolver: Disambiguate generic args
[gcc.git] / gcc / rust / resolve / rust-ast-resolve-type.h
1 // Copyright (C) 2020-2022 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-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 &param : 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 &param) 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 &param) 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 private:
246 ResolveTypeToCanonicalPath ();
247
248 CanonicalPath result;
249 };
250
251 class ResolveGenericArgs : public ResolverBase
252 {
253 using Rust::Resolver::ResolverBase::visit;
254
255 public:
256 static void go (AST::GenericArgs &generic_args);
257 static void go (AST::GenericArgs &generic_args, const CanonicalPath &prefix,
258 const CanonicalPath &canonical_prefix);
259
260 private:
261 ResolveGenericArgs (const CanonicalPath &prefix,
262 const CanonicalPath &canonical_prefix)
263 : ResolverBase (), prefix (prefix), canonical_prefix (canonical_prefix)
264 {}
265
266 bool is_type_name (const CanonicalPath &path);
267 bool is_const_value_name (const CanonicalPath &path);
268
269 /**
270 * Resolve a disambiguated generic arg
271 */
272 void disambiguate (AST::GenericArg &arg);
273
274 /**
275 * Resolve a disambiguated generic arg
276 */
277 void resolve_disambiguated_generic (AST::GenericArg &arg);
278
279 const CanonicalPath &prefix;
280 const CanonicalPath &canonical_prefix;
281 };
282
283 } // namespace Resolver
284 } // namespace Rust
285
286 #endif // RUST_AST_RESOLVE_TYPE_H
This page took 0.05054 seconds and 5 git commands to generate.