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 : : #include "rust-ast-resolve-type.h"
20 : : #include "rust-ast-resolve-expr.h"
21 : : #include "rust-canonical-path.h"
22 : : #include "rust-type.h"
23 : : #include "rust-hir-map.h"
24 : :
25 : : namespace Rust {
26 : : namespace Resolver {
27 : :
28 : : // rust-ast-resolve-type.h
29 : :
30 : : NodeId
31 : 56442 : ResolveType::go (AST::Type &type)
32 : : {
33 : 56442 : ResolveType resolver;
34 : 56442 : type.accept_vis (resolver);
35 : 56442 : return resolver.resolved_node;
36 : 56442 : }
37 : :
38 : : void
39 : 46 : ResolveType::visit (AST::BareFunctionType &fntype)
40 : : {
41 : 90 : for (auto ¶m : fntype.get_function_params ())
42 : 44 : ResolveType::go (param.get_type ());
43 : :
44 : 46 : if (fntype.has_return_type ())
45 : 35 : ResolveType::go (fntype.get_return_type ());
46 : 46 : }
47 : :
48 : : void
49 : 352 : ResolveType::visit (AST::TupleType &tuple)
50 : : {
51 : 352 : if (tuple.is_unit_type ())
52 : : {
53 : 65 : resolved_node = resolver->get_unit_type_node_id ();
54 : 65 : return;
55 : : }
56 : :
57 : 874 : for (auto &elem : tuple.get_elems ())
58 : 587 : ResolveType::go (*elem);
59 : : }
60 : :
61 : : void
62 : 46772 : ResolveType::visit (AST::TypePath &path)
63 : : {
64 : 46772 : ResolveRelativeTypePath::go (path, resolved_node);
65 : 46772 : }
66 : :
67 : : void
68 : 172 : ResolveType::visit (AST::QualifiedPathInType &path)
69 : : {
70 : 172 : ResolveRelativeQualTypePath::go (path);
71 : 172 : }
72 : :
73 : : void
74 : 575 : ResolveType::visit (AST::ArrayType &type)
75 : : {
76 : 575 : type.get_elem_type ().accept_vis (*this);
77 : 575 : ResolveExpr::go (type.get_size_expr (), CanonicalPath::create_empty (),
78 : 575 : CanonicalPath::create_empty ());
79 : 575 : }
80 : :
81 : : void
82 : 156 : ResolveType::visit (AST::TraitObjectTypeOneBound &type)
83 : : {
84 : 156 : ResolveTypeBound::go (type.get_trait_bound ());
85 : 156 : }
86 : :
87 : : void
88 : 12 : ResolveType::visit (AST::TraitObjectType &type)
89 : : {
90 : 41 : for (auto &bound : type.get_type_param_bounds ())
91 : : {
92 : : /* NodeId bound_resolved_id = */
93 : 29 : ResolveTypeBound::go (*bound);
94 : : }
95 : 12 : }
96 : :
97 : : void
98 : 2 : ResolveType::visit (AST::ParenthesisedType &type)
99 : : {
100 : 2 : resolved_node = ResolveType::go (*type.get_type_in_parens ());
101 : 2 : }
102 : :
103 : : void
104 : 2300 : ResolveType::visit (AST::ReferenceType &type)
105 : : {
106 : 2300 : resolved_node = ResolveType::go (type.get_type_referenced ());
107 : 2300 : }
108 : :
109 : : void
110 : 5590 : ResolveType::visit (AST::RawPointerType &type)
111 : : {
112 : 5590 : resolved_node = ResolveType::go (type.get_type_pointed_to ());
113 : 5590 : }
114 : :
115 : : void
116 : 166 : ResolveType::visit (AST::InferredType &)
117 : : {
118 : : // nothing to do
119 : 166 : }
120 : :
121 : : void
122 : 46 : ResolveType::visit (AST::NeverType &)
123 : : {
124 : 46 : resolved_node = resolver->get_never_type_node_id ();
125 : 46 : }
126 : :
127 : : void
128 : 824 : ResolveType::visit (AST::SliceType &type)
129 : : {
130 : 824 : resolved_node = ResolveType::go (type.get_elem_type ());
131 : 824 : }
132 : :
133 : : void
134 : 0 : ResolveType::visit (AST::ImplTraitType &type)
135 : : {
136 : 0 : for (auto &bound : type.get_type_param_bounds ())
137 : 0 : ResolveTypeBound::go (*bound);
138 : 0 : }
139 : :
140 : : void
141 : 4 : ResolveType::visit (AST::ImplTraitTypeOneBound &type)
142 : : {
143 : 4 : ResolveTypeBound::go (type.get_trait_bound ());
144 : 4 : }
145 : :
146 : : // resolve relative type-paths
147 : :
148 : : bool
149 : 46772 : ResolveRelativeTypePath::go (AST::TypePath &path, NodeId &resolved_node_id)
150 : : {
151 : 46772 : auto resolver = Resolver::get ();
152 : 46772 : auto &mappings = Analysis::Mappings::get ();
153 : :
154 : 46772 : NodeId module_scope_id = resolver->peek_current_module_scope ();
155 : 46772 : NodeId previous_resolved_node_id = module_scope_id;
156 : 94721 : for (size_t i = 0; i < path.get_segments ().size (); i++)
157 : : {
158 : 47972 : auto &segment = path.get_segments ().at (i);
159 : 47972 : bool is_first_segment = i == 0;
160 : 47972 : NodeId crate_scope_id = resolver->peek_crate_module_scope ();
161 : 47972 : auto ident_string = segment->is_lang_item ()
162 : 47972 : ? LangItem::PrettyString (segment->get_lang_item ())
163 : 47972 : : segment->get_ident_segment ().as_string ();
164 : :
165 : 47972 : resolved_node_id = UNKNOWN_NODEID;
166 : :
167 : 47972 : if (segment->is_lang_item ())
168 : : {
169 : 112 : resolved_node_id = Analysis::Mappings::get ().get_lang_item_node (
170 : : segment->get_lang_item ());
171 : 112 : previous_resolved_node_id = resolved_node_id;
172 : : }
173 : : else
174 : : {
175 : 47860 : bool in_middle_of_path = i > 0;
176 : 47860 : if (in_middle_of_path && segment->is_lower_self_seg ())
177 : : {
178 : 1 : rust_error_at (segment->get_locus (), ErrorCode::E0433,
179 : : "%qs in paths can only be used in start position",
180 : 1 : segment->as_string ().c_str ());
181 : 1 : return false;
182 : : }
183 : :
184 : 47859 : if (segment->is_crate_path_seg ())
185 : : {
186 : : // what is the current crate scope node id?
187 : 6 : module_scope_id = crate_scope_id;
188 : 6 : previous_resolved_node_id = module_scope_id;
189 : 6 : resolver->insert_resolved_name (segment->get_node_id (),
190 : : module_scope_id);
191 : :
192 : 6 : continue;
193 : : }
194 : 47853 : else if (segment->is_super_path_seg ())
195 : : {
196 : 0 : if (module_scope_id == crate_scope_id)
197 : : {
198 : 0 : rust_error_at (segment->get_locus (),
199 : : "cannot use super at the crate scope");
200 : 0 : return false;
201 : : }
202 : :
203 : 0 : module_scope_id = resolver->peek_parent_module_scope ();
204 : 0 : previous_resolved_node_id = module_scope_id;
205 : 0 : resolver->insert_resolved_name (segment->get_node_id (),
206 : : module_scope_id);
207 : 0 : continue;
208 : : }
209 : : }
210 : :
211 : 47965 : switch (segment->get_type ())
212 : : {
213 : 1861 : case AST::TypePathSegment::SegmentType::GENERIC: {
214 : 1861 : AST::TypePathSegmentGeneric *s
215 : 1861 : = static_cast<AST::TypePathSegmentGeneric *> (segment.get ());
216 : 1861 : if (s->has_generic_args ())
217 : 1860 : ResolveGenericArgs::go (s->get_generic_args ());
218 : : }
219 : : break;
220 : :
221 : : case AST::TypePathSegment::SegmentType::REG:
222 : : // nothing to do
223 : : break;
224 : :
225 : 22 : case AST::TypePathSegment::SegmentType::FUNCTION:
226 : 22 : AST::TypePathSegmentFunction *fnseg
227 : 22 : = static_cast<AST::TypePathSegmentFunction *> (segment.get ());
228 : :
229 : 22 : AST::TypePathFunction &fn = fnseg->get_type_path_function ();
230 : 46 : for (auto ¶m : fn.get_params ())
231 : : {
232 : 24 : ResolveType::go (*param);
233 : : }
234 : :
235 : 22 : if (fn.has_return_type ())
236 : : {
237 : 20 : ResolveType::go (fn.get_return_type ());
238 : : }
239 : :
240 : : break;
241 : : }
242 : :
243 : 47965 : if (is_first_segment)
244 : : {
245 : : // name scope first
246 : 46766 : NodeId resolved_node = UNKNOWN_NODEID;
247 : 46766 : const CanonicalPath path
248 : 46766 : = CanonicalPath::new_seg (segment->get_node_id (), ident_string);
249 : 46766 : if (resolver->get_type_scope ().lookup (path, &resolved_node))
250 : : {
251 : 46196 : NodeId existing = UNKNOWN_NODEID;
252 : 46196 : bool ok = resolver->lookup_resolved_type (segment->get_node_id (),
253 : : &existing);
254 : :
255 : 46196 : if (ok)
256 : 786 : rust_assert (existing == resolved_node);
257 : : else
258 : 45410 : resolver->insert_resolved_type (segment->get_node_id (),
259 : : resolved_node);
260 : 46196 : resolved_node_id = resolved_node;
261 : : }
262 : 570 : else if (resolver->get_name_scope ().lookup (path, &resolved_node))
263 : : {
264 : 113 : NodeId existing = UNKNOWN_NODEID;
265 : 113 : bool ok = resolver->lookup_resolved_name (segment->get_node_id (),
266 : : &existing);
267 : :
268 : 113 : if (ok)
269 : 0 : rust_assert (existing == resolved_node);
270 : : else
271 : 113 : resolver->insert_resolved_name (segment->get_node_id (),
272 : : resolved_node);
273 : 113 : resolved_node_id = resolved_node;
274 : : }
275 : 457 : else if (!segment->is_lang_item () && segment->is_lower_self_seg ())
276 : : {
277 : : // what is the current crate scope node id?
278 : 3 : module_scope_id = crate_scope_id;
279 : 3 : previous_resolved_node_id = module_scope_id;
280 : :
281 : 3 : NodeId existing = UNKNOWN_NODEID;
282 : 3 : bool ok = resolver->lookup_resolved_name (segment->get_node_id (),
283 : : &existing);
284 : :
285 : 3 : if (ok)
286 : 0 : rust_assert (existing == module_scope_id);
287 : : else
288 : 3 : resolver->insert_resolved_name (segment->get_node_id (),
289 : : module_scope_id);
290 : :
291 : 3 : continue;
292 : 3 : }
293 : 46766 : }
294 : :
295 : 47962 : if (resolved_node_id == UNKNOWN_NODEID
296 : 1541 : && previous_resolved_node_id == module_scope_id)
297 : : {
298 : 565 : tl::optional<CanonicalPath &> resolved_child
299 : 565 : = mappings.lookup_module_child (module_scope_id, ident_string);
300 : 565 : if (resolved_child.has_value ())
301 : : {
302 : 542 : NodeId resolved_node = resolved_child->get_node_id ();
303 : 542 : if (resolver->get_name_scope ().decl_was_declared_here (
304 : : resolved_node))
305 : : {
306 : 115 : resolved_node_id = resolved_node;
307 : :
308 : 115 : NodeId existing = UNKNOWN_NODEID;
309 : 115 : bool ok
310 : 115 : = resolver->lookup_resolved_name (segment->get_node_id (),
311 : : &existing);
312 : :
313 : 115 : if (ok)
314 : 0 : rust_assert (existing == resolved_node);
315 : : else
316 : 115 : resolver->insert_resolved_name (segment->get_node_id (),
317 : : resolved_node);
318 : : }
319 : 427 : else if (resolver->get_type_scope ().decl_was_declared_here (
320 : : resolved_node))
321 : : {
322 : 427 : resolved_node_id = resolved_node;
323 : :
324 : 427 : NodeId existing = UNKNOWN_NODEID;
325 : 427 : bool ok
326 : 427 : = resolver->lookup_resolved_type (segment->get_node_id (),
327 : : &existing);
328 : :
329 : 427 : if (ok)
330 : 0 : rust_assert (existing == resolved_node);
331 : : else
332 : 427 : resolver->insert_resolved_type (segment->get_node_id (),
333 : : resolved_node);
334 : : }
335 : : else
336 : : {
337 : 0 : rust_error_at (segment->get_locus (),
338 : : "Cannot find path %qs in this scope",
339 : 0 : segment->as_string ().c_str ());
340 : 0 : return false;
341 : : }
342 : : }
343 : : }
344 : :
345 : 47962 : bool did_resolve_segment = resolved_node_id != UNKNOWN_NODEID;
346 : 47962 : if (did_resolve_segment)
347 : : {
348 : 46963 : if (mappings.node_is_module (resolved_node_id)
349 : 46963 : || mappings.node_is_crate (resolved_node_id))
350 : : {
351 : 868 : module_scope_id = resolved_node_id;
352 : : }
353 : 46963 : previous_resolved_node_id = resolved_node_id;
354 : : }
355 : 999 : else if (is_first_segment)
356 : : {
357 : 44 : rust_error_at (segment->get_locus (), ErrorCode::E0412,
358 : : "could not resolve type path %qs",
359 : 44 : segment->get_ident_segment ().as_string ().c_str ());
360 : 22 : return false;
361 : : }
362 : 47972 : }
363 : :
364 : 46749 : if (resolved_node_id != UNKNOWN_NODEID)
365 : : {
366 : : // name scope first
367 : 45772 : if (resolver->get_name_scope ().decl_was_declared_here (resolved_node_id))
368 : : {
369 : 356 : NodeId existing = UNKNOWN_NODEID;
370 : 356 : bool ok
371 : 356 : = resolver->lookup_resolved_name (path.get_node_id (), &existing);
372 : :
373 : 356 : if (ok)
374 : 1 : rust_assert (existing == resolved_node_id);
375 : : else
376 : 355 : resolver->insert_resolved_name (path.get_node_id (),
377 : : resolved_node_id);
378 : : }
379 : : // check the type scope
380 : 45416 : else if (resolver->get_type_scope ().decl_was_declared_here (
381 : : resolved_node_id))
382 : : {
383 : 45416 : NodeId existing = UNKNOWN_NODEID;
384 : 45416 : bool ok
385 : 45416 : = resolver->lookup_resolved_type (path.get_node_id (), &existing);
386 : :
387 : 45416 : if (ok)
388 : 785 : rust_assert (existing == resolved_node_id);
389 : : else
390 : 44631 : resolver->insert_resolved_type (path.get_node_id (),
391 : : resolved_node_id);
392 : : }
393 : : else
394 : : {
395 : 0 : rust_unreachable ();
396 : : }
397 : : }
398 : :
399 : : return true;
400 : : }
401 : :
402 : : // qualified type paths
403 : :
404 : 172 : ResolveRelativeQualTypePath::ResolveRelativeQualTypePath ()
405 : 172 : : failure_flag (false)
406 : 172 : {}
407 : :
408 : : bool
409 : 172 : ResolveRelativeQualTypePath::go (AST::QualifiedPathInType &path)
410 : : {
411 : 172 : ResolveRelativeQualTypePath o;
412 : :
413 : : // resolve the type and trait path
414 : 172 : auto &qualified_path = path.get_qualified_path_type ();
415 : 172 : if (!o.resolve_qual_seg (qualified_path))
416 : : return false;
417 : :
418 : : // qualified types are similar to other paths in that we cannot guarantee
419 : : // that we can resolve the path at name resolution. We must look up
420 : : // associated types and type information to figure this out properly
421 : :
422 : 172 : std::unique_ptr<AST::TypePathSegment> &associated
423 : 172 : = path.get_associated_segment ();
424 : :
425 : 172 : associated->accept_vis (o);
426 : 172 : if (o.failure_flag)
427 : : return false;
428 : :
429 : 172 : for (auto &seg : path.get_segments ())
430 : : {
431 : 0 : seg->accept_vis (o);
432 : 0 : if (o.failure_flag)
433 : 0 : return false;
434 : : }
435 : :
436 : : return true;
437 : 172 : }
438 : :
439 : : bool
440 : 172 : ResolveRelativeQualTypePath::resolve_qual_seg (AST::QualifiedPathType &seg)
441 : : {
442 : 172 : if (seg.is_error ())
443 : : {
444 : 0 : rust_error_at (seg.get_locus (), "segment has error: %s",
445 : 0 : seg.as_string ().c_str ());
446 : 0 : return false;
447 : : }
448 : :
449 : 172 : auto &type = seg.get_type ();
450 : 172 : ResolveType::go (type);
451 : :
452 : 172 : if (seg.has_as_clause ())
453 : 171 : ResolveType::go (seg.get_as_type_path ());
454 : :
455 : : return true;
456 : : }
457 : :
458 : : void
459 : 0 : ResolveRelativeQualTypePath::visit (AST::TypePathSegmentGeneric &seg)
460 : : {
461 : 0 : if (seg.is_error ())
462 : : {
463 : 0 : failure_flag = true;
464 : 0 : rust_error_at (seg.get_locus (), "segment has error: %s",
465 : 0 : seg.as_string ().c_str ());
466 : 0 : return;
467 : : }
468 : :
469 : 0 : ResolveGenericArgs::go (seg.get_generic_args ());
470 : : }
471 : :
472 : : void
473 : 172 : ResolveRelativeQualTypePath::visit (AST::TypePathSegment &seg)
474 : : {
475 : 172 : if (seg.is_error ())
476 : : {
477 : 0 : failure_flag = true;
478 : 0 : rust_error_at (seg.get_locus (), "segment has error: %s",
479 : 0 : seg.as_string ().c_str ());
480 : 0 : return;
481 : : }
482 : : }
483 : :
484 : : // resolve to canonical path
485 : :
486 : : bool
487 : 9066 : ResolveTypeToCanonicalPath::go (AST::Type &type, CanonicalPath &result)
488 : : {
489 : 9066 : ResolveTypeToCanonicalPath resolver;
490 : 9066 : type.accept_vis (resolver);
491 : 9066 : result = resolver.result;
492 : 9066 : return !resolver.result.is_empty ();
493 : 9066 : }
494 : :
495 : : void
496 : 8465 : ResolveTypeToCanonicalPath::visit (AST::TypePath &path)
497 : : {
498 : 8465 : NodeId resolved_node = UNKNOWN_NODEID;
499 : 8465 : if (!resolver->lookup_resolved_name (path.get_node_id (), &resolved_node))
500 : : {
501 : 8242 : resolver->lookup_resolved_type (path.get_node_id (), &resolved_node);
502 : : }
503 : :
504 : 8465 : if (resolved_node == UNKNOWN_NODEID)
505 : 4 : return;
506 : :
507 : 8461 : if (auto type_path = mappings.lookup_canonical_path (resolved_node))
508 : : {
509 : 8461 : auto &final_seg = path.get_segments ().back ();
510 : 8461 : switch (final_seg->get_type ())
511 : : {
512 : 688 : case AST::TypePathSegment::SegmentType::GENERIC: {
513 : 688 : AST::TypePathSegmentGeneric *s
514 : 688 : = static_cast<AST::TypePathSegmentGeneric *> (final_seg.get ());
515 : :
516 : 688 : std::vector<CanonicalPath> args;
517 : 688 : if (s->has_generic_args ())
518 : : {
519 : 688 : ResolveGenericArgs::go (s->get_generic_args ());
520 : 1455 : for (auto &generic : s->get_generic_args ().get_generic_args ())
521 : : {
522 : : // FIXME: What do we want to do here in case there is a
523 : : // constant or an ambiguous const generic?
524 : : // TODO: At that point, will all generics have been
525 : : // disambiguated? Can we thus canonical resolve types and
526 : : // const and `rust_unreachable` on ambiguous types?
527 : : // This is probably fine as we just want to canonicalize
528 : : // types, right?
529 : 767 : if (generic.get_kind () == AST::GenericArg::Kind::Type)
530 : : {
531 : 767 : CanonicalPath arg = CanonicalPath::create_empty ();
532 : 767 : bool ok
533 : 767 : = ResolveTypeToCanonicalPath::go (generic.get_type (),
534 : : arg);
535 : 767 : if (ok)
536 : 766 : args.push_back (std::move (arg));
537 : 767 : }
538 : : }
539 : : }
540 : :
541 : 688 : result = *type_path;
542 : 688 : if (!args.empty ())
543 : : {
544 : : // append this onto the path
545 : 675 : std::string buf;
546 : 1441 : for (size_t i = 0; i < args.size (); i++)
547 : : {
548 : 766 : bool has_next = (i + 1) < args.size ();
549 : 766 : const auto &arg = args.at (i);
550 : :
551 : 1532 : buf += arg.get ();
552 : 766 : if (has_next)
553 : 91 : buf += ", ";
554 : : }
555 : :
556 : 1350 : std::string arg_seg = "<" + buf + ">";
557 : 675 : CanonicalPath argument_seg
558 : 675 : = CanonicalPath::new_seg (s->get_node_id (), arg_seg);
559 : 675 : result = result.append (argument_seg);
560 : 675 : }
561 : 688 : }
562 : 688 : break;
563 : :
564 : 7773 : default:
565 : 7773 : result = *type_path;
566 : 7773 : break;
567 : : }
568 : : }
569 : : }
570 : :
571 : : void
572 : 257 : ResolveTypeToCanonicalPath::visit (AST::ReferenceType &type)
573 : : {
574 : 257 : CanonicalPath path = CanonicalPath::create_empty ();
575 : 257 : bool ok = ResolveTypeToCanonicalPath::go (type.get_type_referenced (), path);
576 : 257 : if (ok)
577 : : {
578 : 445 : std::string ref_type_str = type.is_mut () ? "mut" : "";
579 : 514 : std::string ref_path = "&" + ref_type_str + " " + path.get ();
580 : 257 : result = CanonicalPath::new_seg (type.get_node_id (), ref_path);
581 : 257 : }
582 : 257 : }
583 : :
584 : : void
585 : 157 : ResolveTypeToCanonicalPath::visit (AST::RawPointerType &type)
586 : : {
587 : 157 : CanonicalPath path = CanonicalPath::create_empty ();
588 : 157 : bool ok = ResolveTypeToCanonicalPath::go (type.get_type_pointed_to (), path);
589 : 157 : if (ok)
590 : : {
591 : 157 : std::string ptr_type_str
592 : 157 : = type.get_pointer_type () == AST::RawPointerType::CONST ? "const"
593 : 185 : : "mut";
594 : 314 : std::string ptr_path = "*" + ptr_type_str + " " + path.get ();
595 : 157 : result = CanonicalPath::new_seg (type.get_node_id (), ptr_path);
596 : 157 : }
597 : 157 : }
598 : :
599 : : void
600 : 173 : ResolveTypeToCanonicalPath::visit (AST::SliceType &type)
601 : : {
602 : 173 : CanonicalPath path = CanonicalPath::create_empty ();
603 : 173 : bool ok = ResolveTypeToCanonicalPath::go (type.get_elem_type (), path);
604 : 173 : if (ok)
605 : : {
606 : 346 : std::string slice_path = "[" + path.get () + "]";
607 : 173 : result = CanonicalPath::new_seg (type.get_node_id (), slice_path);
608 : 173 : }
609 : 173 : }
610 : :
611 : : void
612 : 7 : ResolveTypeToCanonicalPath::visit (AST::TraitObjectTypeOneBound &type)
613 : : {
614 : 7 : CanonicalPath path = CanonicalPath::create_empty ();
615 : 7 : bool ok
616 : 7 : = ResolveTypeToCanonicalPath::go (type.get_trait_bound ().get_type_path (),
617 : : path);
618 : 7 : if (ok)
619 : : {
620 : 14 : std::string slice_path = "<dyn " + path.get () + ">";
621 : 7 : result = CanonicalPath::new_seg (type.get_node_id (), slice_path);
622 : 7 : }
623 : 7 : }
624 : :
625 : : void
626 : 3 : ResolveTypeToCanonicalPath::visit (AST::TraitObjectType &type)
627 : : {
628 : 3 : rust_assert (!type.get_type_param_bounds ().empty ());
629 : :
630 : 3 : auto &first_bound = type.get_type_param_bounds ().front ();
631 : :
632 : : // Is it allowed or even possible to have a lifetime bound as a first bound?
633 : 3 : if (first_bound->get_bound_type () == AST::TraitBound::LIFETIME)
634 : 0 : rust_unreachable ();
635 : :
636 : 3 : auto &trait = static_cast<AST::TraitBound &> (*first_bound);
637 : :
638 : 3 : CanonicalPath path = CanonicalPath::create_empty ();
639 : 3 : bool ok = ResolveTypeToCanonicalPath::go (trait.get_type_path (), path);
640 : :
641 : : // right?
642 : 3 : rust_assert (ok);
643 : :
644 : 3 : auto slice_path = "<dyn " + path.get ();
645 : :
646 : 9 : for (size_t idx = 1; idx < type.get_type_param_bounds ().size (); idx++)
647 : : {
648 : 6 : auto &additional_bound = type.get_type_param_bounds ()[idx];
649 : :
650 : 6 : std::string str;
651 : :
652 : 6 : switch (additional_bound->get_bound_type ())
653 : : {
654 : 6 : case AST::TypeParamBound::TRAIT: {
655 : 6 : auto bound_path = CanonicalPath::create_empty ();
656 : :
657 : 6 : auto &bound_type_path
658 : 6 : = static_cast<AST::TraitBound &> (*additional_bound)
659 : 6 : .get_type_path ();
660 : 6 : bool ok
661 : 6 : = ResolveTypeToCanonicalPath::go (bound_type_path, bound_path);
662 : :
663 : 6 : if (!ok)
664 : 1 : continue;
665 : :
666 : 5 : str = bound_path.get ();
667 : 5 : break;
668 : 6 : }
669 : 0 : case AST::TypeParamBound::LIFETIME:
670 : 0 : rust_unreachable ();
671 : 5 : break;
672 : : }
673 : 10 : slice_path += " + " + str;
674 : 6 : }
675 : :
676 : 3 : slice_path += ">";
677 : :
678 : 3 : result = CanonicalPath::new_seg (type.get_node_id (), slice_path);
679 : 3 : }
680 : :
681 : : void
682 : 2 : ResolveTypeToCanonicalPath::visit (AST::NeverType &type)
683 : : {
684 : 2 : result = CanonicalPath::new_seg (type.get_node_id (), "!");
685 : 2 : }
686 : :
687 : : void
688 : 2 : ResolveTypeToCanonicalPath::visit (AST::TupleType &type)
689 : : {
690 : 2 : if (!type.is_unit_type ())
691 : 0 : rust_unreachable ();
692 : :
693 : 2 : result = CanonicalPath::new_seg (type.get_node_id (), "()");
694 : 2 : }
695 : :
696 : 9066 : ResolveTypeToCanonicalPath::ResolveTypeToCanonicalPath ()
697 : 9066 : : ResolverBase (), result (CanonicalPath::create_empty ())
698 : 9066 : {}
699 : :
700 : : bool
701 : 1754 : ResolveGenericArgs::is_const_value_name (const CanonicalPath &path)
702 : : {
703 : 1754 : NodeId resolved;
704 : 1754 : auto found = resolver->get_name_scope ().lookup (path, &resolved);
705 : :
706 : 1754 : return found;
707 : : }
708 : :
709 : : bool
710 : 1754 : ResolveGenericArgs::is_type_name (const CanonicalPath &path)
711 : : {
712 : 1754 : NodeId resolved;
713 : 1754 : auto found = resolver->get_type_scope ().lookup (path, &resolved);
714 : :
715 : 1754 : return found;
716 : : }
717 : :
718 : : void
719 : 1754 : ResolveGenericArgs::disambiguate (AST::GenericArg &arg)
720 : : {
721 : 1754 : auto path = canonical_prefix.append (
722 : 1754 : CanonicalPath::new_seg (UNKNOWN_NODEID, arg.get_path ()));
723 : :
724 : 1754 : auto is_type = is_type_name (path);
725 : 1754 : auto is_value = is_const_value_name (path);
726 : :
727 : : // In case we cannot find anything, we resolve the ambiguity to a type.
728 : : // This causes the typechecker to error out properly and when necessary.
729 : : // But types also take priority over const values in the case of
730 : : // ambiguities, hence the weird control flow
731 : 1754 : if (is_type || (!is_type && !is_value))
732 : 1751 : arg = arg.disambiguate_to_type ();
733 : 3 : else if (is_value)
734 : 3 : arg = arg.disambiguate_to_const ();
735 : 1754 : }
736 : :
737 : : void
738 : 3580 : ResolveGenericArgs::resolve_disambiguated_generic (AST::GenericArg &arg)
739 : : {
740 : 3580 : switch (arg.get_kind ())
741 : : {
742 : 8 : case AST::GenericArg::Kind::Const:
743 : 8 : ResolveExpr::go (arg.get_expression (), prefix, canonical_prefix);
744 : 8 : break;
745 : 3572 : case AST::GenericArg::Kind::Type:
746 : 3572 : ResolveType::go (arg.get_type ());
747 : 3572 : break;
748 : 0 : default:
749 : 0 : rust_unreachable ();
750 : : }
751 : 3580 : }
752 : : void
753 : 3322 : ResolveGenericArgs::go (AST::GenericArgs &generic_args)
754 : : {
755 : 3322 : auto empty = CanonicalPath::create_empty ();
756 : :
757 : 3322 : go (generic_args, empty, empty);
758 : 3322 : }
759 : :
760 : : void
761 : 3344 : ResolveGenericArgs::go (AST::GenericArgs &generic_args,
762 : : const CanonicalPath &prefix,
763 : : const CanonicalPath &canonical_prefix)
764 : : {
765 : 3344 : auto resolver = ResolveGenericArgs (prefix, canonical_prefix);
766 : :
767 : 6924 : for (auto &arg : generic_args.get_generic_args ())
768 : : {
769 : 3580 : if (arg.get_kind () == AST::GenericArg::Kind::Either)
770 : 1754 : resolver.disambiguate (arg);
771 : :
772 : 3580 : resolver.resolve_disambiguated_generic (arg);
773 : : }
774 : :
775 : 3400 : for (auto &binding : generic_args.get_binding_args ())
776 : : {
777 : 56 : ResolveType::go (binding.get_type ());
778 : : }
779 : 3344 : }
780 : :
781 : : } // namespace Resolver
782 : : } // namespace Rust
|