1 // Copyright (C) 2020-2024 Free Software Foundation, Inc.
3 // This file is part of GCC.
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
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
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/>.
19 #include "rust-ast-resolve-expr.h"
20 #include "rust-ast-resolve-stmt.h"
21 #include "rust-ast-resolve-struct-expr-field.h"
22 #include "rust-ast-verify-assignee.h"
23 #include "rust-ast-resolve-type.h"
24 #include "rust-ast-resolve-pattern.h"
25 #include "rust-ast-resolve-path.h"
31 ResolveExpr::go (AST::Expr
*expr
, const CanonicalPath
&prefix
,
32 const CanonicalPath
&canonical_prefix
)
34 ResolveExpr
resolver (prefix
, canonical_prefix
);
35 expr
->accept_vis (resolver
);
39 ResolveExpr::visit (AST::TupleIndexExpr
&expr
)
41 ResolveExpr::go (expr
.get_tuple_expr ().get (), prefix
, canonical_prefix
);
45 ResolveExpr::visit (AST::TupleExpr
&expr
)
50 for (auto &elem
: expr
.get_tuple_elems ())
51 ResolveExpr::go (elem
.get (), prefix
, canonical_prefix
);
55 ResolveExpr::visit (AST::PathInExpression
&expr
)
57 ResolvePath::go (&expr
);
61 ResolveExpr::visit (AST::QualifiedPathInExpression
&expr
)
63 ResolvePath::go (&expr
);
67 ResolveExpr::visit (AST::ReturnExpr
&expr
)
69 if (expr
.has_returned_expr ())
70 ResolveExpr::go (expr
.get_returned_expr ().get (), prefix
,
75 ResolveExpr::visit (AST::CallExpr
&expr
)
77 ResolveExpr::go (expr
.get_function_expr ().get (), prefix
, canonical_prefix
);
78 for (auto ¶m
: expr
.get_params ())
79 ResolveExpr::go (param
.get (), prefix
, canonical_prefix
);
83 ResolveExpr::visit (AST::MethodCallExpr
&expr
)
85 ResolveExpr::go (expr
.get_receiver_expr ().get (), prefix
, canonical_prefix
);
87 if (expr
.get_method_name ().has_generic_args ())
89 AST::GenericArgs
&args
= expr
.get_method_name ().get_generic_args ();
90 ResolveGenericArgs::go (args
, prefix
, canonical_prefix
);
93 auto const &in_params
= expr
.get_params ();
94 for (auto ¶m
: in_params
)
95 ResolveExpr::go (param
.get (), prefix
, canonical_prefix
);
99 ResolveExpr::visit (AST::AssignmentExpr
&expr
)
101 ResolveExpr::go (expr
.get_left_expr ().get (), prefix
, canonical_prefix
);
102 ResolveExpr::go (expr
.get_right_expr ().get (), prefix
, canonical_prefix
);
104 // need to verify the assignee
105 VerifyAsignee::go (expr
.get_left_expr ().get ());
109 ResolveExpr::visit (AST::IdentifierExpr
&expr
)
111 if (resolver
->get_name_scope ().lookup (
112 CanonicalPath::new_seg (expr
.get_node_id (), expr
.as_string ()),
115 resolver
->insert_resolved_name (expr
.get_node_id (), resolved_node
);
117 else if (resolver
->get_type_scope ().lookup (
118 CanonicalPath::new_seg (expr
.get_node_id (), expr
.as_string ()),
121 resolver
->insert_resolved_type (expr
.get_node_id (), resolved_node
);
125 rust_error_at (expr
.get_locus (), "failed to find name: %s",
126 expr
.as_string ().c_str ());
131 ResolveExpr::visit (AST::ArithmeticOrLogicalExpr
&expr
)
133 ResolveExpr::go (expr
.get_left_expr ().get (), prefix
, canonical_prefix
);
134 ResolveExpr::go (expr
.get_right_expr ().get (), prefix
, canonical_prefix
);
138 ResolveExpr::visit (AST::CompoundAssignmentExpr
&expr
)
140 ResolveExpr::go (expr
.get_left_expr ().get (), prefix
, canonical_prefix
);
141 ResolveExpr::go (expr
.get_right_expr ().get (), prefix
, canonical_prefix
);
143 // need to verify the assignee
144 VerifyAsignee::go (expr
.get_left_expr ().get ());
148 ResolveExpr::visit (AST::ComparisonExpr
&expr
)
150 ResolveExpr::go (expr
.get_left_expr ().get (), prefix
, canonical_prefix
);
151 ResolveExpr::go (expr
.get_right_expr ().get (), prefix
, canonical_prefix
);
155 ResolveExpr::visit (AST::LazyBooleanExpr
&expr
)
157 ResolveExpr::go (expr
.get_left_expr ().get (), prefix
, canonical_prefix
);
158 ResolveExpr::go (expr
.get_right_expr ().get (), prefix
, canonical_prefix
);
162 ResolveExpr::visit (AST::NegationExpr
&expr
)
164 ResolveExpr::go (expr
.get_negated_expr ().get (), prefix
, canonical_prefix
);
168 ResolveExpr::visit (AST::TypeCastExpr
&expr
)
170 ResolveType::go (expr
.get_type_to_cast_to ().get ());
171 ResolveExpr::go (expr
.get_casted_expr ().get (), prefix
, canonical_prefix
);
175 ResolveExpr::visit (AST::IfExpr
&expr
)
177 ResolveExpr::go (expr
.get_condition_expr ().get (), prefix
, canonical_prefix
);
178 ResolveExpr::go (expr
.get_if_block ().get (), prefix
, canonical_prefix
);
182 ResolveExpr::visit (AST::IfExprConseqElse
&expr
)
184 ResolveExpr::go (expr
.get_condition_expr ().get (), prefix
, canonical_prefix
);
185 ResolveExpr::go (expr
.get_if_block ().get (), prefix
, canonical_prefix
);
186 ResolveExpr::go (expr
.get_else_block ().get (), prefix
, canonical_prefix
);
190 ResolveExpr::visit (AST::IfExprConseqIf
&expr
)
192 ResolveExpr::go (expr
.get_condition_expr ().get (), prefix
, canonical_prefix
);
193 ResolveExpr::go (expr
.get_if_block ().get (), prefix
, canonical_prefix
);
194 ResolveExpr::go (expr
.get_conseq_if_expr ().get (), prefix
, canonical_prefix
);
198 ResolveExpr::visit (AST::IfLetExpr
&expr
)
200 ResolveExpr::go (expr
.get_value_expr ().get (), prefix
, canonical_prefix
);
202 NodeId scope_node_id
= expr
.get_node_id ();
203 resolver
->get_name_scope ().push (scope_node_id
);
204 resolver
->get_type_scope ().push (scope_node_id
);
205 resolver
->get_label_scope ().push (scope_node_id
);
206 resolver
->push_new_name_rib (resolver
->get_name_scope ().peek ());
207 resolver
->push_new_type_rib (resolver
->get_type_scope ().peek ());
208 resolver
->push_new_label_rib (resolver
->get_type_scope ().peek ());
210 for (auto &pattern
: expr
.get_patterns ())
212 PatternDeclaration::go (pattern
.get (), Rib::ItemType::Var
);
215 ResolveExpr::go (expr
.get_if_block ().get (), prefix
, canonical_prefix
);
217 resolver
->get_name_scope ().pop ();
218 resolver
->get_type_scope ().pop ();
219 resolver
->get_label_scope ().pop ();
223 ResolveExpr::visit (AST::BlockExpr
&expr
)
225 NodeId scope_node_id
= expr
.get_node_id ();
226 resolver
->get_name_scope ().push (scope_node_id
);
227 resolver
->get_type_scope ().push (scope_node_id
);
228 resolver
->get_label_scope ().push (scope_node_id
);
229 resolver
->push_new_name_rib (resolver
->get_name_scope ().peek ());
230 resolver
->push_new_type_rib (resolver
->get_type_scope ().peek ());
231 resolver
->push_new_label_rib (resolver
->get_type_scope ().peek ());
233 for (auto &s
: expr
.get_statements ())
236 ResolveStmt::go (s
.get (), prefix
, canonical_prefix
,
237 CanonicalPath::create_empty ());
240 for (auto &s
: expr
.get_statements ())
243 ResolveStmt::go (s
.get (), prefix
, canonical_prefix
,
244 CanonicalPath::create_empty ());
247 if (expr
.has_tail_expr ())
248 ResolveExpr::go (expr
.get_tail_expr ().get (), prefix
, canonical_prefix
);
250 resolver
->get_name_scope ().pop ();
251 resolver
->get_type_scope ().pop ();
252 resolver
->get_label_scope ().pop ();
256 ResolveExpr::visit (AST::UnsafeBlockExpr
&expr
)
258 expr
.get_block_expr ()->accept_vis (*this);
262 ResolveExpr::visit (AST::ArrayElemsValues
&elems
)
264 for (auto &elem
: elems
.get_values ())
265 ResolveExpr::go (elem
.get (), prefix
, canonical_prefix
);
269 ResolveExpr::visit (AST::ArrayExpr
&expr
)
271 expr
.get_array_elems ()->accept_vis (*this);
275 ResolveExpr::visit (AST::ArrayIndexExpr
&expr
)
277 ResolveExpr::go (expr
.get_array_expr ().get (), prefix
, canonical_prefix
);
278 ResolveExpr::go (expr
.get_index_expr ().get (), prefix
, canonical_prefix
);
282 ResolveExpr::visit (AST::ArrayElemsCopied
&expr
)
284 ResolveExpr::go (expr
.get_num_copies ().get (), prefix
, canonical_prefix
);
285 ResolveExpr::go (expr
.get_elem_to_copy ().get (), prefix
, canonical_prefix
);
288 // this this an empty struct constructor like 'S {}'
290 ResolveExpr::visit (AST::StructExprStruct
&struct_expr
)
292 ResolveExpr::go (&struct_expr
.get_struct_name (), prefix
, canonical_prefix
);
295 // this this a struct constructor with fields
297 ResolveExpr::visit (AST::StructExprStructFields
&struct_expr
)
299 ResolveExpr::go (&struct_expr
.get_struct_name (), prefix
, canonical_prefix
);
301 if (struct_expr
.has_struct_base ())
303 AST::StructBase
&base
= struct_expr
.get_struct_base ();
304 ResolveExpr::go (base
.get_base_struct ().get (), prefix
,
308 auto const &struct_fields
= struct_expr
.get_fields ();
309 for (auto &struct_field
: struct_fields
)
311 ResolveStructExprField::go (struct_field
.get (), prefix
,
317 ResolveExpr::visit (AST::GroupedExpr
&expr
)
319 ResolveExpr::go (expr
.get_expr_in_parens ().get (), prefix
, canonical_prefix
);
323 ResolveExpr::visit (AST::FieldAccessExpr
&expr
)
325 ResolveExpr::go (expr
.get_receiver_expr ().get (), prefix
, canonical_prefix
);
329 ResolveExpr::visit (AST::LoopExpr
&expr
)
331 if (expr
.has_loop_label ())
333 auto label
= expr
.get_loop_label ();
334 if (label
.get_lifetime ().get_lifetime_type ()
335 != AST::Lifetime::LifetimeType::NAMED
)
337 rust_error_at (label
.get_locus (),
338 "Labels must be a named lifetime value");
342 auto label_name
= label
.get_lifetime ().get_lifetime_name ();
343 auto label_lifetime_node_id
= label
.get_lifetime ().get_node_id ();
344 resolver
->get_label_scope ().insert (
345 CanonicalPath::new_seg (expr
.get_node_id (), label_name
),
346 label_lifetime_node_id
, label
.get_locus (), false, Rib::ItemType::Label
,
347 [&] (const CanonicalPath
&, NodeId
, Location locus
) -> void {
348 rust_error_at (label
.get_locus (), "label redefined multiple times");
349 rust_error_at (locus
, "was defined here");
352 ResolveExpr::go (expr
.get_loop_block ().get (), prefix
, canonical_prefix
);
356 ResolveExpr::visit (AST::BreakExpr
&expr
)
358 if (expr
.has_label ())
360 auto label
= expr
.get_label ();
361 if (label
.get_lifetime_type () != AST::Lifetime::LifetimeType::NAMED
)
363 rust_error_at (label
.get_locus (),
364 "Labels must be a named lifetime value");
368 NodeId resolved_node
= UNKNOWN_NODEID
;
369 if (!resolver
->get_label_scope ().lookup (
370 CanonicalPath::new_seg (label
.get_node_id (),
371 label
.get_lifetime_name ()),
374 rust_error_at (expr
.get_label ().get_locus (),
375 "failed to resolve label");
378 resolver
->insert_resolved_label (label
.get_node_id (), resolved_node
);
381 if (expr
.has_break_expr ())
382 ResolveExpr::go (expr
.get_break_expr ().get (), prefix
, canonical_prefix
);
386 ResolveExpr::visit (AST::WhileLoopExpr
&expr
)
388 if (expr
.has_loop_label ())
390 auto label
= expr
.get_loop_label ();
391 if (label
.get_lifetime ().get_lifetime_type ()
392 != AST::Lifetime::LifetimeType::NAMED
)
394 rust_error_at (label
.get_locus (),
395 "Labels must be a named lifetime value");
399 auto label_name
= label
.get_lifetime ().get_lifetime_name ();
400 auto label_lifetime_node_id
= label
.get_lifetime ().get_node_id ();
401 resolver
->get_label_scope ().insert (
402 CanonicalPath::new_seg (label
.get_node_id (), label_name
),
403 label_lifetime_node_id
, label
.get_locus (), false, Rib::ItemType::Label
,
404 [&] (const CanonicalPath
&, NodeId
, Location locus
) -> void {
405 rust_error_at (label
.get_locus (), "label redefined multiple times");
406 rust_error_at (locus
, "was defined here");
410 ResolveExpr::go (expr
.get_predicate_expr ().get (), prefix
, canonical_prefix
);
411 ResolveExpr::go (expr
.get_loop_block ().get (), prefix
, canonical_prefix
);
415 ResolveExpr::visit (AST::ForLoopExpr
&expr
)
417 if (expr
.has_loop_label ())
419 auto label
= expr
.get_loop_label ();
420 if (label
.get_lifetime ().get_lifetime_type ()
421 != AST::Lifetime::LifetimeType::NAMED
)
423 rust_error_at (label
.get_locus (),
424 "Labels must be a named lifetime value");
428 auto label_name
= label
.get_lifetime ().get_lifetime_name ();
429 auto label_lifetime_node_id
= label
.get_lifetime ().get_node_id ();
430 resolver
->get_label_scope ().insert (
431 CanonicalPath::new_seg (label
.get_node_id (), label_name
),
432 label_lifetime_node_id
, label
.get_locus (), false, Rib::ItemType::Label
,
433 [&] (const CanonicalPath
&, NodeId
, Location locus
) -> void {
434 rust_error_at (label
.get_locus (), "label redefined multiple times");
435 rust_error_at (locus
, "was defined here");
439 // this needs a new rib to contain the pattern
440 NodeId scope_node_id
= expr
.get_node_id ();
441 resolver
->get_name_scope ().push (scope_node_id
);
442 resolver
->get_type_scope ().push (scope_node_id
);
443 resolver
->get_label_scope ().push (scope_node_id
);
444 resolver
->push_new_name_rib (resolver
->get_name_scope ().peek ());
445 resolver
->push_new_type_rib (resolver
->get_type_scope ().peek ());
446 resolver
->push_new_label_rib (resolver
->get_type_scope ().peek ());
448 // resolve the expression
449 PatternDeclaration::go (expr
.get_pattern ().get (), Rib::ItemType::Var
);
450 ResolveExpr::go (expr
.get_iterator_expr ().get (), prefix
, canonical_prefix
);
451 ResolveExpr::go (expr
.get_loop_block ().get (), prefix
, canonical_prefix
);
454 resolver
->get_name_scope ().pop ();
455 resolver
->get_type_scope ().pop ();
456 resolver
->get_label_scope ().pop ();
460 ResolveExpr::visit (AST::ContinueExpr
&expr
)
462 if (expr
.has_label ())
464 auto label
= expr
.get_label ();
465 if (label
.get_lifetime_type () != AST::Lifetime::LifetimeType::NAMED
)
467 rust_error_at (label
.get_locus (),
468 "Labels must be a named lifetime value");
472 NodeId resolved_node
= UNKNOWN_NODEID
;
473 if (!resolver
->get_label_scope ().lookup (
474 CanonicalPath::new_seg (label
.get_node_id (),
475 label
.get_lifetime_name ()),
478 rust_error_at (expr
.get_label ().get_locus (),
479 "failed to resolve label");
482 resolver
->insert_resolved_label (label
.get_node_id (), resolved_node
);
487 ResolveExpr::visit (AST::BorrowExpr
&expr
)
489 ResolveExpr::go (expr
.get_borrowed_expr ().get (), prefix
, canonical_prefix
);
493 ResolveExpr::visit (AST::DereferenceExpr
&expr
)
495 ResolveExpr::go (expr
.get_dereferenced_expr ().get (), prefix
,
500 ResolveExpr::visit (AST::MatchExpr
&expr
)
502 ResolveExpr::go (expr
.get_scrutinee_expr ().get (), prefix
, canonical_prefix
);
503 for (auto &match_case
: expr
.get_match_cases ())
505 // each arm is in its own scope
506 NodeId scope_node_id
= match_case
.get_node_id ();
507 resolver
->get_name_scope ().push (scope_node_id
);
508 resolver
->get_type_scope ().push (scope_node_id
);
509 resolver
->get_label_scope ().push (scope_node_id
);
510 resolver
->push_new_name_rib (resolver
->get_name_scope ().peek ());
511 resolver
->push_new_type_rib (resolver
->get_type_scope ().peek ());
512 resolver
->push_new_label_rib (resolver
->get_type_scope ().peek ());
515 AST::MatchArm
&arm
= match_case
.get_arm ();
516 if (arm
.has_match_arm_guard ())
517 ResolveExpr::go (arm
.get_guard_expr ().get (), prefix
,
520 // insert any possible new patterns
521 for (auto &pattern
: arm
.get_patterns ())
523 PatternDeclaration::go (pattern
.get (), Rib::ItemType::Var
);
527 ResolveExpr::go (match_case
.get_expr ().get (), prefix
, canonical_prefix
);
530 resolver
->get_name_scope ().pop ();
531 resolver
->get_type_scope ().pop ();
532 resolver
->get_label_scope ().pop ();
537 ResolveExpr::visit (AST::RangeFromToExpr
&expr
)
539 ResolveExpr::go (expr
.get_from_expr ().get (), prefix
, canonical_prefix
);
540 ResolveExpr::go (expr
.get_to_expr ().get (), prefix
, canonical_prefix
);
544 ResolveExpr::visit (AST::RangeFromExpr
&expr
)
546 ResolveExpr::go (expr
.get_from_expr ().get (), prefix
, canonical_prefix
);
550 ResolveExpr::visit (AST::RangeToExpr
&expr
)
552 ResolveExpr::go (expr
.get_to_expr ().get (), prefix
, canonical_prefix
);
556 ResolveExpr::visit (AST::RangeFullExpr
&)
562 ResolveExpr::visit (AST::RangeFromToInclExpr
&expr
)
564 ResolveExpr::go (expr
.get_from_expr ().get (), prefix
, canonical_prefix
);
565 ResolveExpr::go (expr
.get_to_expr ().get (), prefix
, canonical_prefix
);
569 ResolveExpr::visit (AST::ClosureExprInner
&expr
)
571 NodeId scope_node_id
= expr
.get_node_id ();
572 resolver
->get_name_scope ().push (scope_node_id
);
573 resolver
->get_type_scope ().push (scope_node_id
);
574 resolver
->get_label_scope ().push (scope_node_id
);
575 resolver
->push_new_name_rib (resolver
->get_name_scope ().peek ());
576 resolver
->push_new_type_rib (resolver
->get_type_scope ().peek ());
577 resolver
->push_new_label_rib (resolver
->get_type_scope ().peek ());
579 for (auto &p
: expr
.get_params ())
581 resolve_closure_param (p
);
584 resolver
->push_closure_context (expr
.get_node_id ());
586 ResolveExpr::go (expr
.get_definition_expr ().get (), prefix
,
589 resolver
->pop_closure_context ();
591 resolver
->get_name_scope ().pop ();
592 resolver
->get_type_scope ().pop ();
593 resolver
->get_label_scope ().pop ();
597 ResolveExpr::visit (AST::ClosureExprInnerTyped
&expr
)
599 NodeId scope_node_id
= expr
.get_node_id ();
600 resolver
->get_name_scope ().push (scope_node_id
);
601 resolver
->get_type_scope ().push (scope_node_id
);
602 resolver
->get_label_scope ().push (scope_node_id
);
603 resolver
->push_new_name_rib (resolver
->get_name_scope ().peek ());
604 resolver
->push_new_type_rib (resolver
->get_type_scope ().peek ());
605 resolver
->push_new_label_rib (resolver
->get_type_scope ().peek ());
607 for (auto &p
: expr
.get_params ())
609 resolve_closure_param (p
);
612 ResolveType::go (expr
.get_return_type ().get ());
614 resolver
->push_closure_context (expr
.get_node_id ());
616 ResolveExpr::go (expr
.get_definition_block ().get (), prefix
,
619 resolver
->pop_closure_context ();
621 resolver
->get_name_scope ().pop ();
622 resolver
->get_type_scope ().pop ();
623 resolver
->get_label_scope ().pop ();
627 ResolveExpr::resolve_closure_param (AST::ClosureParam
¶m
)
629 PatternDeclaration::go (param
.get_pattern ().get (), Rib::ItemType::Param
);
631 if (param
.has_type_given ())
632 ResolveType::go (param
.get_type ().get ());
635 ResolveExpr::ResolveExpr (const CanonicalPath
&prefix
,
636 const CanonicalPath
&canonical_prefix
)
637 : ResolverBase (), prefix (prefix
), canonical_prefix (canonical_prefix
)
640 } // namespace Resolver