gccrs: Remove obsolete classes and functions.
[official-gcc.git] / gcc / rust / resolve / rust-ast-resolve-item.cc
blobe69b945407cfcdf55ba39eafa240827b799ed350
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
8 // version.
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.
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-item.h"
20 #include "rust-ast-full-decls.h"
21 #include "rust-ast-resolve-toplevel.h"
22 #include "rust-ast-resolve-type.h"
23 #include "rust-ast-resolve-pattern.h"
24 #include "rust-ast-resolve-path.h"
26 #include "rust-item.h"
27 #include "selftest.h"
29 namespace Rust {
30 namespace Resolver {
32 ResolveTraitItems::ResolveTraitItems (const CanonicalPath &prefix,
33 const CanonicalPath &canonical_prefix)
34 : ResolverBase (), prefix (prefix), canonical_prefix (canonical_prefix)
37 void
38 ResolveTraitItems::go (AST::AssociatedItem *item, const CanonicalPath &prefix,
39 const CanonicalPath &canonical_prefix)
41 if (item->is_marked_for_strip ())
42 return;
44 ResolveTraitItems resolver (prefix, canonical_prefix);
45 item->accept_vis (resolver);
48 void
49 ResolveTraitItems::visit (AST::Function &function)
51 auto decl
52 = CanonicalPath::new_seg (function.get_node_id (),
53 function.get_function_name ().as_string ());
54 auto path = prefix.append (decl);
55 auto cpath = canonical_prefix.append (decl);
56 mappings->insert_canonical_path (function.get_node_id (), cpath);
58 NodeId scope_node_id = function.get_node_id ();
59 resolver->get_name_scope ().push (scope_node_id);
60 resolver->get_type_scope ().push (scope_node_id);
61 resolver->get_label_scope ().push (scope_node_id);
62 resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
63 resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
64 resolver->push_new_label_rib (resolver->get_type_scope ().peek ());
66 if (function.has_generics ())
67 for (auto &generic : function.get_generic_params ())
68 ResolveGenericParam::go (generic.get (), prefix, canonical_prefix);
70 if (function.has_return_type ())
71 ResolveType::go (function.get_return_type ().get ());
73 // self turns into (self: Self) as a function param
74 std::vector<PatternBinding> bindings
75 = {PatternBinding (PatternBoundCtx::Product, std::set<Identifier> ())};
77 // we make a new scope so the names of parameters are resolved and shadowed
78 // correctly
79 for (auto &p : function.get_function_params ())
81 if (p->is_variadic ())
83 auto param = static_cast<AST::VariadicParam *> (p.get ());
84 PatternDeclaration::go (param->get_pattern ().get (),
85 Rib::ItemType::Param, bindings);
87 else if (p->is_self ())
89 auto param = static_cast<AST::SelfParam *> (p.get ());
90 // FIXME: which location should be used for Rust::Identifier `self`?
91 AST::IdentifierPattern self_pattern (
92 param->get_node_id (), {"self"}, param->get_locus (),
93 param->get_has_ref (), param->get_is_mut (),
94 std::unique_ptr<AST::Pattern> (nullptr));
96 PatternDeclaration::go (&self_pattern, Rib::ItemType::Param);
98 if (param->has_type ())
100 // This shouldn't happen the parser should already error for this
101 rust_assert (!param->get_has_ref ());
102 ResolveType::go (param->get_type ().get ());
104 else
106 // here we implicitly make self have a type path of Self
107 std::vector<std::unique_ptr<AST::TypePathSegment>> segments;
108 segments.push_back (std::unique_ptr<AST::TypePathSegment> (
109 new AST::TypePathSegment ("Self", false, param->get_locus ())));
111 AST::TypePath self_type_path (std::move (segments),
112 param->get_locus ());
113 ResolveType::go (&self_type_path);
116 else
118 auto param = static_cast<AST::FunctionParam *> (p.get ());
119 ResolveType::go (param->get_type ().get ());
120 PatternDeclaration::go (param->get_pattern ().get (),
121 Rib::ItemType::Param, bindings);
125 if (function.has_where_clause ())
126 ResolveWhereClause::Resolve (function.get_where_clause ());
128 // trait items have an optional body
129 if (function.has_body ())
130 ResolveExpr::go (function.get_definition ()->get (), path, cpath);
132 resolver->get_name_scope ().pop ();
133 resolver->get_type_scope ().pop ();
134 resolver->get_label_scope ().pop ();
136 void
137 ResolveTraitItems::visit (AST::TraitItemType &type)
139 auto decl = CanonicalPath::new_seg (type.get_node_id (),
140 type.get_identifier ().as_string ());
141 auto path = prefix.append (decl);
142 auto cpath = canonical_prefix.append (decl);
143 mappings->insert_canonical_path (type.get_node_id (), cpath);
145 for (auto &bound : type.get_type_param_bounds ())
146 ResolveTypeBound::go (bound.get ());
149 void
150 ResolveTraitItems::visit (AST::TraitItemConst &constant)
152 auto decl = CanonicalPath::new_seg (constant.get_node_id (),
153 constant.get_identifier ().as_string ());
154 auto path = prefix.append (decl);
155 auto cpath = canonical_prefix.append (decl);
156 mappings->insert_canonical_path (constant.get_node_id (), cpath);
158 ResolveType::go (constant.get_type ().get ());
160 if (constant.has_expr ())
161 ResolveExpr::go (constant.get_expr ().get (), path, cpath);
164 ResolveItem::ResolveItem (const CanonicalPath &prefix,
165 const CanonicalPath &canonical_prefix)
166 : ResolverBase (), prefix (prefix), canonical_prefix (canonical_prefix)
169 void
170 ResolveItem::go (AST::Item *item, const CanonicalPath &prefix,
171 const CanonicalPath &canonical_prefix)
173 ResolveItem resolver (prefix, canonical_prefix);
174 item->accept_vis (resolver);
177 void
178 ResolveItem::visit (AST::TypeAlias &alias)
180 auto talias
181 = CanonicalPath::new_seg (alias.get_node_id (),
182 alias.get_new_type_name ().as_string ());
183 auto path = prefix.append (talias);
184 auto cpath = canonical_prefix.append (talias);
185 mappings->insert_canonical_path (alias.get_node_id (), cpath);
187 NodeId scope_node_id = alias.get_node_id ();
188 resolver->get_type_scope ().push (scope_node_id);
190 if (alias.has_generics ())
191 for (auto &generic : alias.get_generic_params ())
192 ResolveGenericParam::go (generic.get (), prefix, canonical_prefix);
194 if (alias.has_where_clause ())
195 ResolveWhereClause::Resolve (alias.get_where_clause ());
197 ResolveType::go (alias.get_type_aliased ().get ());
199 resolver->get_type_scope ().pop ();
202 void
203 ResolveItem::visit (AST::Module &module)
205 auto mod = CanonicalPath::new_seg (module.get_node_id (),
206 module.get_name ().as_string ());
207 auto path = prefix.append (mod);
208 auto cpath = canonical_prefix.append (mod);
209 mappings->insert_canonical_path (module.get_node_id (), cpath);
211 resolve_visibility (module.get_visibility ());
213 NodeId scope_node_id = module.get_node_id ();
214 resolver->get_name_scope ().push (scope_node_id);
215 resolver->get_type_scope ().push (scope_node_id);
216 resolver->get_label_scope ().push (scope_node_id);
217 resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
218 resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
219 resolver->push_new_label_rib (resolver->get_type_scope ().peek ());
221 // FIXME: Should we reinsert a child here? Any reason we ResolveTopLevel::go
222 // in ResolveTopLevel::visit (AST::Module) as well as here?
223 for (auto &item : module.get_items ())
224 ResolveTopLevel::go (item.get (), CanonicalPath::create_empty (), cpath);
226 resolver->push_new_module_scope (module.get_node_id ());
227 for (auto &item : module.get_items ())
228 ResolveItem::go (item.get (), path, cpath);
230 resolver->pop_module_scope ();
232 resolver->get_name_scope ().pop ();
233 resolver->get_type_scope ().pop ();
234 resolver->get_label_scope ().pop ();
237 void
238 ResolveItem::visit (AST::TupleStruct &struct_decl)
240 auto decl
241 = CanonicalPath::new_seg (struct_decl.get_node_id (),
242 struct_decl.get_identifier ().as_string ());
243 auto path = prefix.append (decl);
244 auto cpath = canonical_prefix.append (decl);
245 mappings->insert_canonical_path (struct_decl.get_node_id (), cpath);
247 resolve_visibility (struct_decl.get_visibility ());
249 NodeId scope_node_id = struct_decl.get_node_id ();
250 resolver->get_type_scope ().push (scope_node_id);
252 if (struct_decl.has_generics ())
253 for (auto &generic : struct_decl.get_generic_params ())
254 ResolveGenericParam::go (generic.get (), prefix, canonical_prefix);
256 if (struct_decl.has_where_clause ())
257 ResolveWhereClause::Resolve (struct_decl.get_where_clause ());
259 for (AST::TupleField &field : struct_decl.get_fields ())
261 if (field.get_field_type ()->is_marked_for_strip ())
262 continue;
264 resolve_visibility (field.get_visibility ());
266 ResolveType::go (field.get_field_type ().get ());
269 resolver->get_type_scope ().pop ();
272 void
273 ResolveItem::visit (AST::Enum &enum_decl)
275 auto decl = CanonicalPath::new_seg (enum_decl.get_node_id (),
276 enum_decl.get_identifier ().as_string ());
277 auto path = prefix.append (decl);
278 auto cpath = canonical_prefix.append (decl);
279 mappings->insert_canonical_path (enum_decl.get_node_id (), cpath);
281 resolve_visibility (enum_decl.get_visibility ());
283 NodeId scope_node_id = enum_decl.get_node_id ();
284 resolver->get_type_scope ().push (scope_node_id);
286 if (enum_decl.has_generics ())
287 for (auto &generic : enum_decl.get_generic_params ())
288 ResolveGenericParam::go (generic.get (), prefix, cpath);
290 if (enum_decl.has_where_clause ())
291 ResolveWhereClause::Resolve (enum_decl.get_where_clause ());
293 /* The actual fields are inside the variants. */
294 for (auto &variant : enum_decl.get_variants ())
295 ResolveItem::go (variant.get (), path, cpath);
297 resolver->get_type_scope ().pop ();
300 /* EnumItem doesn't need to be handled, no fields. */
301 void
302 ResolveItem::visit (AST::EnumItem &item)
304 // Since at this point we cannot have visibilities on enum items anymore, we
305 // can skip handling them
307 auto decl = CanonicalPath::new_seg (item.get_node_id (),
308 item.get_identifier ().as_string ());
309 auto path = prefix.append (decl);
310 auto cpath = canonical_prefix.append (decl);
311 mappings->insert_canonical_path (item.get_node_id (), cpath);
314 void
315 ResolveItem::visit (AST::EnumItemTuple &item)
317 auto decl = CanonicalPath::new_seg (item.get_node_id (),
318 item.get_identifier ().as_string ());
319 auto path = prefix.append (decl);
320 auto cpath = canonical_prefix.append (decl);
321 mappings->insert_canonical_path (item.get_node_id (), cpath);
323 for (auto &field : item.get_tuple_fields ())
325 if (field.get_field_type ()->is_marked_for_strip ())
326 continue;
328 ResolveType::go (field.get_field_type ().get ());
332 void
333 ResolveItem::visit (AST::EnumItemStruct &item)
335 auto decl = CanonicalPath::new_seg (item.get_node_id (),
336 item.get_identifier ().as_string ());
337 auto path = prefix.append (decl);
338 auto cpath = canonical_prefix.append (decl);
339 mappings->insert_canonical_path (item.get_node_id (), cpath);
341 for (auto &field : item.get_struct_fields ())
343 if (field.get_field_type ()->is_marked_for_strip ())
344 continue;
346 ResolveType::go (field.get_field_type ().get ());
350 void
351 ResolveItem::visit (AST::EnumItemDiscriminant &item)
353 auto decl = CanonicalPath::new_seg (item.get_node_id (),
354 item.get_identifier ().as_string ());
355 auto path = prefix.append (decl);
356 auto cpath = canonical_prefix.append (decl);
358 mappings->insert_canonical_path (item.get_node_id (), cpath);
361 void
362 ResolveItem::visit (AST::StructStruct &struct_decl)
364 auto decl
365 = CanonicalPath::new_seg (struct_decl.get_node_id (),
366 struct_decl.get_identifier ().as_string ());
367 auto path = prefix.append (decl);
368 auto cpath = canonical_prefix.append (decl);
369 mappings->insert_canonical_path (struct_decl.get_node_id (), cpath);
371 resolve_visibility (struct_decl.get_visibility ());
373 NodeId scope_node_id = struct_decl.get_node_id ();
374 resolver->get_type_scope ().push (scope_node_id);
376 if (struct_decl.has_generics ())
377 for (auto &generic : struct_decl.get_generic_params ())
378 ResolveGenericParam::go (generic.get (), prefix, canonical_prefix);
380 if (struct_decl.has_where_clause ())
381 ResolveWhereClause::Resolve (struct_decl.get_where_clause ());
383 for (AST::StructField &field : struct_decl.get_fields ())
385 if (field.get_field_type ()->is_marked_for_strip ())
386 continue;
388 resolve_visibility (field.get_visibility ());
390 ResolveType::go (field.get_field_type ().get ());
393 resolver->get_type_scope ().pop ();
396 void
397 ResolveItem::visit (AST::Union &union_decl)
399 auto decl
400 = CanonicalPath::new_seg (union_decl.get_node_id (),
401 union_decl.get_identifier ().as_string ());
402 auto path = prefix.append (decl);
403 auto cpath = canonical_prefix.append (decl);
404 mappings->insert_canonical_path (union_decl.get_node_id (), cpath);
406 resolve_visibility (union_decl.get_visibility ());
408 NodeId scope_node_id = union_decl.get_node_id ();
409 resolver->get_type_scope ().push (scope_node_id);
411 if (union_decl.has_generics ())
412 for (auto &generic : union_decl.get_generic_params ())
413 ResolveGenericParam::go (generic.get (), prefix, canonical_prefix);
415 if (union_decl.has_where_clause ())
416 ResolveWhereClause::Resolve (union_decl.get_where_clause ());
418 for (AST::StructField &field : union_decl.get_variants ())
420 if (field.get_field_type ()->is_marked_for_strip ())
421 continue;
423 ResolveType::go (field.get_field_type ().get ());
426 resolver->get_type_scope ().pop ();
429 void
430 ResolveItem::visit (AST::StaticItem &var)
432 auto decl = CanonicalPath::new_seg (var.get_node_id (),
433 var.get_identifier ().as_string ());
434 auto path = prefix.append (decl);
435 auto cpath = canonical_prefix.append (decl);
436 mappings->insert_canonical_path (var.get_node_id (), cpath);
438 ResolveType::go (var.get_type ().get ());
439 ResolveExpr::go (var.get_expr ().get (), path, cpath);
442 void
443 ResolveItem::visit (AST::ConstantItem &constant)
445 auto decl = CanonicalPath::new_seg (constant.get_node_id (),
446 constant.get_identifier ());
447 auto path = prefix.append (decl);
448 auto cpath = canonical_prefix.append (decl);
449 mappings->insert_canonical_path (constant.get_node_id (), cpath);
451 resolve_visibility (constant.get_visibility ());
453 ResolveType::go (constant.get_type ().get ());
454 ResolveExpr::go (constant.get_expr ().get (), path, cpath);
457 void
458 ResolveItem::visit (AST::Function &function)
460 auto decl
461 = CanonicalPath::new_seg (function.get_node_id (),
462 function.get_function_name ().as_string ());
463 auto path = prefix.append (decl);
464 auto cpath = canonical_prefix.append (decl);
466 mappings->insert_canonical_path (function.get_node_id (), cpath);
468 resolve_visibility (function.get_visibility ());
470 NodeId scope_node_id = function.get_node_id ();
471 resolver->get_name_scope ().push (scope_node_id);
472 resolver->get_type_scope ().push (scope_node_id);
473 resolver->get_label_scope ().push (scope_node_id);
474 resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
475 resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
476 resolver->push_new_label_rib (resolver->get_type_scope ().peek ());
478 if (function.has_generics ())
479 for (auto &generic : function.get_generic_params ())
480 ResolveGenericParam::go (generic.get (), prefix, canonical_prefix);
482 // resolve any where clause items
483 if (function.has_where_clause ())
484 ResolveWhereClause::Resolve (function.get_where_clause ());
486 if (function.has_return_type ())
487 ResolveType::go (function.get_return_type ().get ());
489 if (function.has_self_param ())
491 // self turns into (self: Self) as a function param
492 std::unique_ptr<AST::Param> &s_param = function.get_self_param ();
493 auto self_param = static_cast<AST::SelfParam *> (s_param.get ());
495 // FIXME: which location should be used for Rust::Identifier `self`?
496 AST::IdentifierPattern self_pattern (
497 self_param->get_node_id (), {"self"}, self_param->get_locus (),
498 self_param->get_has_ref (), self_param->get_is_mut (),
499 std::unique_ptr<AST::Pattern> (nullptr));
500 PatternDeclaration::go (&self_pattern, Rib::ItemType::Param);
502 if (self_param->has_type ())
504 // This shouldn't happen the parser should already error for this
505 rust_assert (!self_param->get_has_ref ());
506 ResolveType::go (self_param->get_type ().get ());
508 else
510 // here we implicitly make self have a type path of Self
511 std::vector<std::unique_ptr<AST::TypePathSegment>> segments;
512 segments.push_back (std::unique_ptr<AST::TypePathSegment> (
513 new AST::TypePathSegment ("Self", false,
514 self_param->get_locus ())));
516 AST::TypePath self_type_path (std::move (segments),
517 self_param->get_locus ());
518 ResolveType::go (&self_type_path);
522 std::vector<PatternBinding> bindings
523 = {PatternBinding (PatternBoundCtx::Product, std::set<Identifier> ())};
525 // we make a new scope so the names of parameters are resolved and shadowed
526 // correctly
527 for (auto &p : function.get_function_params ())
529 if (p->is_variadic ())
531 auto param = static_cast<AST::VariadicParam *> (p.get ());
532 if (param->has_pattern ())
533 PatternDeclaration::go (param->get_pattern ().get (),
534 Rib::ItemType::Param, bindings);
536 else if (p->is_self ())
538 auto param = static_cast<AST::SelfParam *> (p.get ());
539 if (param->has_type ())
540 ResolveType::go (param->get_type ().get ());
542 else
544 auto param = static_cast<AST::FunctionParam *> (p.get ());
545 ResolveType::go (param->get_type ().get ());
546 PatternDeclaration::go (param->get_pattern ().get (),
547 Rib::ItemType::Param, bindings);
551 // resolve the function body
552 ResolveExpr::go (function.get_definition ()->get (), path, cpath);
554 resolver->get_name_scope ().pop ();
555 resolver->get_type_scope ().pop ();
556 resolver->get_label_scope ().pop ();
559 void
560 ResolveItem::visit (AST::InherentImpl &impl_block)
562 NodeId scope_node_id = impl_block.get_node_id ();
563 resolver->get_name_scope ().push (scope_node_id);
564 resolver->get_type_scope ().push (scope_node_id);
565 resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
566 resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
568 resolve_visibility (impl_block.get_visibility ());
570 if (impl_block.has_generics ())
571 for (auto &generic : impl_block.get_generic_params ())
572 ResolveGenericParam::go (generic.get (), prefix, canonical_prefix);
574 // resolve any where clause items
575 if (impl_block.has_where_clause ())
576 ResolveWhereClause::Resolve (impl_block.get_where_clause ());
578 // FIXME this needs to be protected behind nominal type-checks see:
579 // rustc --explain E0118
580 // issue #2634
581 ResolveType::go (impl_block.get_type ().get ());
583 // Setup paths
584 CanonicalPath self_cpath = CanonicalPath::create_empty ();
585 bool ok = ResolveTypeToCanonicalPath::go (impl_block.get_type ().get (),
586 self_cpath);
587 rust_assert (ok);
588 rust_debug ("AST::InherentImpl resolve Self: {%s}",
589 self_cpath.get ().c_str ());
591 CanonicalPath impl_type = self_cpath;
592 CanonicalPath impl_type_seg
593 = CanonicalPath::inherent_impl_seg (impl_block.get_node_id (), impl_type);
594 CanonicalPath impl_prefix = prefix.append (impl_type_seg);
596 // see https://godbolt.org/z/a3vMbsT6W
597 CanonicalPath cpath = CanonicalPath::create_empty ();
598 if (canonical_prefix.size () <= 1)
600 cpath = impl_prefix;
602 else
604 std::string seg_buf = "<impl " + self_cpath.get () + ">";
605 CanonicalPath seg
606 = CanonicalPath::new_seg (impl_block.get_node_id (), seg_buf);
607 cpath = canonical_prefix.append (seg);
610 // done setup paths
612 auto Self
613 = CanonicalPath::get_big_self (impl_block.get_type ()->get_node_id ());
615 resolver->get_type_scope ().insert (Self,
616 impl_block.get_type ()->get_node_id (),
617 impl_block.get_type ()->get_locus ());
619 for (auto &impl_item : impl_block.get_impl_items ())
621 rust_debug (
622 "AST::InherentImpl resolve_impl_item: impl_prefix={%s} cpath={%s}",
623 impl_prefix.get ().c_str (), cpath.get ().c_str ());
624 resolve_impl_item (impl_item.get (), impl_prefix, cpath);
627 resolver->get_type_scope ().peek ()->clear_name (
628 Self, impl_block.get_type ()->get_node_id ());
630 resolver->get_type_scope ().pop ();
631 resolver->get_name_scope ().pop ();
634 void
635 ResolveItem::visit (AST::TraitImpl &impl_block)
637 NodeId scope_node_id = impl_block.get_node_id ();
639 resolve_visibility (impl_block.get_visibility ());
641 resolver->get_name_scope ().push (scope_node_id);
642 resolver->get_type_scope ().push (scope_node_id);
643 resolver->get_label_scope ().push (scope_node_id);
644 resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
645 resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
646 resolver->push_new_label_rib (resolver->get_type_scope ().peek ());
648 if (impl_block.has_generics ())
649 for (auto &generic : impl_block.get_generic_params ())
650 ResolveGenericParam::go (generic.get (), prefix, canonical_prefix);
652 // resolve any where clause items
653 if (impl_block.has_where_clause ())
654 ResolveWhereClause::Resolve (impl_block.get_where_clause ());
656 // CanonicalPath canonical_trait_type = CanonicalPath::create_empty ();
657 NodeId trait_resolved_node = ResolveType::go (&impl_block.get_trait_path ());
658 if (trait_resolved_node == UNKNOWN_NODEID)
660 resolver->get_name_scope ().pop ();
661 resolver->get_type_scope ().pop ();
662 resolver->get_label_scope ().pop ();
663 return;
666 // CanonicalPath canonical_impl_type = CanonicalPath::create_empty ();
667 NodeId type_resolved_node = ResolveType::go (impl_block.get_type ().get ());
668 if (type_resolved_node == UNKNOWN_NODEID)
670 resolver->get_name_scope ().pop ();
671 resolver->get_type_scope ().pop ();
672 resolver->get_label_scope ().pop ();
673 return;
676 bool ok;
677 // setup paths
678 CanonicalPath canonical_trait_type = CanonicalPath::create_empty ();
679 ok = ResolveTypeToCanonicalPath::go (&impl_block.get_trait_path (),
680 canonical_trait_type);
681 rust_assert (ok);
683 rust_debug ("AST::TraitImpl resolve trait type: {%s}",
684 canonical_trait_type.get ().c_str ());
686 CanonicalPath canonical_impl_type = CanonicalPath::create_empty ();
687 ok = ResolveTypeToCanonicalPath::go (impl_block.get_type ().get (),
688 canonical_impl_type);
689 rust_assert (ok);
691 rust_debug ("AST::TraitImpl resolve self: {%s}",
692 canonical_impl_type.get ().c_str ());
694 // raw paths
695 CanonicalPath impl_type_seg = canonical_impl_type;
696 CanonicalPath trait_type_seg = canonical_trait_type;
697 CanonicalPath projection
698 = CanonicalPath::trait_impl_projection_seg (impl_block.get_node_id (),
699 trait_type_seg, impl_type_seg);
700 CanonicalPath impl_prefix = prefix.append (projection);
702 // setup canonical-path
703 CanonicalPath canonical_projection
704 = CanonicalPath::trait_impl_projection_seg (impl_block.get_node_id (),
705 canonical_trait_type,
706 canonical_impl_type);
707 CanonicalPath cpath = CanonicalPath::create_empty ();
708 if (canonical_prefix.size () <= 1)
710 cpath = canonical_projection;
712 else
714 std::string projection_str = canonical_projection.get ();
715 std::string seg_buf
716 = "<impl " + projection_str.substr (1, projection_str.size () - 2)
717 + ">";
718 CanonicalPath seg
719 = CanonicalPath::new_seg (impl_block.get_node_id (), seg_buf);
720 cpath = canonical_prefix.append (seg);
723 // DONE setup canonical-path
725 auto Self
726 = CanonicalPath::get_big_self (impl_block.get_type ()->get_node_id ());
728 resolver->get_type_scope ().insert (Self,
729 impl_block.get_type ()->get_node_id (),
730 impl_block.get_type ()->get_locus ());
732 for (auto &impl_item : impl_block.get_impl_items ())
734 rust_debug (
735 "AST::TraitImpl resolve_impl_item: impl_prefix={%s} cpath={%s}",
736 impl_prefix.get ().c_str (), cpath.get ().c_str ());
737 resolve_impl_item (impl_item.get (), impl_prefix, cpath);
740 Rib *r = resolver->get_type_scope ().peek ();
741 r->clear_name (Self, impl_block.get_type ()->get_node_id ());
743 resolver->get_name_scope ().pop ();
744 resolver->get_type_scope ().pop ();
745 resolver->get_label_scope ().pop ();
748 void
749 ResolveItem::visit (AST::Trait &trait)
751 NodeId scope_node_id = trait.get_node_id ();
753 resolve_visibility (trait.get_visibility ());
755 resolver->get_name_scope ().push (scope_node_id);
756 resolver->get_type_scope ().push (scope_node_id);
757 resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
758 resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
760 // we need to inject an implicit self TypeParam here
761 // FIXME: which location should be used for Rust::Identifier `Self`?
762 AST::TypeParam *implicit_self
763 = new AST::TypeParam ({"Self"}, trait.get_locus ());
764 trait.insert_implict_self (
765 std::unique_ptr<AST::GenericParam> (implicit_self));
766 CanonicalPath Self = CanonicalPath::get_big_self (trait.get_node_id ());
768 for (auto &generic : trait.get_generic_params ())
769 ResolveGenericParam::go (generic.get (), prefix, canonical_prefix);
771 // Self is an implicit TypeParam so lets mark it as such
772 resolver->get_type_scope ().append_reference_for_def (
773 Self.get_node_id (), implicit_self->get_node_id ());
775 if (trait.has_type_param_bounds ())
777 for (auto &bound : trait.get_type_param_bounds ())
779 ResolveTypeBound::go (bound.get ());
783 // resolve any where clause items
784 if (trait.has_where_clause ())
785 ResolveWhereClause::Resolve (trait.get_where_clause ());
787 // resolve the paths
788 CanonicalPath path = CanonicalPath::create_empty ();
789 CanonicalPath cpath = CanonicalPath::create_empty ();
792 for (auto &item : trait.get_trait_items ())
794 ResolveTraitItems::go (item.get (), path, cpath);
797 resolver->get_type_scope ().pop ();
798 resolver->get_name_scope ().pop ();
801 void
802 ResolveItem::visit (AST::ExternBlock &extern_block)
804 resolve_visibility (extern_block.get_visibility ());
806 for (auto &item : extern_block.get_extern_items ())
808 resolve_extern_item (item.get ());
812 void
813 ResolveItem::resolve_impl_item (AST::AssociatedItem *item,
814 const CanonicalPath &prefix,
815 const CanonicalPath &canonical_prefix)
817 ResolveImplItems::go (item, prefix, canonical_prefix);
820 void
821 ResolveItem::resolve_extern_item (AST::ExternalItem *item)
823 ResolveExternItem::go (item, prefix, canonical_prefix);
826 static void
827 flatten_glob (const AST::UseTreeGlob &glob,
828 std::vector<AST::SimplePath> &paths);
829 static void
830 flatten_rebind (const AST::UseTreeRebind &glob,
831 std::vector<AST::SimplePath> &paths);
832 static void
833 flatten_list (const AST::UseTreeList &glob,
834 std::vector<AST::SimplePath> &paths);
836 static void
837 flatten (const AST::UseTree *tree, std::vector<AST::SimplePath> &paths)
839 switch (tree->get_kind ())
841 case AST::UseTree::Glob: {
842 auto glob = static_cast<const AST::UseTreeGlob *> (tree);
843 flatten_glob (*glob, paths);
844 break;
846 case AST::UseTree::Rebind: {
847 auto rebind = static_cast<const AST::UseTreeRebind *> (tree);
848 flatten_rebind (*rebind, paths);
849 break;
851 case AST::UseTree::List: {
852 auto list = static_cast<const AST::UseTreeList *> (tree);
853 flatten_list (*list, paths);
854 break;
856 break;
860 static void
861 flatten_glob (const AST::UseTreeGlob &glob, std::vector<AST::SimplePath> &paths)
863 if (glob.has_path ())
864 paths.emplace_back (glob.get_path ());
867 static void
868 flatten_rebind (const AST::UseTreeRebind &rebind,
869 std::vector<AST::SimplePath> &paths)
871 auto path = rebind.get_path ();
872 if (rebind.has_path ())
873 paths.emplace_back (path);
875 // FIXME: Do we want to emplace the rebind here as well?
876 if (rebind.has_identifier ())
878 auto rebind_path = path;
879 auto new_seg = rebind.get_identifier ();
881 // Add the identifier as a new path
882 rebind_path.get_segments ().back ()
883 = AST::SimplePathSegment (new_seg.as_string (), UNDEF_LOCATION);
885 paths.emplace_back (rebind_path);
889 static void
890 flatten_list (const AST::UseTreeList &list, std::vector<AST::SimplePath> &paths)
892 auto prefix = AST::SimplePath::create_empty ();
893 if (list.has_path ())
894 prefix = list.get_path ();
896 for (const auto &tree : list.get_trees ())
898 auto sub_paths = std::vector<AST::SimplePath> ();
899 flatten (tree.get (), sub_paths);
901 for (auto &sub_path : sub_paths)
903 auto new_path = prefix;
904 std::copy (sub_path.get_segments ().begin (),
905 sub_path.get_segments ().end (),
906 std::back_inserter (new_path.get_segments ()));
908 paths.emplace_back (new_path);
914 * Flatten a UseDeclaration's UseTree into multiple simple paths to resolve.
916 * Given the following use declarations:
917 * ```
918 * use some::path::to_resolve; #1
919 * use some::path::to_glob::*; #2
920 * use some::path::{one, two}; #2
921 * ```
923 * In the first case, we simply want to return a vector with a single
924 * SimplePath:
925 * [some::path::to_resolve]
927 * In the second case, we want to resolve the glob's "origin path":
928 * [some::path::to_glob]
930 * Finally in the third case, we want to create two SimplePaths to resolve:
931 * [some::path::one, some::path::two]
933 static std::vector<AST::SimplePath>
934 flatten_use_dec_to_paths (const AST::UseDeclaration &use_item)
936 auto paths = std::vector<AST::SimplePath> ();
938 const auto &tree = use_item.get_tree ();
939 flatten (tree.get (), paths);
941 return paths;
944 void
945 ResolveItem::visit (AST::UseDeclaration &use_item)
947 std::vector<AST::SimplePath> to_resolve = flatten_use_dec_to_paths (use_item);
949 // FIXME: I think this does not actually resolve glob use-decls and is going
950 // the wrong way about it. RFC #1560 specifies the following:
952 // > When we find a glob import, we have to record a 'back link', so that when
953 // a public name is added for the supplying module, we can add it for the
954 // importing module.
956 // Which is the opposite of what we're doing if I understand correctly?
958 NodeId current_module = resolver->peek_current_module_scope ();
959 for (auto &path : to_resolve)
961 rust_debug ("resolving use-decl path: [%s]", path.as_string ().c_str ());
962 NodeId resolved_node_id = ResolvePath::go (&path);
963 bool ok = resolved_node_id != UNKNOWN_NODEID;
964 if (!ok)
965 continue;
967 const AST::SimplePathSegment &final_seg = path.get_segments ().back ();
969 auto decl
970 = CanonicalPath::new_seg (resolved_node_id, final_seg.as_string ());
971 mappings->insert_module_child_item (current_module, decl);
973 resolver->get_type_scope ().insert (decl, resolved_node_id,
974 path.get_locus (),
975 Rib::ItemType::Type);
976 rust_debug ("use-decl rexporting: [%s]", decl.get ().c_str ());
980 ResolveImplItems::ResolveImplItems (const CanonicalPath &prefix,
981 const CanonicalPath &canonical_prefix)
982 : ResolveItem (prefix, canonical_prefix)
985 void
986 ResolveImplItems::go (AST::AssociatedItem *item, const CanonicalPath &prefix,
987 const CanonicalPath &canonical_prefix)
989 if (item->is_marked_for_strip ())
990 return;
992 ResolveImplItems resolver (prefix, canonical_prefix);
993 item->accept_vis (resolver);
996 void
997 ResolveImplItems::visit (AST::TypeAlias &alias)
999 ResolveItem::visit (alias);
1001 resolve_visibility (alias.get_visibility ());
1003 // FIXME this stops the erronious unused decls which will be fixed later on
1004 resolver->get_type_scope ().append_reference_for_def (alias.get_node_id (),
1005 alias.get_node_id ());
1008 void
1009 ResolveExternItem::go (AST::ExternalItem *item, const CanonicalPath &prefix,
1010 const CanonicalPath &canonical_prefix)
1012 ResolveExternItem resolver (prefix, canonical_prefix);
1013 item->accept_vis (resolver);
1016 void
1017 ResolveExternItem::visit (AST::ExternalFunctionItem &function)
1019 NodeId scope_node_id = function.get_node_id ();
1020 auto decl = CanonicalPath::new_seg (function.get_node_id (),
1021 function.get_identifier ().as_string ());
1022 auto path = prefix.append (decl);
1023 auto cpath = canonical_prefix.append (decl);
1025 mappings->insert_canonical_path (function.get_node_id (), cpath);
1027 resolve_visibility (function.get_visibility ());
1029 resolver->get_name_scope ().push (scope_node_id);
1030 resolver->get_type_scope ().push (scope_node_id);
1031 resolver->get_label_scope ().push (scope_node_id);
1032 resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
1033 resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
1034 resolver->push_new_label_rib (resolver->get_type_scope ().peek ());
1036 // resolve the generics
1037 if (function.has_generics ())
1038 for (auto &generic : function.get_generic_params ())
1039 ResolveGenericParam::go (generic.get (), prefix, canonical_prefix);
1041 if (function.has_return_type ())
1042 ResolveType::go (function.get_return_type ().get ());
1044 // we make a new scope so the names of parameters are resolved and shadowed
1045 // correctly
1046 for (auto &param : function.get_function_params ())
1047 if (!param.is_variadic ())
1048 ResolveType::go (param.get_type ().get ());
1050 // done
1051 resolver->get_name_scope ().pop ();
1052 resolver->get_type_scope ().pop ();
1053 resolver->get_label_scope ().pop ();
1056 void
1057 ResolveExternItem::visit (AST::ExternalStaticItem &item)
1059 resolve_visibility (item.get_visibility ());
1061 ResolveType::go (item.get_type ().get ());
1064 } // namespace Resolver
1065 } // namespace Rust
1067 #if CHECKING_P
1069 namespace selftest {
1071 static void
1072 rust_flatten_nested_glob (void)
1074 auto foo = Rust::AST::SimplePathSegment ("foo", UNDEF_LOCATION);
1075 auto bar = Rust::AST::SimplePathSegment ("bar", UNDEF_LOCATION);
1076 auto foobar = Rust::AST::SimplePath ({foo, bar});
1078 auto glob
1079 = Rust::AST::UseTreeGlob (Rust::AST::UseTreeGlob::PathType::PATH_PREFIXED,
1080 foobar, UNDEF_LOCATION);
1082 auto paths = std::vector<Rust::AST::SimplePath> ();
1083 Rust::Resolver::flatten_glob (glob, paths);
1085 ASSERT_TRUE (!paths.empty ());
1086 ASSERT_EQ (paths.size (), 1);
1087 ASSERT_EQ (paths[0].get_segments ()[0].as_string (), "foo");
1088 ASSERT_EQ (paths[0].get_segments ()[1].as_string (), "bar");
1091 static void
1092 rust_flatten_glob (void)
1094 auto frob = Rust::AST::SimplePath::from_str ("frobulator", UNDEF_LOCATION);
1096 auto glob
1097 = Rust::AST::UseTreeGlob (Rust::AST::UseTreeGlob::PathType::PATH_PREFIXED,
1098 frob, UNDEF_LOCATION);
1100 auto paths = std::vector<Rust::AST::SimplePath> ();
1101 Rust::Resolver::flatten_glob (glob, paths);
1103 ASSERT_TRUE (!paths.empty ());
1104 ASSERT_EQ (paths.size (), 1);
1105 ASSERT_EQ (paths[0], "frobulator");
1108 static void
1109 rust_flatten_rebind_none (void)
1111 auto foo = Rust::AST::SimplePathSegment ("foo", UNDEF_LOCATION);
1112 auto bar = Rust::AST::SimplePathSegment ("bar", UNDEF_LOCATION);
1113 auto foobar = Rust::AST::SimplePath ({foo, bar});
1115 auto rebind = Rust::AST::UseTreeRebind (Rust::AST::UseTreeRebind::NONE,
1116 foobar, UNDEF_LOCATION);
1118 auto paths = std::vector<Rust::AST::SimplePath> ();
1119 Rust::Resolver::flatten_rebind (rebind, paths);
1121 ASSERT_TRUE (!paths.empty ());
1122 ASSERT_EQ (paths.size (), 1);
1123 ASSERT_EQ (paths[0].get_segments ()[0].as_string (), "foo");
1124 ASSERT_EQ (paths[0].get_segments ()[1].as_string (), "bar");
1127 static void
1128 rust_flatten_rebind (void)
1130 auto frob = Rust::AST::SimplePath::from_str ("frobulator", UNDEF_LOCATION);
1132 auto rebind = Rust::AST::UseTreeRebind (Rust::AST::UseTreeRebind::IDENTIFIER,
1133 frob, UNDEF_LOCATION, {"saindoux"});
1135 auto paths = std::vector<Rust::AST::SimplePath> ();
1136 Rust::Resolver::flatten_rebind (rebind, paths);
1138 ASSERT_TRUE (!paths.empty ());
1139 ASSERT_EQ (paths.size (), 2);
1140 ASSERT_EQ (paths[0], "frobulator");
1141 ASSERT_EQ (paths[1], "saindoux");
1144 static void
1145 rust_flatten_rebind_nested (void)
1147 auto foo = Rust::AST::SimplePathSegment ("foo", UNDEF_LOCATION);
1148 auto bar = Rust::AST::SimplePathSegment ("bar", UNDEF_LOCATION);
1149 auto baz = Rust::AST::SimplePathSegment ("baz", UNDEF_LOCATION);
1151 auto foo_bar_baz = Rust::AST::SimplePath ({foo, bar, baz});
1153 auto rebind
1154 = Rust::AST::UseTreeRebind (Rust::AST::UseTreeRebind::IDENTIFIER,
1155 foo_bar_baz, UNDEF_LOCATION, {"saindoux"});
1157 auto paths = std::vector<Rust::AST::SimplePath> ();
1158 Rust::Resolver::flatten_rebind (rebind, paths);
1160 ASSERT_TRUE (!paths.empty ());
1161 ASSERT_EQ (paths.size (), 2);
1162 ASSERT_EQ (paths[0].get_segments ()[0].as_string (), "foo");
1163 ASSERT_EQ (paths[0].get_segments ()[1].as_string (), "bar");
1164 ASSERT_EQ (paths[0].get_segments ()[2].as_string (), "baz");
1165 ASSERT_EQ (paths[1].get_segments ()[0].as_string (), "foo");
1166 ASSERT_EQ (paths[1].get_segments ()[1].as_string (), "bar");
1167 ASSERT_EQ (paths[1].get_segments ()[2].as_string (), "saindoux");
1170 static void
1171 rust_flatten_list (void)
1173 auto foo = Rust::AST::SimplePathSegment ("foo", UNDEF_LOCATION);
1174 auto bar = Rust::AST::SimplePathSegment ("bar", UNDEF_LOCATION);
1175 auto foo_bar = Rust::AST::SimplePath ({foo, bar});
1177 auto baz = Rust::AST::SimplePath::from_str ("baz", UNDEF_LOCATION);
1178 auto bul = Rust::AST::SimplePath::from_str ("bul", UNDEF_LOCATION);
1180 // use foo::bar::{baz, bul};
1182 auto use0 = std::unique_ptr<Rust::AST::UseTree> (
1183 new Rust::AST::UseTreeRebind (Rust::AST::UseTreeRebind::NONE, baz,
1184 UNDEF_LOCATION));
1185 auto use1 = std::unique_ptr<Rust::AST::UseTree> (
1186 new Rust::AST::UseTreeRebind (Rust::AST::UseTreeRebind::NONE, bul,
1187 UNDEF_LOCATION));
1189 auto uses = std::vector<std::unique_ptr<Rust::AST::UseTree>> ();
1190 uses.emplace_back (std::move (use0));
1191 uses.emplace_back (std::move (use1));
1193 auto list
1194 = Rust::AST::UseTreeList (Rust::AST::UseTreeList::PATH_PREFIXED, foo_bar,
1195 std::move (uses), UNDEF_LOCATION);
1197 auto paths = std::vector<Rust::AST::SimplePath> ();
1198 Rust::Resolver::flatten_list (list, paths);
1200 ASSERT_TRUE (!paths.empty ());
1201 ASSERT_EQ (paths.size (), 2);
1202 ASSERT_EQ (paths[0].get_segments ()[0].as_string (), "foo");
1203 ASSERT_EQ (paths[0].get_segments ()[1].as_string (), "bar");
1204 ASSERT_EQ (paths[0].get_segments ()[2].as_string (), "baz");
1205 ASSERT_EQ (paths[1].get_segments ()[0].as_string (), "foo");
1206 ASSERT_EQ (paths[1].get_segments ()[1].as_string (), "bar");
1207 ASSERT_EQ (paths[1].get_segments ()[2].as_string (), "bul");
1210 static void
1211 rust_use_dec_flattening (void)
1213 rust_flatten_glob ();
1214 rust_flatten_nested_glob ();
1215 rust_flatten_rebind_none ();
1216 rust_flatten_rebind ();
1217 rust_flatten_rebind_nested ();
1218 rust_flatten_list ();
1221 void
1222 rust_simple_path_resolve_test (void)
1224 rust_use_dec_flattening ();
1227 } // namespace selftest
1229 #endif // CHECKING_P