Branch data Line data Source code
1 : : // Copyright (C) 2020-2024 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 : : #include "rust-ast-resolve-type.h"
20 : : #include "rust-ast-resolve-expr.h"
21 : :
22 : : namespace Rust {
23 : : namespace Resolver {
24 : :
25 : : // rust-ast-resolve-type.h
26 : :
27 : : void
28 : 393 : ResolveType::visit (AST::ArrayType &type)
29 : : {
30 : 393 : type.get_elem_type ()->accept_vis (*this);
31 : 393 : ResolveExpr::go (type.get_size_expr ().get (), CanonicalPath::create_empty (),
32 : 393 : CanonicalPath::create_empty ());
33 : 393 : }
34 : :
35 : : void
36 : 103 : ResolveType::visit (AST::TraitObjectTypeOneBound &type)
37 : : {
38 : 103 : ResolveTypeBound::go (&type.get_trait_bound ());
39 : 103 : }
40 : :
41 : : void
42 : 7 : ResolveType::visit (AST::TraitObjectType &type)
43 : : {
44 : 21 : for (auto &bound : type.get_type_param_bounds ())
45 : : {
46 : : /* NodeId bound_resolved_id = */
47 : 14 : ResolveTypeBound::go (bound.get ());
48 : : }
49 : 7 : }
50 : :
51 : : void
52 : 1876 : ResolveType::visit (AST::ReferenceType &type)
53 : : {
54 : 1876 : resolved_node = ResolveType::go (type.get_type_referenced ().get ());
55 : 1876 : }
56 : :
57 : : void
58 : 4688 : ResolveType::visit (AST::RawPointerType &type)
59 : : {
60 : 4688 : resolved_node = ResolveType::go (type.get_type_pointed_to ().get ());
61 : 4688 : }
62 : :
63 : : void
64 : 131 : ResolveType::visit (AST::InferredType &)
65 : : {
66 : : // FIXME
67 : 131 : }
68 : :
69 : : void
70 : 23 : ResolveType::visit (AST::NeverType &)
71 : : {
72 : : // FIXME
73 : 23 : }
74 : :
75 : : void
76 : 810 : ResolveType::visit (AST::SliceType &type)
77 : : {
78 : 810 : resolved_node = ResolveType::go (type.get_elem_type ().get ());
79 : 810 : }
80 : :
81 : : // resolve relative type-paths
82 : :
83 : : bool
84 : 34556 : ResolveRelativeTypePath::go (AST::TypePath &path, NodeId &resolved_node_id)
85 : : {
86 : 34556 : auto resolver = Resolver::get ();
87 : 34556 : auto mappings = Analysis::Mappings::get ();
88 : :
89 : 34556 : NodeId module_scope_id = resolver->peek_current_module_scope ();
90 : 34556 : NodeId previous_resolved_node_id = module_scope_id;
91 : 69978 : for (size_t i = 0; i < path.get_segments ().size (); i++)
92 : : {
93 : 35438 : auto &segment = path.get_segments ().at (i);
94 : 35438 : const AST::PathIdentSegment &ident_seg = segment->get_ident_segment ();
95 : 35438 : bool is_first_segment = i == 0;
96 : 35438 : resolved_node_id = UNKNOWN_NODEID;
97 : :
98 : 35438 : bool in_middle_of_path = i > 0;
99 : 35438 : if (in_middle_of_path && segment->is_lower_self_seg ())
100 : : {
101 : 1 : rust_error_at (segment->get_locus (), ErrorCode::E0433,
102 : : "failed to resolve: %<%s%> in paths can only be used "
103 : : "in start position",
104 : 1 : segment->as_string ().c_str ());
105 : 1 : return false;
106 : : }
107 : :
108 : 35437 : NodeId crate_scope_id = resolver->peek_crate_module_scope ();
109 : 35437 : if (segment->is_crate_path_seg ())
110 : : {
111 : : // what is the current crate scope node id?
112 : 3 : module_scope_id = crate_scope_id;
113 : 3 : previous_resolved_node_id = module_scope_id;
114 : 3 : resolver->insert_resolved_name (segment->get_node_id (),
115 : : module_scope_id);
116 : :
117 : 3 : continue;
118 : : }
119 : 35434 : else if (segment->is_super_path_seg ())
120 : : {
121 : 0 : if (module_scope_id == crate_scope_id)
122 : : {
123 : 0 : rust_error_at (segment->get_locus (),
124 : : "cannot use super at the crate scope");
125 : 0 : return false;
126 : : }
127 : :
128 : 0 : module_scope_id = resolver->peek_parent_module_scope ();
129 : 0 : previous_resolved_node_id = module_scope_id;
130 : 0 : resolver->insert_resolved_name (segment->get_node_id (),
131 : : module_scope_id);
132 : 0 : continue;
133 : : }
134 : :
135 : 35434 : switch (segment->get_type ())
136 : : {
137 : 1377 : case AST::TypePathSegment::SegmentType::GENERIC: {
138 : 1377 : AST::TypePathSegmentGeneric *s
139 : 1377 : = static_cast<AST::TypePathSegmentGeneric *> (segment.get ());
140 : 1377 : if (s->has_generic_args ())
141 : 1377 : ResolveGenericArgs::go (s->get_generic_args ());
142 : : }
143 : : break;
144 : :
145 : : case AST::TypePathSegment::SegmentType::REG:
146 : : // nothing to do
147 : : break;
148 : :
149 : 19 : case AST::TypePathSegment::SegmentType::FUNCTION:
150 : 19 : AST::TypePathSegmentFunction *fnseg
151 : 19 : = static_cast<AST::TypePathSegmentFunction *> (segment.get ());
152 : :
153 : 19 : AST::TypePathFunction &fn = fnseg->get_type_path_function ();
154 : 38 : for (auto ¶m : fn.get_params ())
155 : : {
156 : 19 : ResolveType::go (param.get ());
157 : : }
158 : :
159 : 19 : if (fn.has_return_type ())
160 : : {
161 : 17 : ResolveType::go (fn.get_return_type ().get ());
162 : : }
163 : :
164 : : break;
165 : : }
166 : :
167 : 35434 : if (is_first_segment)
168 : : {
169 : : // name scope first
170 : 34553 : NodeId resolved_node = UNKNOWN_NODEID;
171 : 34553 : const CanonicalPath path
172 : : = CanonicalPath::new_seg (segment->get_node_id (),
173 : 34553 : ident_seg.as_string ());
174 : 34553 : if (resolver->get_type_scope ().lookup (path, &resolved_node))
175 : : {
176 : 34374 : resolver->insert_resolved_type (segment->get_node_id (),
177 : : resolved_node);
178 : 34374 : resolved_node_id = resolved_node;
179 : : }
180 : 179 : else if (resolver->get_name_scope ().lookup (path, &resolved_node))
181 : : {
182 : 53 : resolver->insert_resolved_name (segment->get_node_id (),
183 : : resolved_node);
184 : 53 : resolved_node_id = resolved_node;
185 : : }
186 : 126 : else if (segment->is_lower_self_seg ())
187 : : {
188 : : // what is the current crate scope node id?
189 : 3 : module_scope_id = crate_scope_id;
190 : 3 : previous_resolved_node_id = module_scope_id;
191 : 3 : resolver->insert_resolved_name (segment->get_node_id (),
192 : : module_scope_id);
193 : :
194 : 3 : continue;
195 : : }
196 : 34553 : }
197 : :
198 : 35431 : if (resolved_node_id == UNKNOWN_NODEID
199 : 1004 : && previous_resolved_node_id == module_scope_id)
200 : : {
201 : 221 : tl::optional<CanonicalPath &> resolved_child
202 : 442 : = mappings->lookup_module_child (module_scope_id,
203 : 221 : ident_seg.as_string ());
204 : 221 : if (resolved_child.has_value ())
205 : : {
206 : 206 : NodeId resolved_node = resolved_child->get_node_id ();
207 : 206 : if (resolver->get_name_scope ().decl_was_declared_here (
208 : : resolved_node))
209 : : {
210 : 40 : resolved_node_id = resolved_node;
211 : 40 : resolver->insert_resolved_name (segment->get_node_id (),
212 : : resolved_node);
213 : : }
214 : 166 : else if (resolver->get_type_scope ().decl_was_declared_here (
215 : : resolved_node))
216 : : {
217 : 166 : resolved_node_id = resolved_node;
218 : 166 : resolver->insert_resolved_type (segment->get_node_id (),
219 : : resolved_node);
220 : : }
221 : : else
222 : : {
223 : 0 : rust_error_at (segment->get_locus (),
224 : : "Cannot find path %<%s%> in this scope",
225 : 0 : segment->as_string ().c_str ());
226 : 0 : return false;
227 : : }
228 : : }
229 : : }
230 : :
231 : 35431 : bool did_resolve_segment = resolved_node_id != UNKNOWN_NODEID;
232 : 35431 : if (did_resolve_segment)
233 : : {
234 : 34633 : if (mappings->node_is_module (resolved_node_id)
235 : 34633 : || mappings->node_is_crate (resolved_node_id))
236 : : {
237 : 374 : module_scope_id = resolved_node_id;
238 : : }
239 : 34633 : previous_resolved_node_id = resolved_node_id;
240 : : }
241 : 798 : else if (is_first_segment)
242 : : {
243 : 15 : rust_error_at (segment->get_locus (), ErrorCode::E0412,
244 : : "failed to resolve TypePath: %s in this scope",
245 : 15 : segment->as_string ().c_str ());
246 : 15 : return false;
247 : : }
248 : : }
249 : :
250 : 34540 : if (resolved_node_id != UNKNOWN_NODEID)
251 : : {
252 : : // name scope first
253 : 33757 : if (resolver->get_name_scope ().decl_was_declared_here (resolved_node_id))
254 : : {
255 : 0 : resolver->insert_resolved_name (path.get_node_id (),
256 : : resolved_node_id);
257 : : }
258 : : // check the type scope
259 : 33757 : else if (resolver->get_type_scope ().decl_was_declared_here (
260 : : resolved_node_id))
261 : : {
262 : 33757 : resolver->insert_resolved_type (path.get_node_id (),
263 : : resolved_node_id);
264 : : }
265 : : else
266 : : {
267 : 0 : rust_unreachable ();
268 : : }
269 : : }
270 : :
271 : : return true;
272 : : }
273 : :
274 : : // qualified type paths
275 : :
276 : 159 : ResolveRelativeQualTypePath::ResolveRelativeQualTypePath ()
277 : 159 : : failure_flag (false)
278 : 159 : {}
279 : :
280 : : bool
281 : 159 : ResolveRelativeQualTypePath::go (AST::QualifiedPathInType &path)
282 : : {
283 : 159 : ResolveRelativeQualTypePath o;
284 : :
285 : : // resolve the type and trait path
286 : 159 : auto &qualified_path = path.get_qualified_path_type ();
287 : 159 : if (!o.resolve_qual_seg (qualified_path))
288 : : return false;
289 : :
290 : : // qualified types are similar to other paths in that we cannot guarantee
291 : : // that we can resolve the path at name resolution. We must look up
292 : : // associated types and type information to figure this out properly
293 : :
294 : 159 : std::unique_ptr<AST::TypePathSegment> &associated
295 : 159 : = path.get_associated_segment ();
296 : :
297 : 159 : associated->accept_vis (o);
298 : 159 : if (o.failure_flag)
299 : : return false;
300 : :
301 : 159 : for (auto &seg : path.get_segments ())
302 : : {
303 : 0 : seg->accept_vis (o);
304 : 0 : if (o.failure_flag)
305 : 0 : return false;
306 : : }
307 : :
308 : : return true;
309 : 159 : }
310 : :
311 : : bool
312 : 159 : ResolveRelativeQualTypePath::resolve_qual_seg (AST::QualifiedPathType &seg)
313 : : {
314 : 159 : if (seg.is_error ())
315 : : {
316 : 0 : rust_error_at (seg.get_locus (), "segment has error: %s",
317 : 0 : seg.as_string ().c_str ());
318 : 0 : return false;
319 : : }
320 : :
321 : 159 : auto type = seg.get_type ().get ();
322 : 159 : ResolveType::go (type);
323 : :
324 : 159 : if (seg.has_as_clause ())
325 : 159 : ResolveType::go (&seg.get_as_type_path ());
326 : :
327 : : return true;
328 : : }
329 : :
330 : : void
331 : 0 : ResolveRelativeQualTypePath::visit (AST::TypePathSegmentGeneric &seg)
332 : : {
333 : 0 : if (seg.is_error ())
334 : : {
335 : 0 : failure_flag = true;
336 : 0 : rust_error_at (seg.get_locus (), "segment has error: %s",
337 : 0 : seg.as_string ().c_str ());
338 : 0 : return;
339 : : }
340 : :
341 : 0 : ResolveGenericArgs::go (seg.get_generic_args ());
342 : : }
343 : :
344 : : void
345 : 159 : ResolveRelativeQualTypePath::visit (AST::TypePathSegment &seg)
346 : : {
347 : 159 : if (seg.is_error ())
348 : : {
349 : 0 : failure_flag = true;
350 : 0 : rust_error_at (seg.get_locus (), "segment has error: %s",
351 : 0 : seg.as_string ().c_str ());
352 : 0 : return;
353 : : }
354 : : }
355 : :
356 : : // resolve to canonical path
357 : :
358 : : bool
359 : 6506 : ResolveTypeToCanonicalPath::go (AST::Type *type, CanonicalPath &result)
360 : : {
361 : 6506 : ResolveTypeToCanonicalPath resolver;
362 : 6506 : type->accept_vis (resolver);
363 : 6506 : result = resolver.result;
364 : 6506 : return !resolver.result.is_empty ();
365 : 6506 : }
366 : :
367 : : void
368 : 5961 : ResolveTypeToCanonicalPath::visit (AST::TypePath &path)
369 : : {
370 : 5961 : NodeId resolved_node = UNKNOWN_NODEID;
371 : 5961 : if (!resolver->lookup_resolved_name (path.get_node_id (), &resolved_node))
372 : : {
373 : 5961 : resolver->lookup_resolved_type (path.get_node_id (), &resolved_node);
374 : : }
375 : :
376 : 5961 : if (resolved_node == UNKNOWN_NODEID)
377 : 1 : return;
378 : :
379 : 5960 : const CanonicalPath *type_path = nullptr;
380 : 5960 : if (mappings->lookup_canonical_path (resolved_node, &type_path))
381 : : {
382 : 5960 : auto &final_seg = path.get_segments ().back ();
383 : 5960 : switch (final_seg->get_type ())
384 : : {
385 : 552 : case AST::TypePathSegment::SegmentType::GENERIC: {
386 : 552 : AST::TypePathSegmentGeneric *s
387 : 552 : = static_cast<AST::TypePathSegmentGeneric *> (final_seg.get ());
388 : :
389 : 552 : std::vector<CanonicalPath> args;
390 : 552 : if (s->has_generic_args ())
391 : : {
392 : 552 : ResolveGenericArgs::go (s->get_generic_args ());
393 : 1183 : for (auto &generic : s->get_generic_args ().get_generic_args ())
394 : : {
395 : : // FIXME: What do we want to do here in case there is a
396 : : // constant or an ambiguous const generic?
397 : : // TODO: At that point, will all generics have been
398 : : // disambiguated? Can we thus canonical resolve types and
399 : : // const and `rust_unreachable` on ambiguous types?
400 : : // This is probably fine as we just want to canonicalize
401 : : // types, right?
402 : 631 : if (generic.get_kind () == AST::GenericArg::Kind::Type)
403 : : {
404 : 631 : CanonicalPath arg = CanonicalPath::create_empty ();
405 : 631 : bool ok = ResolveTypeToCanonicalPath::go (
406 : 631 : generic.get_type ().get (), arg);
407 : 631 : if (ok)
408 : 630 : args.push_back (std::move (arg));
409 : 631 : }
410 : : }
411 : : }
412 : :
413 : 552 : result = *type_path;
414 : 552 : if (!args.empty ())
415 : : {
416 : : // append this onto the path
417 : 548 : std::string buf;
418 : 1178 : for (size_t i = 0; i < args.size (); i++)
419 : : {
420 : 630 : bool has_next = (i + 1) < args.size ();
421 : 630 : const auto &arg = args.at (i);
422 : :
423 : 630 : buf += arg.get ();
424 : 630 : if (has_next)
425 : 82 : buf += ", ";
426 : : }
427 : :
428 : 1096 : std::string arg_seg = "<" + buf + ">";
429 : 548 : CanonicalPath argument_seg
430 : 548 : = CanonicalPath::new_seg (s->get_node_id (), arg_seg);
431 : 548 : result = result.append (argument_seg);
432 : 548 : }
433 : 552 : }
434 : 552 : break;
435 : :
436 : 5408 : default:
437 : 5408 : result = *type_path;
438 : 5408 : break;
439 : : }
440 : : }
441 : : }
442 : :
443 : : void
444 : 242 : ResolveTypeToCanonicalPath::visit (AST::ReferenceType &type)
445 : : {
446 : 242 : CanonicalPath path = CanonicalPath::create_empty ();
447 : 242 : bool ok
448 : 242 : = ResolveTypeToCanonicalPath::go (type.get_type_referenced ().get (), path);
449 : 242 : if (ok)
450 : : {
451 : 421 : std::string ref_type_str = type.is_mut () ? "mut" : "";
452 : 484 : std::string ref_path = "&" + ref_type_str + " " + path.get ();
453 : 242 : result = CanonicalPath::new_seg (type.get_node_id (), ref_path);
454 : 242 : }
455 : 242 : }
456 : :
457 : : void
458 : 125 : ResolveTypeToCanonicalPath::visit (AST::RawPointerType &type)
459 : : {
460 : 125 : CanonicalPath path = CanonicalPath::create_empty ();
461 : 125 : bool ok
462 : 125 : = ResolveTypeToCanonicalPath::go (type.get_type_pointed_to ().get (), path);
463 : 125 : if (ok)
464 : : {
465 : 125 : std::string ptr_type_str
466 : 125 : = type.get_pointer_type () == AST::RawPointerType::CONST ? "const"
467 : 137 : : "mut";
468 : 250 : std::string ptr_path = "*" + ptr_type_str + " " + path.get ();
469 : 125 : result = CanonicalPath::new_seg (type.get_node_id (), ptr_path);
470 : 125 : }
471 : 125 : }
472 : :
473 : : void
474 : 171 : ResolveTypeToCanonicalPath::visit (AST::SliceType &type)
475 : : {
476 : 171 : CanonicalPath path = CanonicalPath::create_empty ();
477 : 171 : bool ok = ResolveTypeToCanonicalPath::go (type.get_elem_type ().get (), path);
478 : 171 : if (ok)
479 : : {
480 : 342 : std::string slice_path = "[" + path.get () + "]";
481 : 171 : result = CanonicalPath::new_seg (type.get_node_id (), slice_path);
482 : 171 : }
483 : 171 : }
484 : :
485 : : void
486 : 7 : ResolveTypeToCanonicalPath::visit (AST::TraitObjectTypeOneBound &type)
487 : : {
488 : 7 : CanonicalPath path = CanonicalPath::create_empty ();
489 : 7 : bool ok
490 : 7 : = ResolveTypeToCanonicalPath::go (&type.get_trait_bound ().get_type_path (),
491 : : path);
492 : 7 : if (ok)
493 : : {
494 : 14 : std::string slice_path = "<dyn " + path.get () + ">";
495 : 7 : result = CanonicalPath::new_seg (type.get_node_id (), slice_path);
496 : 7 : }
497 : 7 : }
498 : :
499 : : void
500 : 0 : ResolveTypeToCanonicalPath::visit (AST::TraitObjectType &)
501 : : {
502 : : // FIXME is this actually allowed? dyn A+B
503 : 0 : rust_unreachable ();
504 : : }
505 : :
506 : 6506 : ResolveTypeToCanonicalPath::ResolveTypeToCanonicalPath ()
507 : 6506 : : ResolverBase (), result (CanonicalPath::create_empty ())
508 : 6506 : {}
509 : :
510 : : bool
511 : 1431 : ResolveGenericArgs::is_const_value_name (const CanonicalPath &path)
512 : : {
513 : 1431 : NodeId resolved;
514 : 1431 : auto found = resolver->get_name_scope ().lookup (path, &resolved);
515 : :
516 : 1431 : return found;
517 : : }
518 : :
519 : : bool
520 : 1431 : ResolveGenericArgs::is_type_name (const CanonicalPath &path)
521 : : {
522 : 1431 : NodeId resolved;
523 : 1431 : auto found = resolver->get_type_scope ().lookup (path, &resolved);
524 : :
525 : 1431 : return found;
526 : : }
527 : :
528 : : void
529 : 1431 : ResolveGenericArgs::disambiguate (AST::GenericArg &arg)
530 : : {
531 : 1431 : auto path = canonical_prefix.append (
532 : 1431 : CanonicalPath::new_seg (UNKNOWN_NODEID, arg.get_path ()));
533 : :
534 : 1431 : auto is_type = is_type_name (path);
535 : 1431 : auto is_value = is_const_value_name (path);
536 : :
537 : : // In case we cannot find anything, we resolve the ambiguity to a type.
538 : : // This causes the typechecker to error out properly and when necessary.
539 : : // But types also take priority over const values in the case of
540 : : // ambiguities, hence the weird control flow
541 : 1431 : if (is_type || (!is_type && !is_value))
542 : 1428 : arg = arg.disambiguate_to_type ();
543 : 3 : else if (is_value)
544 : 3 : arg = arg.disambiguate_to_const ();
545 : 1431 : }
546 : :
547 : : void
548 : 2733 : ResolveGenericArgs::resolve_disambiguated_generic (AST::GenericArg &arg)
549 : : {
550 : 2733 : switch (arg.get_kind ())
551 : : {
552 : 19 : case AST::GenericArg::Kind::Const:
553 : 19 : ResolveExpr::go (arg.get_expression ().get (), prefix, canonical_prefix);
554 : 19 : break;
555 : 2714 : case AST::GenericArg::Kind::Type:
556 : 2714 : ResolveType::go (arg.get_type ().get ());
557 : 2714 : break;
558 : 0 : default:
559 : 0 : rust_unreachable ();
560 : : }
561 : 2733 : }
562 : : void
563 : 2499 : ResolveGenericArgs::go (AST::GenericArgs &generic_args)
564 : : {
565 : 2499 : auto empty = CanonicalPath::create_empty ();
566 : :
567 : 2499 : go (generic_args, empty, empty);
568 : 2499 : }
569 : :
570 : : void
571 : 2521 : ResolveGenericArgs::go (AST::GenericArgs &generic_args,
572 : : const CanonicalPath &prefix,
573 : : const CanonicalPath &canonical_prefix)
574 : : {
575 : 2521 : auto resolver = ResolveGenericArgs (prefix, canonical_prefix);
576 : :
577 : 5254 : for (auto &arg : generic_args.get_generic_args ())
578 : : {
579 : 2733 : if (arg.get_kind () == AST::GenericArg::Kind::Either)
580 : 1431 : resolver.disambiguate (arg);
581 : :
582 : 2733 : resolver.resolve_disambiguated_generic (arg);
583 : : }
584 : :
585 : 2557 : for (auto &binding : generic_args.get_binding_args ())
586 : : {
587 : 36 : ResolveType::go (binding.get_type ().get ());
588 : : }
589 : 2521 : }
590 : :
591 : : } // namespace Resolver
592 : : } // namespace Rust
|