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