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 (), 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);
48 : : }
49 : 7 : }
50 : :
51 : : void
52 : 1884 : ResolveType::visit (AST::ReferenceType &type)
53 : : {
54 : 1884 : resolved_node = ResolveType::go (type.get_type_referenced ());
55 : 1884 : }
56 : :
57 : : void
58 : 4667 : ResolveType::visit (AST::RawPointerType &type)
59 : : {
60 : 4667 : resolved_node = ResolveType::go (type.get_type_pointed_to ());
61 : 4667 : }
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 : 812 : ResolveType::visit (AST::SliceType &type)
77 : : {
78 : 812 : resolved_node = ResolveType::go (type.get_elem_type ());
79 : 812 : }
80 : :
81 : : // resolve relative type-paths
82 : :
83 : : bool
84 : 34543 : ResolveRelativeTypePath::go (AST::TypePath &path, NodeId &resolved_node_id)
85 : : {
86 : 34543 : auto resolver = Resolver::get ();
87 : 34543 : auto mappings = Analysis::Mappings::get ();
88 : :
89 : 34543 : NodeId module_scope_id = resolver->peek_current_module_scope ();
90 : 34543 : NodeId previous_resolved_node_id = module_scope_id;
91 : 69952 : for (size_t i = 0; i < path.get_segments ().size (); i++)
92 : : {
93 : 35425 : auto &segment = path.get_segments ().at (i);
94 : 35425 : const AST::PathIdentSegment &ident_seg = segment->get_ident_segment ();
95 : 35425 : bool is_first_segment = i == 0;
96 : 35425 : resolved_node_id = UNKNOWN_NODEID;
97 : :
98 : 35425 : bool in_middle_of_path = i > 0;
99 : 35425 : 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: %qs in paths can only be used "
103 : : "in start position",
104 : 1 : segment->as_string ().c_str ());
105 : 1 : return false;
106 : : }
107 : :
108 : 35424 : NodeId crate_scope_id = resolver->peek_crate_module_scope ();
109 : 35424 : 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 : 35421 : 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 : 35421 : switch (segment->get_type ())
136 : : {
137 : 1381 : case AST::TypePathSegment::SegmentType::GENERIC: {
138 : 1381 : AST::TypePathSegmentGeneric *s
139 : 1381 : = static_cast<AST::TypePathSegmentGeneric *> (segment.get ());
140 : 1381 : if (s->has_generic_args ())
141 : 1381 : 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);
157 : : }
158 : :
159 : 19 : if (fn.has_return_type ())
160 : : {
161 : 17 : ResolveType::go (fn.get_return_type ());
162 : : }
163 : :
164 : : break;
165 : : }
166 : :
167 : 35421 : if (is_first_segment)
168 : : {
169 : : // name scope first
170 : 34540 : NodeId resolved_node = UNKNOWN_NODEID;
171 : 34540 : const CanonicalPath path
172 : : = CanonicalPath::new_seg (segment->get_node_id (),
173 : 34540 : ident_seg.as_string ());
174 : 34540 : if (resolver->get_type_scope ().lookup (path, &resolved_node))
175 : : {
176 : 34361 : resolver->insert_resolved_type (segment->get_node_id (),
177 : : resolved_node);
178 : 34361 : 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 : 34540 : }
197 : :
198 : 35418 : 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 %qs in this scope",
225 : 0 : segment->as_string ().c_str ());
226 : 0 : return false;
227 : : }
228 : : }
229 : : }
230 : :
231 : 35418 : bool did_resolve_segment = resolved_node_id != UNKNOWN_NODEID;
232 : 35418 : if (did_resolve_segment)
233 : : {
234 : 34620 : if (mappings->node_is_module (resolved_node_id)
235 : 34620 : || mappings->node_is_crate (resolved_node_id))
236 : : {
237 : 374 : module_scope_id = resolved_node_id;
238 : : }
239 : 34620 : 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 : 34527 : if (resolved_node_id != UNKNOWN_NODEID)
251 : : {
252 : : // name scope first
253 : 33744 : 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 : 33744 : else if (resolver->get_type_scope ().decl_was_declared_here (
260 : : resolved_node_id))
261 : : {
262 : 33744 : 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 ();
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 : 6511 : ResolveTypeToCanonicalPath::go (AST::Type &type, CanonicalPath &result)
360 : : {
361 : 6511 : ResolveTypeToCanonicalPath resolver;
362 : 6511 : type.accept_vis (resolver);
363 : 6511 : result = resolver.result;
364 : 6511 : return !resolver.result.is_empty ();
365 : 6511 : }
366 : :
367 : : void
368 : 5966 : ResolveTypeToCanonicalPath::visit (AST::TypePath &path)
369 : : {
370 : 5966 : NodeId resolved_node = UNKNOWN_NODEID;
371 : 5966 : if (!resolver->lookup_resolved_name (path.get_node_id (), &resolved_node))
372 : : {
373 : 5966 : resolver->lookup_resolved_type (path.get_node_id (), &resolved_node);
374 : : }
375 : :
376 : 5966 : if (resolved_node == UNKNOWN_NODEID)
377 : 1 : return;
378 : :
379 : 5965 : const CanonicalPath *type_path = nullptr;
380 : 5965 : if (mappings->lookup_canonical_path (resolved_node, &type_path))
381 : : {
382 : 5965 : auto &final_seg = path.get_segments ().back ();
383 : 5965 : switch (final_seg->get_type ())
384 : : {
385 : 554 : case AST::TypePathSegment::SegmentType::GENERIC: {
386 : 554 : AST::TypePathSegmentGeneric *s
387 : 554 : = static_cast<AST::TypePathSegmentGeneric *> (final_seg.get ());
388 : :
389 : 554 : std::vector<CanonicalPath> args;
390 : 554 : if (s->has_generic_args ())
391 : : {
392 : 554 : ResolveGenericArgs::go (s->get_generic_args ());
393 : 1185 : 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
406 : 631 : = ResolveTypeToCanonicalPath::go (generic.get_type (),
407 : : arg);
408 : 631 : if (ok)
409 : 630 : args.push_back (std::move (arg));
410 : 631 : }
411 : : }
412 : : }
413 : :
414 : 554 : result = *type_path;
415 : 554 : if (!args.empty ())
416 : : {
417 : : // append this onto the path
418 : 548 : std::string buf;
419 : 1178 : for (size_t i = 0; i < args.size (); i++)
420 : : {
421 : 630 : bool has_next = (i + 1) < args.size ();
422 : 630 : const auto &arg = args.at (i);
423 : :
424 : 630 : buf += arg.get ();
425 : 630 : if (has_next)
426 : 82 : buf += ", ";
427 : : }
428 : :
429 : 1096 : std::string arg_seg = "<" + buf + ">";
430 : 548 : CanonicalPath argument_seg
431 : 548 : = CanonicalPath::new_seg (s->get_node_id (), arg_seg);
432 : 548 : result = result.append (argument_seg);
433 : 548 : }
434 : 554 : }
435 : 554 : break;
436 : :
437 : 5411 : default:
438 : 5411 : result = *type_path;
439 : 5411 : break;
440 : : }
441 : : }
442 : : }
443 : :
444 : : void
445 : 242 : ResolveTypeToCanonicalPath::visit (AST::ReferenceType &type)
446 : : {
447 : 242 : CanonicalPath path = CanonicalPath::create_empty ();
448 : 242 : bool ok = ResolveTypeToCanonicalPath::go (type.get_type_referenced (), 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 = ResolveTypeToCanonicalPath::go (type.get_type_pointed_to (), path);
462 : 125 : if (ok)
463 : : {
464 : 125 : std::string ptr_type_str
465 : 125 : = type.get_pointer_type () == AST::RawPointerType::CONST ? "const"
466 : 137 : : "mut";
467 : 250 : std::string ptr_path = "*" + ptr_type_str + " " + path.get ();
468 : 125 : result = CanonicalPath::new_seg (type.get_node_id (), ptr_path);
469 : 125 : }
470 : 125 : }
471 : :
472 : : void
473 : 171 : ResolveTypeToCanonicalPath::visit (AST::SliceType &type)
474 : : {
475 : 171 : CanonicalPath path = CanonicalPath::create_empty ();
476 : 171 : bool ok = ResolveTypeToCanonicalPath::go (type.get_elem_type (), path);
477 : 171 : if (ok)
478 : : {
479 : 342 : std::string slice_path = "[" + path.get () + "]";
480 : 171 : result = CanonicalPath::new_seg (type.get_node_id (), slice_path);
481 : 171 : }
482 : 171 : }
483 : :
484 : : void
485 : 7 : ResolveTypeToCanonicalPath::visit (AST::TraitObjectTypeOneBound &type)
486 : : {
487 : 7 : CanonicalPath path = CanonicalPath::create_empty ();
488 : 7 : bool ok
489 : 7 : = ResolveTypeToCanonicalPath::go (type.get_trait_bound ().get_type_path (),
490 : : path);
491 : 7 : if (ok)
492 : : {
493 : 14 : std::string slice_path = "<dyn " + path.get () + ">";
494 : 7 : result = CanonicalPath::new_seg (type.get_node_id (), slice_path);
495 : 7 : }
496 : 7 : }
497 : :
498 : : void
499 : 0 : ResolveTypeToCanonicalPath::visit (AST::TraitObjectType &)
500 : : {
501 : : // FIXME is this actually allowed? dyn A+B
502 : 0 : rust_unreachable ();
503 : : }
504 : :
505 : 6511 : ResolveTypeToCanonicalPath::ResolveTypeToCanonicalPath ()
506 : 6511 : : ResolverBase (), result (CanonicalPath::create_empty ())
507 : 6511 : {}
508 : :
509 : : bool
510 : 1431 : ResolveGenericArgs::is_const_value_name (const CanonicalPath &path)
511 : : {
512 : 1431 : NodeId resolved;
513 : 1431 : auto found = resolver->get_name_scope ().lookup (path, &resolved);
514 : :
515 : 1431 : return found;
516 : : }
517 : :
518 : : bool
519 : 1431 : ResolveGenericArgs::is_type_name (const CanonicalPath &path)
520 : : {
521 : 1431 : NodeId resolved;
522 : 1431 : auto found = resolver->get_type_scope ().lookup (path, &resolved);
523 : :
524 : 1431 : return found;
525 : : }
526 : :
527 : : void
528 : 1431 : ResolveGenericArgs::disambiguate (AST::GenericArg &arg)
529 : : {
530 : 1431 : auto path = canonical_prefix.append (
531 : 1431 : CanonicalPath::new_seg (UNKNOWN_NODEID, arg.get_path ()));
532 : :
533 : 1431 : auto is_type = is_type_name (path);
534 : 1431 : auto is_value = is_const_value_name (path);
535 : :
536 : : // In case we cannot find anything, we resolve the ambiguity to a type.
537 : : // This causes the typechecker to error out properly and when necessary.
538 : : // But types also take priority over const values in the case of
539 : : // ambiguities, hence the weird control flow
540 : 1431 : if (is_type || (!is_type && !is_value))
541 : 1428 : arg = arg.disambiguate_to_type ();
542 : 3 : else if (is_value)
543 : 3 : arg = arg.disambiguate_to_const ();
544 : 1431 : }
545 : :
546 : : void
547 : 2733 : ResolveGenericArgs::resolve_disambiguated_generic (AST::GenericArg &arg)
548 : : {
549 : 2733 : switch (arg.get_kind ())
550 : : {
551 : 19 : case AST::GenericArg::Kind::Const:
552 : 19 : ResolveExpr::go (arg.get_expression (), prefix, canonical_prefix);
553 : 19 : break;
554 : 2714 : case AST::GenericArg::Kind::Type:
555 : 2714 : ResolveType::go (arg.get_type ());
556 : 2714 : break;
557 : 0 : default:
558 : 0 : rust_unreachable ();
559 : : }
560 : 2733 : }
561 : : void
562 : 2505 : ResolveGenericArgs::go (AST::GenericArgs &generic_args)
563 : : {
564 : 2505 : auto empty = CanonicalPath::create_empty ();
565 : :
566 : 2505 : go (generic_args, empty, empty);
567 : 2505 : }
568 : :
569 : : void
570 : 2527 : ResolveGenericArgs::go (AST::GenericArgs &generic_args,
571 : : const CanonicalPath &prefix,
572 : : const CanonicalPath &canonical_prefix)
573 : : {
574 : 2527 : auto resolver = ResolveGenericArgs (prefix, canonical_prefix);
575 : :
576 : 5260 : for (auto &arg : generic_args.get_generic_args ())
577 : : {
578 : 2733 : if (arg.get_kind () == AST::GenericArg::Kind::Either)
579 : 1431 : resolver.disambiguate (arg);
580 : :
581 : 2733 : resolver.resolve_disambiguated_generic (arg);
582 : : }
583 : :
584 : 2563 : for (auto &binding : generic_args.get_binding_args ())
585 : : {
586 : 36 : ResolveType::go (binding.get_type ());
587 : : }
588 : 2527 : }
589 : :
590 : : } // namespace Resolver
591 : : } // namespace Rust
|