]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/rust/resolve/rust-ast-resolve-expr.cc
Update copyright years.
[thirdparty/gcc.git] / gcc / rust / resolve / rust-ast-resolve-expr.cc
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-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"
26
27 namespace Rust {
28 namespace Resolver {
29
30 void
31 ResolveExpr::go (AST::Expr *expr, const CanonicalPath &prefix,
32 const CanonicalPath &canonical_prefix)
33 {
34 ResolveExpr resolver (prefix, canonical_prefix);
35 expr->accept_vis (resolver);
36 }
37
38 void
39 ResolveExpr::visit (AST::TupleIndexExpr &expr)
40 {
41 ResolveExpr::go (expr.get_tuple_expr ().get (), prefix, canonical_prefix);
42 }
43
44 void
45 ResolveExpr::visit (AST::TupleExpr &expr)
46 {
47 if (expr.is_unit ())
48 return;
49
50 for (auto &elem : expr.get_tuple_elems ())
51 ResolveExpr::go (elem.get (), prefix, canonical_prefix);
52 }
53
54 void
55 ResolveExpr::visit (AST::PathInExpression &expr)
56 {
57 ResolvePath::go (&expr);
58 }
59
60 void
61 ResolveExpr::visit (AST::QualifiedPathInExpression &expr)
62 {
63 ResolvePath::go (&expr);
64 }
65
66 void
67 ResolveExpr::visit (AST::ReturnExpr &expr)
68 {
69 if (expr.has_returned_expr ())
70 ResolveExpr::go (expr.get_returned_expr ().get (), prefix,
71 canonical_prefix);
72 }
73
74 void
75 ResolveExpr::visit (AST::CallExpr &expr)
76 {
77 ResolveExpr::go (expr.get_function_expr ().get (), prefix, canonical_prefix);
78 for (auto &param : expr.get_params ())
79 ResolveExpr::go (param.get (), prefix, canonical_prefix);
80 }
81
82 void
83 ResolveExpr::visit (AST::MethodCallExpr &expr)
84 {
85 ResolveExpr::go (expr.get_receiver_expr ().get (), prefix, canonical_prefix);
86
87 if (expr.get_method_name ().has_generic_args ())
88 {
89 AST::GenericArgs &args = expr.get_method_name ().get_generic_args ();
90 ResolveGenericArgs::go (args, prefix, canonical_prefix);
91 }
92
93 auto const &in_params = expr.get_params ();
94 for (auto &param : in_params)
95 ResolveExpr::go (param.get (), prefix, canonical_prefix);
96 }
97
98 void
99 ResolveExpr::visit (AST::AssignmentExpr &expr)
100 {
101 ResolveExpr::go (expr.get_left_expr ().get (), prefix, canonical_prefix);
102 ResolveExpr::go (expr.get_right_expr ().get (), prefix, canonical_prefix);
103
104 // need to verify the assignee
105 VerifyAsignee::go (expr.get_left_expr ().get ());
106 }
107
108 void
109 ResolveExpr::visit (AST::IdentifierExpr &expr)
110 {
111 if (resolver->get_name_scope ().lookup (
112 CanonicalPath::new_seg (expr.get_node_id (), expr.as_string ()),
113 &resolved_node))
114 {
115 resolver->insert_resolved_name (expr.get_node_id (), resolved_node);
116 }
117 else if (resolver->get_type_scope ().lookup (
118 CanonicalPath::new_seg (expr.get_node_id (), expr.as_string ()),
119 &resolved_node))
120 {
121 resolver->insert_resolved_type (expr.get_node_id (), resolved_node);
122 }
123 else
124 {
125 rust_error_at (expr.get_locus (), "failed to find name: %s",
126 expr.as_string ().c_str ());
127 }
128 }
129
130 void
131 ResolveExpr::visit (AST::ArithmeticOrLogicalExpr &expr)
132 {
133 ResolveExpr::go (expr.get_left_expr ().get (), prefix, canonical_prefix);
134 ResolveExpr::go (expr.get_right_expr ().get (), prefix, canonical_prefix);
135 }
136
137 void
138 ResolveExpr::visit (AST::CompoundAssignmentExpr &expr)
139 {
140 ResolveExpr::go (expr.get_left_expr ().get (), prefix, canonical_prefix);
141 ResolveExpr::go (expr.get_right_expr ().get (), prefix, canonical_prefix);
142
143 // need to verify the assignee
144 VerifyAsignee::go (expr.get_left_expr ().get ());
145 }
146
147 void
148 ResolveExpr::visit (AST::ComparisonExpr &expr)
149 {
150 ResolveExpr::go (expr.get_left_expr ().get (), prefix, canonical_prefix);
151 ResolveExpr::go (expr.get_right_expr ().get (), prefix, canonical_prefix);
152 }
153
154 void
155 ResolveExpr::visit (AST::LazyBooleanExpr &expr)
156 {
157 ResolveExpr::go (expr.get_left_expr ().get (), prefix, canonical_prefix);
158 ResolveExpr::go (expr.get_right_expr ().get (), prefix, canonical_prefix);
159 }
160
161 void
162 ResolveExpr::visit (AST::NegationExpr &expr)
163 {
164 ResolveExpr::go (expr.get_negated_expr ().get (), prefix, canonical_prefix);
165 }
166
167 void
168 ResolveExpr::visit (AST::TypeCastExpr &expr)
169 {
170 ResolveType::go (expr.get_type_to_cast_to ().get ());
171 ResolveExpr::go (expr.get_casted_expr ().get (), prefix, canonical_prefix);
172 }
173
174 void
175 ResolveExpr::visit (AST::IfExpr &expr)
176 {
177 ResolveExpr::go (expr.get_condition_expr ().get (), prefix, canonical_prefix);
178 ResolveExpr::go (expr.get_if_block ().get (), prefix, canonical_prefix);
179 }
180
181 void
182 ResolveExpr::visit (AST::IfExprConseqElse &expr)
183 {
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);
187 }
188
189 void
190 ResolveExpr::visit (AST::IfExprConseqIf &expr)
191 {
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);
195 }
196
197 void
198 ResolveExpr::visit (AST::IfLetExpr &expr)
199 {
200 ResolveExpr::go (expr.get_value_expr ().get (), prefix, canonical_prefix);
201
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 ());
209
210 for (auto &pattern : expr.get_patterns ())
211 {
212 PatternDeclaration::go (pattern.get (), Rib::ItemType::Var);
213 }
214
215 ResolveExpr::go (expr.get_if_block ().get (), prefix, canonical_prefix);
216
217 resolver->get_name_scope ().pop ();
218 resolver->get_type_scope ().pop ();
219 resolver->get_label_scope ().pop ();
220 }
221
222 void
223 ResolveExpr::visit (AST::BlockExpr &expr)
224 {
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 ());
232
233 for (auto &s : expr.get_statements ())
234 {
235 if (s->is_item ())
236 ResolveStmt::go (s.get (), prefix, canonical_prefix,
237 CanonicalPath::create_empty ());
238 }
239
240 for (auto &s : expr.get_statements ())
241 {
242 if (!s->is_item ())
243 ResolveStmt::go (s.get (), prefix, canonical_prefix,
244 CanonicalPath::create_empty ());
245 }
246
247 if (expr.has_tail_expr ())
248 ResolveExpr::go (expr.get_tail_expr ().get (), prefix, canonical_prefix);
249
250 resolver->get_name_scope ().pop ();
251 resolver->get_type_scope ().pop ();
252 resolver->get_label_scope ().pop ();
253 }
254
255 void
256 ResolveExpr::visit (AST::UnsafeBlockExpr &expr)
257 {
258 expr.get_block_expr ()->accept_vis (*this);
259 }
260
261 void
262 ResolveExpr::visit (AST::ArrayElemsValues &elems)
263 {
264 for (auto &elem : elems.get_values ())
265 ResolveExpr::go (elem.get (), prefix, canonical_prefix);
266 }
267
268 void
269 ResolveExpr::visit (AST::ArrayExpr &expr)
270 {
271 expr.get_array_elems ()->accept_vis (*this);
272 }
273
274 void
275 ResolveExpr::visit (AST::ArrayIndexExpr &expr)
276 {
277 ResolveExpr::go (expr.get_array_expr ().get (), prefix, canonical_prefix);
278 ResolveExpr::go (expr.get_index_expr ().get (), prefix, canonical_prefix);
279 }
280
281 void
282 ResolveExpr::visit (AST::ArrayElemsCopied &expr)
283 {
284 ResolveExpr::go (expr.get_num_copies ().get (), prefix, canonical_prefix);
285 ResolveExpr::go (expr.get_elem_to_copy ().get (), prefix, canonical_prefix);
286 }
287
288 // this this an empty struct constructor like 'S {}'
289 void
290 ResolveExpr::visit (AST::StructExprStruct &struct_expr)
291 {
292 ResolveExpr::go (&struct_expr.get_struct_name (), prefix, canonical_prefix);
293 }
294
295 // this this a struct constructor with fields
296 void
297 ResolveExpr::visit (AST::StructExprStructFields &struct_expr)
298 {
299 ResolveExpr::go (&struct_expr.get_struct_name (), prefix, canonical_prefix);
300
301 if (struct_expr.has_struct_base ())
302 {
303 AST::StructBase &base = struct_expr.get_struct_base ();
304 ResolveExpr::go (base.get_base_struct ().get (), prefix,
305 canonical_prefix);
306 }
307
308 auto const &struct_fields = struct_expr.get_fields ();
309 for (auto &struct_field : struct_fields)
310 {
311 ResolveStructExprField::go (struct_field.get (), prefix,
312 canonical_prefix);
313 }
314 }
315
316 void
317 ResolveExpr::visit (AST::GroupedExpr &expr)
318 {
319 ResolveExpr::go (expr.get_expr_in_parens ().get (), prefix, canonical_prefix);
320 }
321
322 void
323 ResolveExpr::visit (AST::FieldAccessExpr &expr)
324 {
325 ResolveExpr::go (expr.get_receiver_expr ().get (), prefix, canonical_prefix);
326 }
327
328 void
329 ResolveExpr::visit (AST::LoopExpr &expr)
330 {
331 if (expr.has_loop_label ())
332 {
333 auto label = expr.get_loop_label ();
334 if (label.get_lifetime ().get_lifetime_type ()
335 != AST::Lifetime::LifetimeType::NAMED)
336 {
337 rust_error_at (label.get_locus (),
338 "Labels must be a named lifetime value");
339 return;
340 }
341
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");
350 });
351 }
352 ResolveExpr::go (expr.get_loop_block ().get (), prefix, canonical_prefix);
353 }
354
355 void
356 ResolveExpr::visit (AST::BreakExpr &expr)
357 {
358 if (expr.has_label ())
359 {
360 auto label = expr.get_label ();
361 if (label.get_lifetime_type () != AST::Lifetime::LifetimeType::NAMED)
362 {
363 rust_error_at (label.get_locus (),
364 "Labels must be a named lifetime value");
365 return;
366 }
367
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 ()),
372 &resolved_node))
373 {
374 rust_error_at (expr.get_label ().get_locus (),
375 "failed to resolve label");
376 return;
377 }
378 resolver->insert_resolved_label (label.get_node_id (), resolved_node);
379 }
380
381 if (expr.has_break_expr ())
382 ResolveExpr::go (expr.get_break_expr ().get (), prefix, canonical_prefix);
383 }
384
385 void
386 ResolveExpr::visit (AST::WhileLoopExpr &expr)
387 {
388 if (expr.has_loop_label ())
389 {
390 auto label = expr.get_loop_label ();
391 if (label.get_lifetime ().get_lifetime_type ()
392 != AST::Lifetime::LifetimeType::NAMED)
393 {
394 rust_error_at (label.get_locus (),
395 "Labels must be a named lifetime value");
396 return;
397 }
398
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");
407 });
408 }
409
410 ResolveExpr::go (expr.get_predicate_expr ().get (), prefix, canonical_prefix);
411 ResolveExpr::go (expr.get_loop_block ().get (), prefix, canonical_prefix);
412 }
413
414 void
415 ResolveExpr::visit (AST::ForLoopExpr &expr)
416 {
417 if (expr.has_loop_label ())
418 {
419 auto label = expr.get_loop_label ();
420 if (label.get_lifetime ().get_lifetime_type ()
421 != AST::Lifetime::LifetimeType::NAMED)
422 {
423 rust_error_at (label.get_locus (),
424 "Labels must be a named lifetime value");
425 return;
426 }
427
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");
436 });
437 }
438
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 ());
447
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);
452
453 // done
454 resolver->get_name_scope ().pop ();
455 resolver->get_type_scope ().pop ();
456 resolver->get_label_scope ().pop ();
457 }
458
459 void
460 ResolveExpr::visit (AST::ContinueExpr &expr)
461 {
462 if (expr.has_label ())
463 {
464 auto label = expr.get_label ();
465 if (label.get_lifetime_type () != AST::Lifetime::LifetimeType::NAMED)
466 {
467 rust_error_at (label.get_locus (),
468 "Labels must be a named lifetime value");
469 return;
470 }
471
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 ()),
476 &resolved_node))
477 {
478 rust_error_at (expr.get_label ().get_locus (),
479 "failed to resolve label");
480 return;
481 }
482 resolver->insert_resolved_label (label.get_node_id (), resolved_node);
483 }
484 }
485
486 void
487 ResolveExpr::visit (AST::BorrowExpr &expr)
488 {
489 ResolveExpr::go (expr.get_borrowed_expr ().get (), prefix, canonical_prefix);
490 }
491
492 void
493 ResolveExpr::visit (AST::DereferenceExpr &expr)
494 {
495 ResolveExpr::go (expr.get_dereferenced_expr ().get (), prefix,
496 canonical_prefix);
497 }
498
499 void
500 ResolveExpr::visit (AST::MatchExpr &expr)
501 {
502 ResolveExpr::go (expr.get_scrutinee_expr ().get (), prefix, canonical_prefix);
503 for (auto &match_case : expr.get_match_cases ())
504 {
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 ());
513
514 // resolve
515 AST::MatchArm &arm = match_case.get_arm ();
516 if (arm.has_match_arm_guard ())
517 ResolveExpr::go (arm.get_guard_expr ().get (), prefix,
518 canonical_prefix);
519
520 // insert any possible new patterns
521 for (auto &pattern : arm.get_patterns ())
522 {
523 PatternDeclaration::go (pattern.get (), Rib::ItemType::Var);
524 }
525
526 // resolve the body
527 ResolveExpr::go (match_case.get_expr ().get (), prefix, canonical_prefix);
528
529 // done
530 resolver->get_name_scope ().pop ();
531 resolver->get_type_scope ().pop ();
532 resolver->get_label_scope ().pop ();
533 }
534 }
535
536 void
537 ResolveExpr::visit (AST::RangeFromToExpr &expr)
538 {
539 ResolveExpr::go (expr.get_from_expr ().get (), prefix, canonical_prefix);
540 ResolveExpr::go (expr.get_to_expr ().get (), prefix, canonical_prefix);
541 }
542
543 void
544 ResolveExpr::visit (AST::RangeFromExpr &expr)
545 {
546 ResolveExpr::go (expr.get_from_expr ().get (), prefix, canonical_prefix);
547 }
548
549 void
550 ResolveExpr::visit (AST::RangeToExpr &expr)
551 {
552 ResolveExpr::go (expr.get_to_expr ().get (), prefix, canonical_prefix);
553 }
554
555 void
556 ResolveExpr::visit (AST::RangeFullExpr &)
557 {
558 // nothing to do
559 }
560
561 void
562 ResolveExpr::visit (AST::RangeFromToInclExpr &expr)
563 {
564 ResolveExpr::go (expr.get_from_expr ().get (), prefix, canonical_prefix);
565 ResolveExpr::go (expr.get_to_expr ().get (), prefix, canonical_prefix);
566 }
567
568 void
569 ResolveExpr::visit (AST::ClosureExprInner &expr)
570 {
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 ());
578
579 for (auto &p : expr.get_params ())
580 {
581 resolve_closure_param (p);
582 }
583
584 resolver->push_closure_context (expr.get_node_id ());
585
586 ResolveExpr::go (expr.get_definition_expr ().get (), prefix,
587 canonical_prefix);
588
589 resolver->pop_closure_context ();
590
591 resolver->get_name_scope ().pop ();
592 resolver->get_type_scope ().pop ();
593 resolver->get_label_scope ().pop ();
594 }
595
596 void
597 ResolveExpr::visit (AST::ClosureExprInnerTyped &expr)
598 {
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 ());
606
607 for (auto &p : expr.get_params ())
608 {
609 resolve_closure_param (p);
610 }
611
612 ResolveType::go (expr.get_return_type ().get ());
613
614 resolver->push_closure_context (expr.get_node_id ());
615
616 ResolveExpr::go (expr.get_definition_block ().get (), prefix,
617 canonical_prefix);
618
619 resolver->pop_closure_context ();
620
621 resolver->get_name_scope ().pop ();
622 resolver->get_type_scope ().pop ();
623 resolver->get_label_scope ().pop ();
624 }
625
626 void
627 ResolveExpr::resolve_closure_param (AST::ClosureParam &param)
628 {
629 PatternDeclaration::go (param.get_pattern ().get (), Rib::ItemType::Param);
630
631 if (param.has_type_given ())
632 ResolveType::go (param.get_type ().get ());
633 }
634
635 ResolveExpr::ResolveExpr (const CanonicalPath &prefix,
636 const CanonicalPath &canonical_prefix)
637 : ResolverBase (), prefix (prefix), canonical_prefix (canonical_prefix)
638 {}
639
640 } // namespace Resolver
641 } // namespace Rust