]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/rust/resolve/rust-ast-resolve-item.cc
Update copyright years.
[thirdparty/gcc.git] / gcc / rust / resolve / rust-ast-resolve-item.cc
CommitLineData
83ffe9cd 1// Copyright (C) 2020-2023 Free Software Foundation, Inc.
85a8fe00
PH
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-item.h"
20#include "rust-ast-resolve-path.h"
21#include "selftest.h"
22
23namespace Rust {
24namespace Resolver {
25
26ResolveTraitItems::ResolveTraitItems (const CanonicalPath &prefix,
27 const CanonicalPath &canonical_prefix)
28 : ResolverBase (), prefix (prefix), canonical_prefix (canonical_prefix)
29{}
30
31void
32ResolveTraitItems::go (AST::TraitItem *item, const CanonicalPath &prefix,
33 const CanonicalPath &canonical_prefix)
34{
35 if (item->is_marked_for_strip ())
36 return;
37
38 ResolveTraitItems resolver (prefix, canonical_prefix);
39 item->accept_vis (resolver);
40}
41
42void
43ResolveTraitItems::visit (AST::TraitItemType &type)
44{
45 auto decl
46 = CanonicalPath::new_seg (type.get_node_id (), type.get_identifier ());
47 auto path = prefix.append (decl);
48 auto cpath = canonical_prefix.append (decl);
49 mappings->insert_canonical_path (type.get_node_id (), cpath);
50
51 for (auto &bound : type.get_type_param_bounds ())
52 ResolveTypeBound::go (bound.get ());
53}
54
55void
56ResolveTraitItems::visit (AST::TraitItemFunc &func)
57{
58 auto decl = CanonicalPath::new_seg (
59 func.get_node_id (), func.get_trait_function_decl ().get_identifier ());
60 auto path = prefix.append (decl);
61 auto cpath = canonical_prefix.append (decl);
62 mappings->insert_canonical_path (func.get_node_id (), cpath);
63
64 NodeId scope_node_id = func.get_node_id ();
65 resolver->get_name_scope ().push (scope_node_id);
66 resolver->get_type_scope ().push (scope_node_id);
67 resolver->get_label_scope ().push (scope_node_id);
68 resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
69 resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
70 resolver->push_new_label_rib (resolver->get_type_scope ().peek ());
71
72 AST::TraitFunctionDecl &function = func.get_trait_function_decl ();
73 if (function.has_generics ())
74 for (auto &generic : function.get_generic_params ())
75 ResolveGenericParam::go (generic.get (), prefix, canonical_prefix);
76
77 if (function.has_return_type ())
78 ResolveType::go (function.get_return_type ().get ());
79
80 // we make a new scope so the names of parameters are resolved and shadowed
81 // correctly
82 for (auto &param : function.get_function_params ())
83 {
84 ResolveType::go (param.get_type ().get ());
85 PatternDeclaration::go (param.get_pattern ().get ());
86 }
87
88 if (function.has_where_clause ())
89 ResolveWhereClause::Resolve (function.get_where_clause ());
90
91 // trait items have an optional body
92 if (func.has_definition ())
93 ResolveExpr::go (func.get_definition ().get (), path, cpath);
94
95 resolver->get_name_scope ().pop ();
96 resolver->get_type_scope ().pop ();
97 resolver->get_label_scope ().pop ();
98}
99
100void
101ResolveTraitItems::visit (AST::TraitItemMethod &func)
102{
103 auto decl
104 = CanonicalPath::new_seg (func.get_node_id (),
105 func.get_trait_method_decl ().get_identifier ());
106 auto path = prefix.append (decl);
107 auto cpath = canonical_prefix.append (decl);
108 mappings->insert_canonical_path (func.get_node_id (), cpath);
109
110 NodeId scope_node_id = func.get_node_id ();
111 resolver->get_name_scope ().push (scope_node_id);
112 resolver->get_type_scope ().push (scope_node_id);
113 resolver->get_label_scope ().push (scope_node_id);
114 resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
115 resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
116 resolver->push_new_label_rib (resolver->get_type_scope ().peek ());
117
118 AST::TraitMethodDecl &function = func.get_trait_method_decl ();
119 if (function.has_generics ())
120 for (auto &generic : function.get_generic_params ())
121 ResolveGenericParam::go (generic.get (), prefix, canonical_prefix);
122
123 if (function.has_return_type ())
124 ResolveType::go (function.get_return_type ().get ());
125
126 // self turns into (self: Self) as a function param
127 AST::SelfParam &self_param = function.get_self_param ();
128 AST::IdentifierPattern self_pattern (self_param.get_node_id (), "self",
129 self_param.get_locus (),
130 self_param.get_has_ref (),
131 self_param.get_is_mut (),
132 std::unique_ptr<AST::Pattern> (nullptr));
133
134 std::vector<std::unique_ptr<AST::TypePathSegment>> segments;
135 segments.push_back (std::unique_ptr<AST::TypePathSegment> (
136 new AST::TypePathSegment ("Self", false, self_param.get_locus ())));
137
138 AST::TypePath self_type_path (std::move (segments), self_param.get_locus ());
139
140 ResolveType::go (&self_type_path);
141 PatternDeclaration::go (&self_pattern);
142
143 // we make a new scope so the names of parameters are resolved and shadowed
144 // correctly
145 for (auto &param : function.get_function_params ())
146 {
147 ResolveType::go (param.get_type ().get ());
148 PatternDeclaration::go (param.get_pattern ().get ());
149 }
150
151 if (function.has_where_clause ())
152 ResolveWhereClause::Resolve (function.get_where_clause ());
153
154 // trait items have an optional body
155 if (func.has_definition ())
156 ResolveExpr::go (func.get_definition ().get (), path, cpath);
157
158 resolver->get_name_scope ().pop ();
159 resolver->get_type_scope ().pop ();
160 resolver->get_label_scope ().pop ();
161}
162
163void
164ResolveTraitItems::visit (AST::TraitItemConst &constant)
165{
166 auto decl = CanonicalPath::new_seg (constant.get_node_id (),
167 constant.get_identifier ());
168 auto path = prefix.append (decl);
169 auto cpath = canonical_prefix.append (decl);
170 mappings->insert_canonical_path (constant.get_node_id (), cpath);
171
172 ResolveType::go (constant.get_type ().get ());
173
174 if (constant.has_expr ())
175 ResolveExpr::go (constant.get_expr ().get (), path, cpath);
176}
177
178ResolveItem::ResolveItem (const CanonicalPath &prefix,
179 const CanonicalPath &canonical_prefix)
180 : ResolverBase (), prefix (prefix), canonical_prefix (canonical_prefix)
181{}
182
183void
184ResolveItem::go (AST::Item *item, const CanonicalPath &prefix,
185 const CanonicalPath &canonical_prefix)
186{
187 ResolveItem resolver (prefix, canonical_prefix);
188 item->accept_vis (resolver);
189}
190
191void
192ResolveItem::visit (AST::TypeAlias &alias)
193{
194 auto talias
195 = CanonicalPath::new_seg (alias.get_node_id (), alias.get_new_type_name ());
196 auto path = prefix.append (talias);
197 auto cpath = canonical_prefix.append (talias);
198 mappings->insert_canonical_path (alias.get_node_id (), cpath);
199
200 NodeId scope_node_id = alias.get_node_id ();
201 resolver->get_type_scope ().push (scope_node_id);
202
203 if (alias.has_generics ())
204 for (auto &generic : alias.get_generic_params ())
205 ResolveGenericParam::go (generic.get (), prefix, canonical_prefix);
206
207 if (alias.has_where_clause ())
208 ResolveWhereClause::Resolve (alias.get_where_clause ());
209
210 ResolveType::go (alias.get_type_aliased ().get ());
211
212 resolver->get_type_scope ().pop ();
213}
214
215void
216ResolveItem::visit (AST::Module &module)
217{
218 auto mod = CanonicalPath::new_seg (module.get_node_id (), module.get_name ());
219 auto path = prefix.append (mod);
220 auto cpath = canonical_prefix.append (mod);
221 mappings->insert_canonical_path (module.get_node_id (), cpath);
222
223 resolve_visibility (module.get_visibility ());
224
225 NodeId scope_node_id = module.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 // FIXME: Should we reinsert a child here? Any reason we ResolveTopLevel::go
234 // in ResolveTopLevel::visit (AST::Module) as well as here?
235 for (auto &item : module.get_items ())
236 ResolveTopLevel::go (item.get (), CanonicalPath::create_empty (), cpath);
237
238 resolver->push_new_module_scope (module.get_node_id ());
239 for (auto &item : module.get_items ())
240 ResolveItem::go (item.get (), path, cpath);
241
242 resolver->pop_module_scope ();
243
244 resolver->get_name_scope ().pop ();
245 resolver->get_type_scope ().pop ();
246 resolver->get_label_scope ().pop ();
247}
248
249void
250ResolveItem::visit (AST::TupleStruct &struct_decl)
251{
252 auto decl = CanonicalPath::new_seg (struct_decl.get_node_id (),
253 struct_decl.get_identifier ());
254 auto path = prefix.append (decl);
255 auto cpath = canonical_prefix.append (decl);
256 mappings->insert_canonical_path (struct_decl.get_node_id (), cpath);
257
258 resolve_visibility (struct_decl.get_visibility ());
259
260 NodeId scope_node_id = struct_decl.get_node_id ();
261 resolver->get_type_scope ().push (scope_node_id);
262
263 if (struct_decl.has_generics ())
264 for (auto &generic : struct_decl.get_generic_params ())
265 ResolveGenericParam::go (generic.get (), prefix, canonical_prefix);
266
267 if (struct_decl.has_where_clause ())
268 ResolveWhereClause::Resolve (struct_decl.get_where_clause ());
269
270 for (AST::TupleField &field : struct_decl.get_fields ())
271 {
272 if (field.get_field_type ()->is_marked_for_strip ())
273 continue;
274
275 resolve_visibility (field.get_visibility ());
276
277 ResolveType::go (field.get_field_type ().get ());
278 }
279
280 resolver->get_type_scope ().pop ();
281}
282
283void
284ResolveItem::visit (AST::Enum &enum_decl)
285{
286 auto decl = CanonicalPath::new_seg (enum_decl.get_node_id (),
287 enum_decl.get_identifier ());
288 auto path = prefix.append (decl);
289 auto cpath = canonical_prefix.append (decl);
290 mappings->insert_canonical_path (enum_decl.get_node_id (), cpath);
291
292 resolve_visibility (enum_decl.get_visibility ());
293
294 NodeId scope_node_id = enum_decl.get_node_id ();
295 resolver->get_type_scope ().push (scope_node_id);
296
297 if (enum_decl.has_generics ())
298 for (auto &generic : enum_decl.get_generic_params ())
299 ResolveGenericParam::go (generic.get (), prefix, cpath);
300
301 if (enum_decl.has_where_clause ())
302 ResolveWhereClause::Resolve (enum_decl.get_where_clause ());
303
304 /* The actual fields are inside the variants. */
305 for (auto &variant : enum_decl.get_variants ())
306 ResolveItem::go (variant.get (), path, cpath);
307
308 resolver->get_type_scope ().pop ();
309}
310
311/* EnumItem doesn't need to be handled, no fields. */
312void
313ResolveItem::visit (AST::EnumItem &item)
314{
315 // Since at this point we cannot have visibilities on enum items anymore, we
316 // can skip handling them
317
318 auto decl
319 = CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ());
320 auto path = prefix.append (decl);
321 auto cpath = canonical_prefix.append (decl);
322 mappings->insert_canonical_path (item.get_node_id (), cpath);
323}
324
325void
326ResolveItem::visit (AST::EnumItemTuple &item)
327{
328 auto decl
329 = CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ());
330 auto path = prefix.append (decl);
331 auto cpath = canonical_prefix.append (decl);
332 mappings->insert_canonical_path (item.get_node_id (), cpath);
333
334 for (auto &field : item.get_tuple_fields ())
335 {
336 if (field.get_field_type ()->is_marked_for_strip ())
337 continue;
338
339 ResolveType::go (field.get_field_type ().get ());
340 }
341}
342
343void
344ResolveItem::visit (AST::EnumItemStruct &item)
345{
346 auto decl
347 = CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ());
348 auto path = prefix.append (decl);
349 auto cpath = canonical_prefix.append (decl);
350 mappings->insert_canonical_path (item.get_node_id (), cpath);
351
352 for (auto &field : item.get_struct_fields ())
353 {
354 if (field.get_field_type ()->is_marked_for_strip ())
355 continue;
356
357 ResolveType::go (field.get_field_type ().get ());
358 }
359}
360
361void
362ResolveItem::visit (AST::EnumItemDiscriminant &item)
363{
364 auto decl
365 = CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ());
366 auto path = prefix.append (decl);
367 auto cpath = canonical_prefix.append (decl);
368
369 mappings->insert_canonical_path (item.get_node_id (), cpath);
370}
371
372void
373ResolveItem::visit (AST::StructStruct &struct_decl)
374{
375 auto decl = CanonicalPath::new_seg (struct_decl.get_node_id (),
376 struct_decl.get_identifier ());
377 auto path = prefix.append (decl);
378 auto cpath = canonical_prefix.append (decl);
379 mappings->insert_canonical_path (struct_decl.get_node_id (), cpath);
380
381 resolve_visibility (struct_decl.get_visibility ());
382
383 NodeId scope_node_id = struct_decl.get_node_id ();
384 resolver->get_type_scope ().push (scope_node_id);
385
386 if (struct_decl.has_generics ())
387 for (auto &generic : struct_decl.get_generic_params ())
388 ResolveGenericParam::go (generic.get (), prefix, canonical_prefix);
389
390 if (struct_decl.has_where_clause ())
391 ResolveWhereClause::Resolve (struct_decl.get_where_clause ());
392
393 for (AST::StructField &field : struct_decl.get_fields ())
394 {
395 if (field.get_field_type ()->is_marked_for_strip ())
396 continue;
397
398 resolve_visibility (field.get_visibility ());
399
400 ResolveType::go (field.get_field_type ().get ());
401 }
402
403 resolver->get_type_scope ().pop ();
404}
405
406void
407ResolveItem::visit (AST::Union &union_decl)
408{
409 auto decl = CanonicalPath::new_seg (union_decl.get_node_id (),
410 union_decl.get_identifier ());
411 auto path = prefix.append (decl);
412 auto cpath = canonical_prefix.append (decl);
413 mappings->insert_canonical_path (union_decl.get_node_id (), cpath);
414
415 resolve_visibility (union_decl.get_visibility ());
416
417 NodeId scope_node_id = union_decl.get_node_id ();
418 resolver->get_type_scope ().push (scope_node_id);
419
420 if (union_decl.has_generics ())
421 for (auto &generic : union_decl.get_generic_params ())
422 ResolveGenericParam::go (generic.get (), prefix, canonical_prefix);
423
424 if (union_decl.has_where_clause ())
425 ResolveWhereClause::Resolve (union_decl.get_where_clause ());
426
427 for (AST::StructField &field : union_decl.get_variants ())
428 {
429 if (field.get_field_type ()->is_marked_for_strip ())
430 continue;
431
432 ResolveType::go (field.get_field_type ().get ());
433 }
434
435 resolver->get_type_scope ().pop ();
436}
437
438void
439ResolveItem::visit (AST::StaticItem &var)
440{
441 auto decl
442 = CanonicalPath::new_seg (var.get_node_id (), var.get_identifier ());
443 auto path = prefix.append (decl);
444 auto cpath = canonical_prefix.append (decl);
445 mappings->insert_canonical_path (var.get_node_id (), cpath);
446
447 ResolveType::go (var.get_type ().get ());
448 ResolveExpr::go (var.get_expr ().get (), path, cpath);
449}
450
451void
452ResolveItem::visit (AST::ConstantItem &constant)
453{
454 auto decl = CanonicalPath::new_seg (constant.get_node_id (),
455 constant.get_identifier ());
456 auto path = prefix.append (decl);
457 auto cpath = canonical_prefix.append (decl);
458 mappings->insert_canonical_path (constant.get_node_id (), cpath);
459
460 resolve_visibility (constant.get_visibility ());
461
462 ResolveType::go (constant.get_type ().get ());
463 ResolveExpr::go (constant.get_expr ().get (), path, cpath);
464}
465
466void
467ResolveItem::visit (AST::Function &function)
468{
469 auto decl = CanonicalPath::new_seg (function.get_node_id (),
470 function.get_function_name ());
471 auto path = prefix.append (decl);
472 auto cpath = canonical_prefix.append (decl);
473
474 mappings->insert_canonical_path (function.get_node_id (), cpath);
475
476 resolve_visibility (function.get_visibility ());
477
478 NodeId scope_node_id = function.get_node_id ();
479 resolver->get_name_scope ().push (scope_node_id);
480 resolver->get_type_scope ().push (scope_node_id);
481 resolver->get_label_scope ().push (scope_node_id);
482 resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
483 resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
484 resolver->push_new_label_rib (resolver->get_type_scope ().peek ());
485
486 if (function.has_generics ())
487 for (auto &generic : function.get_generic_params ())
488 ResolveGenericParam::go (generic.get (), prefix, canonical_prefix);
489
490 // resolve any where clause items
491 if (function.has_where_clause ())
492 ResolveWhereClause::Resolve (function.get_where_clause ());
493
494 if (function.has_return_type ())
495 ResolveType::go (function.get_return_type ().get ());
496
497 // we make a new scope so the names of parameters are resolved and shadowed
498 // correctly
499 for (auto &param : function.get_function_params ())
500 {
501 ResolveType::go (param.get_type ().get ());
502 PatternDeclaration::go (param.get_pattern ().get ());
503
504 // the mutability checker needs to verify for immutable decls the number
505 // of assignments are <1. This marks an implicit assignment
506 }
507
508 // resolve the function body
509 ResolveExpr::go (function.get_definition ().get (), path, cpath);
510
511 resolver->get_name_scope ().pop ();
512 resolver->get_type_scope ().pop ();
513 resolver->get_label_scope ().pop ();
514}
515
516void
517ResolveItem::visit (AST::InherentImpl &impl_block)
518{
519 NodeId scope_node_id = impl_block.get_node_id ();
520 resolver->get_name_scope ().push (scope_node_id);
521 resolver->get_type_scope ().push (scope_node_id);
522 resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
523 resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
524
525 resolve_visibility (impl_block.get_visibility ());
526
527 if (impl_block.has_generics ())
528 for (auto &generic : impl_block.get_generic_params ())
529 ResolveGenericParam::go (generic.get (), prefix, canonical_prefix);
530
531 // resolve any where clause items
532 if (impl_block.has_where_clause ())
533 ResolveWhereClause::Resolve (impl_block.get_where_clause ());
534
535 // FIXME this needs to be protected behind nominal type-checks see:
536 // rustc --explain E0118
537 ResolveType::go (impl_block.get_type ().get ());
538
539 // Setup paths
540 CanonicalPath self_cpath = CanonicalPath::create_empty ();
541 bool ok = ResolveTypeToCanonicalPath::go (impl_block.get_type ().get (),
542 self_cpath);
543 rust_assert (ok);
544 rust_debug ("AST::InherentImpl resolve Self: {%s}",
545 self_cpath.get ().c_str ());
546
547 CanonicalPath impl_type = self_cpath;
548 CanonicalPath impl_prefix = prefix.append (impl_type);
549
550 // see https://godbolt.org/z/a3vMbsT6W
551 CanonicalPath cpath = CanonicalPath::create_empty ();
552 if (canonical_prefix.size () <= 1)
553 {
554 cpath = self_cpath;
555 }
556 else
557 {
558 std::string seg_buf = "<impl " + self_cpath.get () + ">";
559 CanonicalPath seg
560 = CanonicalPath::new_seg (impl_block.get_node_id (), seg_buf);
561 cpath = canonical_prefix.append (seg);
562 }
563
564 // done setup paths
565
566 auto Self
567 = CanonicalPath::get_big_self (impl_block.get_type ()->get_node_id ());
568
569 resolver->get_type_scope ().insert (Self,
570 impl_block.get_type ()->get_node_id (),
571 impl_block.get_type ()->get_locus ());
572
573 for (auto &impl_item : impl_block.get_impl_items ())
574 {
575 rust_debug (
576 "AST::InherentImpl resolve_impl_item: impl_prefix={%s} cpath={%s}",
577 impl_prefix.get ().c_str (), cpath.get ().c_str ());
578 resolve_impl_item (impl_item.get (), impl_prefix, cpath);
579 }
580
581 resolver->get_type_scope ().peek ()->clear_name (
582 Self, impl_block.get_type ()->get_node_id ());
583
584 resolver->get_type_scope ().pop ();
585 resolver->get_name_scope ().pop ();
586}
587
588void
589ResolveItem::visit (AST::Method &method)
590{
591 auto decl
592 = CanonicalPath::new_seg (method.get_node_id (), method.get_method_name ());
593 auto path = prefix.append (decl);
594 auto cpath = canonical_prefix.append (decl);
595 mappings->insert_canonical_path (method.get_node_id (), cpath);
596
597 NodeId scope_node_id = method.get_node_id ();
598
599 resolve_visibility (method.get_visibility ());
600
601 resolver->get_name_scope ().push (scope_node_id);
602 resolver->get_type_scope ().push (scope_node_id);
603 resolver->get_label_scope ().push (scope_node_id);
604 resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
605 resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
606 resolver->push_new_label_rib (resolver->get_type_scope ().peek ());
607
608 if (method.has_generics ())
609 for (auto &generic : method.get_generic_params ())
610 ResolveGenericParam::go (generic.get (), prefix, canonical_prefix);
611
612 // resolve any where clause items
613 if (method.has_where_clause ())
614 ResolveWhereClause::Resolve (method.get_where_clause ());
615
616 if (method.has_return_type ())
617 ResolveType::go (method.get_return_type ().get ());
618
619 // self turns into (self: Self) as a function param
620 AST::SelfParam &self_param = method.get_self_param ();
621 AST::IdentifierPattern self_pattern (self_param.get_node_id (), "self",
622 self_param.get_locus (),
623 self_param.get_has_ref (),
624 self_param.get_is_mut (),
625 std::unique_ptr<AST::Pattern> (nullptr));
626
627 std::vector<std::unique_ptr<AST::TypePathSegment>> segments;
628 segments.push_back (std::unique_ptr<AST::TypePathSegment> (
629 new AST::TypePathSegment ("Self", false, self_param.get_locus ())));
630
631 AST::TypePath self_type_path (std::move (segments), self_param.get_locus ());
632
633 ResolveType::go (&self_type_path);
634 PatternDeclaration::go (&self_pattern);
635
636 // we make a new scope so the names of parameters are resolved and shadowed
637 // correctly
638 for (auto &param : method.get_function_params ())
639 {
640 ResolveType::go (param.get_type ().get ());
641 PatternDeclaration::go (param.get_pattern ().get ());
642 }
643
644 // resolve any where clause items
645 if (method.has_where_clause ())
646 ResolveWhereClause::Resolve (method.get_where_clause ());
647
648 // resolve the function body
649 ResolveExpr::go (method.get_definition ().get (), path, cpath);
650
651 resolver->get_name_scope ().pop ();
652 resolver->get_type_scope ().pop ();
653 resolver->get_label_scope ().pop ();
654}
655
656void
657ResolveItem::visit (AST::TraitImpl &impl_block)
658{
659 NodeId scope_node_id = impl_block.get_node_id ();
660
661 resolve_visibility (impl_block.get_visibility ());
662
663 resolver->get_name_scope ().push (scope_node_id);
664 resolver->get_type_scope ().push (scope_node_id);
665 resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
666 resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
667
668 if (impl_block.has_generics ())
669 for (auto &generic : impl_block.get_generic_params ())
670 ResolveGenericParam::go (generic.get (), prefix, canonical_prefix);
671
672 // resolve any where clause items
673 if (impl_block.has_where_clause ())
674 ResolveWhereClause::Resolve (impl_block.get_where_clause ());
675
676 // CanonicalPath canonical_trait_type = CanonicalPath::create_empty ();
677 NodeId trait_resolved_node = ResolveType::go (&impl_block.get_trait_path ());
678 if (trait_resolved_node == UNKNOWN_NODEID)
679 {
680 resolver->get_type_scope ().pop ();
681 resolver->get_name_scope ().pop ();
682 return;
683 }
684
685 // CanonicalPath canonical_impl_type = CanonicalPath::create_empty ();
686 NodeId type_resolved_node = ResolveType::go (impl_block.get_type ().get ());
687 if (type_resolved_node == UNKNOWN_NODEID)
688 {
689 resolver->get_type_scope ().pop ();
690 resolver->get_name_scope ().pop ();
691 return;
692 }
693
694 bool ok;
695 // setup paths
696 CanonicalPath canonical_trait_type = CanonicalPath::create_empty ();
697 ok = ResolveTypeToCanonicalPath::go (&impl_block.get_trait_path (),
698 canonical_trait_type);
699 rust_assert (ok);
700
701 rust_debug ("AST::TraitImpl resolve trait type: {%s}",
702 canonical_trait_type.get ().c_str ());
703
704 CanonicalPath canonical_impl_type = CanonicalPath::create_empty ();
705 ok = ResolveTypeToCanonicalPath::go (impl_block.get_type ().get (),
706 canonical_impl_type);
707 rust_assert (ok);
708
709 rust_debug ("AST::TraitImpl resolve self: {%s}",
710 canonical_impl_type.get ().c_str ());
711
712 // raw paths
713 CanonicalPath impl_type_seg = canonical_impl_type;
714 CanonicalPath trait_type_seg = canonical_trait_type;
715 CanonicalPath projection
716 = CanonicalPath::trait_impl_projection_seg (impl_block.get_node_id (),
717 trait_type_seg, impl_type_seg);
718 CanonicalPath impl_prefix = prefix.append (projection);
719
720 // setup canonical-path
721 CanonicalPath canonical_projection
722 = CanonicalPath::trait_impl_projection_seg (impl_block.get_node_id (),
723 canonical_trait_type,
724 canonical_impl_type);
725 CanonicalPath cpath = CanonicalPath::create_empty ();
726 if (canonical_prefix.size () <= 1)
727 {
728 cpath = canonical_projection;
729 }
730 else
731 {
732 std::string projection_str = canonical_projection.get ();
733 std::string seg_buf
734 = "<impl " + projection_str.substr (1, projection_str.size () - 2)
735 + ">";
736 CanonicalPath seg
737 = CanonicalPath::new_seg (impl_block.get_node_id (), seg_buf);
738 cpath = canonical_prefix.append (seg);
739 }
740
741 // DONE setup canonical-path
742
743 auto Self
744 = CanonicalPath::get_big_self (impl_block.get_type ()->get_node_id ());
745
746 resolver->get_type_scope ().insert (Self,
747 impl_block.get_type ()->get_node_id (),
748 impl_block.get_type ()->get_locus ());
749
750 for (auto &impl_item : impl_block.get_impl_items ())
751 {
752 rust_debug (
753 "AST::TraitImpl resolve_impl_item: impl_prefix={%s} cpath={%s}",
754 impl_prefix.get ().c_str (), cpath.get ().c_str ());
755 resolve_impl_item (impl_item.get (), impl_prefix, cpath);
756 }
757
758 resolver->get_type_scope ().peek ()->clear_name (
759 Self, impl_block.get_type ()->get_node_id ());
760 resolver->get_type_scope ().pop ();
761}
762
763void
764ResolveItem::visit (AST::Trait &trait)
765{
766 NodeId scope_node_id = trait.get_node_id ();
767
768 resolve_visibility (trait.get_visibility ());
769
770 resolver->get_name_scope ().push (scope_node_id);
771 resolver->get_type_scope ().push (scope_node_id);
772 resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
773 resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
774
775 // we need to inject an implicit self TypeParam here
776 AST::TypeParam *implicit_self
777 = new AST::TypeParam ("Self", trait.get_locus ());
778 trait.insert_implict_self (
779 std::unique_ptr<AST::GenericParam> (implicit_self));
780 CanonicalPath Self = CanonicalPath::get_big_self (trait.get_node_id ());
781
782 for (auto &generic : trait.get_generic_params ())
783 ResolveGenericParam::go (generic.get (), prefix, canonical_prefix);
784
785 // Self is an implicit TypeParam so lets mark it as such
786 resolver->get_type_scope ().append_reference_for_def (
787 Self.get_node_id (), implicit_self->get_node_id ());
788
789 if (trait.has_type_param_bounds ())
790 {
791 for (auto &bound : trait.get_type_param_bounds ())
792 {
793 ResolveTypeBound::go (bound.get ());
794 }
795 }
796
797 // resolve any where clause items
798 if (trait.has_where_clause ())
799 ResolveWhereClause::Resolve (trait.get_where_clause ());
800
801 // resolve the paths
802 CanonicalPath path = CanonicalPath::create_empty ();
803 CanonicalPath cpath = CanonicalPath::create_empty ();
804 //
805
806 for (auto &item : trait.get_trait_items ())
807 {
808 ResolveTraitItems::go (item.get (), path, cpath);
809 }
810
811 resolver->get_type_scope ().pop ();
812 resolver->get_name_scope ().pop ();
813}
814
815void
816ResolveItem::visit (AST::ExternBlock &extern_block)
817{
818 resolve_visibility (extern_block.get_visibility ());
819
820 for (auto &item : extern_block.get_extern_items ())
821 {
822 resolve_extern_item (item.get ());
823 }
824}
825
826void
827ResolveItem::resolve_impl_item (AST::TraitImplItem *item,
828 const CanonicalPath &prefix,
829 const CanonicalPath &canonical_prefix)
830{
831 ResolveImplItems::go (item, prefix, canonical_prefix);
832}
833
834void
835ResolveItem::resolve_impl_item (AST::InherentImplItem *item,
836 const CanonicalPath &prefix,
837 const CanonicalPath &canonical_prefix)
838{
839 ResolveImplItems::go (item, prefix, canonical_prefix);
840}
841
842void
843ResolveItem::resolve_extern_item (AST::ExternalItem *item)
844{
845 ResolveExternItem::go (item, prefix, canonical_prefix);
846}
847
848static void
849flatten_glob (const AST::UseTreeGlob &glob,
850 std::vector<AST::SimplePath> &paths);
851static void
852flatten_rebind (const AST::UseTreeRebind &glob,
853 std::vector<AST::SimplePath> &paths);
854static void
855flatten_list (const AST::UseTreeList &glob,
856 std::vector<AST::SimplePath> &paths);
857
858static void
859flatten (const AST::UseTree *tree, std::vector<AST::SimplePath> &paths)
860{
861 switch (tree->get_kind ())
862 {
863 case AST::UseTree::Glob: {
864 auto glob = static_cast<const AST::UseTreeGlob *> (tree);
865 flatten_glob (*glob, paths);
866 break;
867 }
868 case AST::UseTree::Rebind: {
869 auto rebind = static_cast<const AST::UseTreeRebind *> (tree);
870 flatten_rebind (*rebind, paths);
871 break;
872 }
873 case AST::UseTree::List: {
874 auto list = static_cast<const AST::UseTreeList *> (tree);
875 flatten_list (*list, paths);
876 break;
877 }
878 break;
879 }
880}
881
882static void
883flatten_glob (const AST::UseTreeGlob &glob, std::vector<AST::SimplePath> &paths)
884{
885 if (glob.has_path ())
886 paths.emplace_back (glob.get_path ());
887}
888
889static void
890flatten_rebind (const AST::UseTreeRebind &rebind,
891 std::vector<AST::SimplePath> &paths)
892{
893 auto path = rebind.get_path ();
894 if (rebind.has_path ())
895 paths.emplace_back (path);
896
897 // FIXME: Do we want to emplace the rebind here as well?
898 if (rebind.has_identifier ())
899 {
900 auto rebind_path = path;
901 auto new_seg = rebind.get_identifier ();
902
903 // Add the identifier as a new path
904 rebind_path.get_segments ().back ()
905 = AST::SimplePathSegment (new_seg, Location ());
906
907 paths.emplace_back (rebind_path);
908 }
909}
910
911static void
912flatten_list (const AST::UseTreeList &list, std::vector<AST::SimplePath> &paths)
913{
914 auto prefix = AST::SimplePath::create_empty ();
915 if (list.has_path ())
916 prefix = list.get_path ();
917
918 for (const auto &tree : list.get_trees ())
919 {
920 auto sub_paths = std::vector<AST::SimplePath> ();
921 flatten (tree.get (), sub_paths);
922
923 for (auto &sub_path : sub_paths)
924 {
925 auto new_path = prefix;
926 std::copy (sub_path.get_segments ().begin (),
927 sub_path.get_segments ().end (),
928 std::back_inserter (new_path.get_segments ()));
929
930 paths.emplace_back (new_path);
931 }
932 }
933}
934
935/**
936 * Flatten a UseDeclaration's UseTree into multiple simple paths to resolve.
937 *
938 * Given the following use declarations:
939 * ```
940 * use some::path::to_resolve; #1
941 * use some::path::to_glob::*; #2
942 * use some::path::{one, two}; #2
943 * ```
944 *
945 * In the first case, we simply want to return a vector with a single
946 * SimplePath:
947 * [some::path::to_resolve]
948 *
949 * In the second case, we want to resolve the glob's "origin path":
950 * [some::path::to_glob]
951 *
952 * Finally in the third case, we want to create two SimplePaths to resolve:
953 * [some::path::one, some::path::two]
954 */
955static std::vector<AST::SimplePath>
956flatten_use_dec_to_paths (const AST::UseDeclaration &use_item)
957{
958 auto paths = std::vector<AST::SimplePath> ();
959
960 const auto &tree = use_item.get_tree ();
961 flatten (tree.get (), paths);
962
963 return paths;
964}
965
966void
967ResolveItem::visit (AST::UseDeclaration &use_item)
968{
969 auto to_resolve = flatten_use_dec_to_paths (use_item);
970
971 for (auto &path : to_resolve)
972 ResolvePath::go (&path);
973}
974
975ResolveImplItems::ResolveImplItems (const CanonicalPath &prefix,
976 const CanonicalPath &canonical_prefix)
977 : ResolveItem (prefix, canonical_prefix)
978{}
979
980void
981ResolveImplItems::go (AST::InherentImplItem *item, const CanonicalPath &prefix,
982 const CanonicalPath &canonical_prefix)
983{
984 if (item->is_marked_for_strip ())
985 return;
986
987 ResolveImplItems resolver (prefix, canonical_prefix);
988 item->accept_vis (resolver);
989}
990
991void
992ResolveImplItems::go (AST::TraitImplItem *item, const CanonicalPath &prefix,
993 const CanonicalPath &canonical_prefix)
994{
995 if (item->is_marked_for_strip ())
996 return;
997
998 ResolveImplItems resolver (prefix, canonical_prefix);
999 item->accept_vis (resolver);
1000}
1001
1002void
1003ResolveImplItems::visit (AST::TypeAlias &alias)
1004{
1005 ResolveItem::visit (alias);
1006
1007 resolve_visibility (alias.get_visibility ());
1008
1009 // FIXME this stops the erronious unused decls which will be fixed later on
1010 resolver->get_type_scope ().append_reference_for_def (alias.get_node_id (),
1011 alias.get_node_id ());
1012}
1013
1014void
1015ResolveExternItem::go (AST::ExternalItem *item, const CanonicalPath &prefix,
1016 const CanonicalPath &canonical_prefix)
1017{
1018 ResolveExternItem resolver (prefix, canonical_prefix);
1019 item->accept_vis (resolver);
1020}
1021
1022void
1023ResolveExternItem::visit (AST::ExternalFunctionItem &function)
1024{
1025 NodeId scope_node_id = function.get_node_id ();
1026 auto decl = CanonicalPath::new_seg (function.get_node_id (),
1027 function.get_identifier ());
1028 auto path = prefix.append (decl);
1029 auto cpath = canonical_prefix.append (decl);
1030
1031 mappings->insert_canonical_path (function.get_node_id (), cpath);
1032
1033 resolve_visibility (function.get_visibility ());
1034
1035 resolver->get_name_scope ().push (scope_node_id);
1036 resolver->get_type_scope ().push (scope_node_id);
1037 resolver->get_label_scope ().push (scope_node_id);
1038 resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
1039 resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
1040 resolver->push_new_label_rib (resolver->get_type_scope ().peek ());
1041
1042 // resolve the generics
1043 if (function.has_generics ())
1044 for (auto &generic : function.get_generic_params ())
1045 ResolveGenericParam::go (generic.get (), prefix, canonical_prefix);
1046
1047 if (function.has_return_type ())
1048 ResolveType::go (function.get_return_type ().get ());
1049
1050 // we make a new scope so the names of parameters are resolved and shadowed
1051 // correctly
1052 for (auto &param : function.get_function_params ())
1053 {
1054 ResolveType::go (param.get_type ().get ());
1055 }
1056
1057 // done
1058 resolver->get_name_scope ().pop ();
1059 resolver->get_type_scope ().pop ();
1060 resolver->get_label_scope ().pop ();
1061}
1062
1063void
1064ResolveExternItem::visit (AST::ExternalStaticItem &item)
1065{
1066 resolve_visibility (item.get_visibility ());
1067
1068 ResolveType::go (item.get_type ().get ());
1069}
1070
1071} // namespace Resolver
1072} // namespace Rust
1073
1074#if CHECKING_P
1075
1076namespace selftest {
1077
1078static void
1079rust_flatten_nested_glob (void)
1080{
1081 auto foo = Rust::AST::SimplePathSegment ("foo", Location ());
1082 auto bar = Rust::AST::SimplePathSegment ("bar", Location ());
1083 auto foobar = Rust::AST::SimplePath ({foo, bar});
1084
1085 auto glob
1086 = Rust::AST::UseTreeGlob (Rust::AST::UseTreeGlob::PathType::PATH_PREFIXED,
1087 foobar, Location ());
1088
1089 auto paths = std::vector<Rust::AST::SimplePath> ();
1090 Rust::Resolver::flatten_glob (glob, paths);
1091
1092 ASSERT_TRUE (!paths.empty ());
1093 ASSERT_EQ (paths.size (), 1);
1094 ASSERT_EQ (paths[0].get_segments ()[0].as_string (), "foo");
1095 ASSERT_EQ (paths[0].get_segments ()[1].as_string (), "bar");
1096}
1097
1098static void
1099rust_flatten_glob (void)
1100{
1101 auto frob = Rust::AST::SimplePath::from_str ("frobulator", Location ());
1102
1103 auto glob
1104 = Rust::AST::UseTreeGlob (Rust::AST::UseTreeGlob::PathType::PATH_PREFIXED,
1105 frob, Location ());
1106
1107 auto paths = std::vector<Rust::AST::SimplePath> ();
1108 Rust::Resolver::flatten_glob (glob, paths);
1109
1110 ASSERT_TRUE (!paths.empty ());
1111 ASSERT_EQ (paths.size (), 1);
1112 ASSERT_EQ (paths[0], "frobulator");
1113}
1114
1115static void
1116rust_flatten_rebind_none (void)
1117{
1118 auto foo = Rust::AST::SimplePathSegment ("foo", Location ());
1119 auto bar = Rust::AST::SimplePathSegment ("bar", Location ());
1120 auto foobar = Rust::AST::SimplePath ({foo, bar});
1121
1122 auto rebind = Rust::AST::UseTreeRebind (Rust::AST::UseTreeRebind::NONE,
1123 foobar, Location ());
1124
1125 auto paths = std::vector<Rust::AST::SimplePath> ();
1126 Rust::Resolver::flatten_rebind (rebind, paths);
1127
1128 ASSERT_TRUE (!paths.empty ());
1129 ASSERT_EQ (paths.size (), 1);
1130 ASSERT_EQ (paths[0].get_segments ()[0].as_string (), "foo");
1131 ASSERT_EQ (paths[0].get_segments ()[1].as_string (), "bar");
1132}
1133
1134static void
1135rust_flatten_rebind (void)
1136{
1137 auto frob = Rust::AST::SimplePath::from_str ("frobulator", Location ());
1138
1139 auto rebind = Rust::AST::UseTreeRebind (Rust::AST::UseTreeRebind::IDENTIFIER,
1140 frob, Location (), "saindoux");
1141
1142 auto paths = std::vector<Rust::AST::SimplePath> ();
1143 Rust::Resolver::flatten_rebind (rebind, paths);
1144
1145 ASSERT_TRUE (!paths.empty ());
1146 ASSERT_EQ (paths.size (), 2);
1147 ASSERT_EQ (paths[0], "frobulator");
1148 ASSERT_EQ (paths[1], "saindoux");
1149}
1150
1151static void
1152rust_flatten_rebind_nested (void)
1153{
1154 auto foo = Rust::AST::SimplePathSegment ("foo", Location ());
1155 auto bar = Rust::AST::SimplePathSegment ("bar", Location ());
1156 auto baz = Rust::AST::SimplePathSegment ("baz", Location ());
1157
1158 auto foo_bar_baz = Rust::AST::SimplePath ({foo, bar, baz});
1159
1160 auto rebind = Rust::AST::UseTreeRebind (Rust::AST::UseTreeRebind::IDENTIFIER,
1161 foo_bar_baz, Location (), "saindoux");
1162
1163 auto paths = std::vector<Rust::AST::SimplePath> ();
1164 Rust::Resolver::flatten_rebind (rebind, paths);
1165
1166 ASSERT_TRUE (!paths.empty ());
1167 ASSERT_EQ (paths.size (), 2);
1168 ASSERT_EQ (paths[0].get_segments ()[0].as_string (), "foo");
1169 ASSERT_EQ (paths[0].get_segments ()[1].as_string (), "bar");
1170 ASSERT_EQ (paths[0].get_segments ()[2].as_string (), "baz");
1171 ASSERT_EQ (paths[1].get_segments ()[0].as_string (), "foo");
1172 ASSERT_EQ (paths[1].get_segments ()[1].as_string (), "bar");
1173 ASSERT_EQ (paths[1].get_segments ()[2].as_string (), "saindoux");
1174}
1175
1176static void
1177rust_flatten_list (void)
1178{
1179 auto foo = Rust::AST::SimplePathSegment ("foo", Location ());
1180 auto bar = Rust::AST::SimplePathSegment ("bar", Location ());
1181 auto foo_bar = Rust::AST::SimplePath ({foo, bar});
1182
1183 auto baz = Rust::AST::SimplePath::from_str ("baz", Location ());
1184 auto bul = Rust::AST::SimplePath::from_str ("bul", Location ());
1185
1186 // use foo::bar::{baz, bul};
1187
1188 auto use0 = std::unique_ptr<Rust::AST::UseTree> (
1189 new Rust::AST::UseTreeRebind (Rust::AST::UseTreeRebind::NONE, baz,
1190 Location ()));
1191 auto use1 = std::unique_ptr<Rust::AST::UseTree> (
1192 new Rust::AST::UseTreeRebind (Rust::AST::UseTreeRebind::NONE, bul,
1193 Location ()));
1194
1195 auto uses = std::vector<std::unique_ptr<Rust::AST::UseTree>> ();
1196 uses.emplace_back (std::move (use0));
1197 uses.emplace_back (std::move (use1));
1198
1199 auto list = Rust::AST::UseTreeList (Rust::AST::UseTreeList::PATH_PREFIXED,
1200 foo_bar, std::move (uses), Location ());
1201
1202 auto paths = std::vector<Rust::AST::SimplePath> ();
1203 Rust::Resolver::flatten_list (list, paths);
1204
85a8fe00
PH
1205 ASSERT_TRUE (!paths.empty ());
1206 ASSERT_EQ (paths.size (), 2);
1207 ASSERT_EQ (paths[0].get_segments ()[0].as_string (), "foo");
1208 ASSERT_EQ (paths[0].get_segments ()[1].as_string (), "bar");
1209 ASSERT_EQ (paths[0].get_segments ()[2].as_string (), "baz");
1210 ASSERT_EQ (paths[1].get_segments ()[0].as_string (), "foo");
1211 ASSERT_EQ (paths[1].get_segments ()[1].as_string (), "bar");
1212 ASSERT_EQ (paths[1].get_segments ()[2].as_string (), "bul");
1213}
1214
1215static void
1216rust_use_dec_flattening (void)
1217{
1218 rust_flatten_glob ();
1219 rust_flatten_nested_glob ();
1220 rust_flatten_rebind_none ();
1221 rust_flatten_rebind ();
1222 rust_flatten_rebind_nested ();
1223 rust_flatten_list ();
1224}
1225
1226void
1227rust_simple_path_resolve_test (void)
1228{
1229 rust_use_dec_flattening ();
1230}
1231
1232} // namespace selftest
1233
1234#endif // CHECKING_P