1 // Copyright (C) 2020-2024 Free Software Foundation, Inc.
3 // This file is part of GCC.
5 // GCC is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU General Public License as published by the Free
7 // Software Foundation; either version 3, or (at your option) any later
10 // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 // You should have received a copy of the GNU General Public License
16 // along with GCC; see the file COPYING3. If not see
17 // <http://www.gnu.org/licenses/>.
19 #include "rust-toplevel-name-resolver-2.0.h"
22 #include "rust-ast-full.h"
23 #include "rust-hir-map.h"
24 #include "rust-attribute-values.h"
27 namespace Resolver2_0
{
30 GlobbingVisitor::go (AST::Module
*module
)
32 for (auto &i
: module
->get_items ())
37 GlobbingVisitor::visit (AST::Module
&module
)
39 if (module
.get_visibility ().is_public ())
40 ctx
.insert_shadowable (module
.get_name (), module
.get_node_id (),
45 GlobbingVisitor::visit (AST::MacroRulesDefinition
¯o
)
47 if (macro
.get_visibility ().is_public ())
48 ctx
.insert_shadowable (macro
.get_rule_name (), macro
.get_node_id (),
53 GlobbingVisitor::visit (AST::Function
&function
)
55 if (function
.get_visibility ().is_public ())
56 ctx
.insert_shadowable (function
.get_function_name (),
57 function
.get_node_id (), Namespace::Values
);
61 GlobbingVisitor::visit (AST::StaticItem
&static_item
)
63 if (static_item
.get_visibility ().is_public ())
64 ctx
.insert_shadowable (static_item
.get_identifier (),
65 static_item
.get_node_id (), Namespace::Values
);
69 GlobbingVisitor::visit (AST::StructStruct
&struct_item
)
71 if (struct_item
.get_visibility ().is_public ())
73 ctx
.insert_shadowable (struct_item
.get_identifier (),
74 struct_item
.get_node_id (), Namespace::Types
);
75 if (struct_item
.is_unit_struct ())
76 ctx
.insert_shadowable (struct_item
.get_identifier (),
77 struct_item
.get_node_id (), Namespace::Values
);
82 GlobbingVisitor::visit (AST::TupleStruct
&tuple_struct
)
84 if (tuple_struct
.get_visibility ().is_public ())
86 ctx
.insert_shadowable (tuple_struct
.get_identifier (),
87 tuple_struct
.get_node_id (), Namespace::Types
);
89 ctx
.insert_shadowable (tuple_struct
.get_identifier (),
90 tuple_struct
.get_node_id (), Namespace::Values
);
95 GlobbingVisitor::visit (AST::Enum
&enum_item
)
97 if (enum_item
.get_visibility ().is_public ())
98 ctx
.insert_shadowable (enum_item
.get_identifier (),
99 enum_item
.get_node_id (), Namespace::Types
);
103 GlobbingVisitor::visit (AST::Union
&union_item
)
105 if (union_item
.get_visibility ().is_public ())
106 ctx
.insert_shadowable (union_item
.get_identifier (),
107 union_item
.get_node_id (), Namespace::Values
);
111 GlobbingVisitor::visit (AST::ConstantItem
&const_item
)
113 if (const_item
.get_visibility ().is_public ())
114 ctx
.insert_shadowable (const_item
.get_identifier (),
115 const_item
.get_node_id (), Namespace::Values
);
119 GlobbingVisitor::visit (AST::ExternCrate
&crate
)
123 GlobbingVisitor::visit (AST::UseDeclaration
&use
)
128 TopLevel::TopLevel (NameResolutionContext
&resolver
)
129 : DefaultResolver (resolver
)
132 template <typename T
>
134 TopLevel::insert_or_error_out (const Identifier
&identifier
, const T
&node
,
137 insert_or_error_out (identifier
, node
.get_locus (), node
.get_node_id (), ns
);
141 TopLevel::insert_or_error_out (const Identifier
&identifier
,
142 const location_t
&locus
, const NodeId
&node_id
,
145 // keep track of each node's location to provide useful errors
146 node_locations
.emplace (node_id
, locus
);
148 auto result
= ctx
.insert (identifier
, node_id
, ns
);
150 if (!result
&& result
.error ().existing
!= node_id
)
152 rich_location
rich_loc (line_table
, locus
);
153 rich_loc
.add_range (node_locations
[result
.error ().existing
]);
155 rust_error_at (rich_loc
, ErrorCode::E0428
, "%qs defined multiple times",
156 identifier
.as_string ().c_str ());
161 TopLevel::go (AST::Crate
&crate
)
163 // we do not include builtin types in the top-level definition collector, as
164 // they are not used until `Late`. furthermore, we run this visitor multiple
165 // times in a row in a fixed-point fashion, so it would make the code
166 // responsible for this ugly and perfom a lot of error checking.
168 for (auto &item
: crate
.items
)
169 item
->accept_vis (*this);
173 TopLevel::visit (AST::Module
&module
)
175 insert_or_error_out (module
.get_name (), module
, Namespace::Types
);
177 auto sub_visitor
= [this, &module
] () {
178 for (auto &item
: module
.get_items ())
179 item
->accept_vis (*this);
182 ctx
.scoped (Rib::Kind::Module
, module
.get_node_id (), sub_visitor
,
185 if (Analysis::Mappings::get ()->lookup_ast_module (module
.get_node_id ())
187 Analysis::Mappings::get ()->insert_ast_module (&module
);
191 TopLevel::visit (AST::Trait
&trait
)
193 // FIXME: This Self injection is dodgy. It even lead to issues with metadata
194 // export in the past (#2349). We cannot tell appart injected parameters from
195 // regular ones. Dumping generic parameters highlights this Self in metadata,
196 // during debug or proc macro collection. This is clearly a hack.
198 // For now I'll keep it here in the new name resolver even if it should
199 // probably not be there. We need to find another way to solve this.
200 // Maybe an additional attribute to Trait ?
202 // From old resolver:
203 //// we need to inject an implicit self TypeParam here
204 //// FIXME: which location should be used for Rust::Identifier `Self`?
205 AST::TypeParam
*implicit_self
206 = new AST::TypeParam ({"Self"}, trait
.get_locus ());
207 trait
.insert_implict_self (
208 std::unique_ptr
<AST::GenericParam
> (implicit_self
));
210 DefaultResolver::visit (trait
);
213 template <typename PROC_MACRO
>
215 insert_macros (std::vector
<PROC_MACRO
> ¯os
, NameResolutionContext
&ctx
)
217 for (auto ¯o
: macros
)
219 auto res
= ctx
.macros
.insert (macro
.get_name (), macro
.get_node_id ());
221 if (!res
&& res
.error ().existing
!= macro
.get_node_id ())
223 rust_error_at (UNKNOWN_LOCATION
, ErrorCode::E0428
,
224 "macro %qs defined multiple times",
225 macro
.get_name ().c_str ());
231 TopLevel::visit (AST::ExternCrate
&crate
)
234 rust_assert (Analysis::Mappings::get ()->lookup_crate_name (
235 crate
.get_referenced_crate (), num
));
237 auto attribute_macros
238 = Analysis::Mappings::get ()->lookup_attribute_proc_macros (num
);
240 auto bang_macros
= Analysis::Mappings::get ()->lookup_bang_proc_macros (num
);
243 = Analysis::Mappings::get ()->lookup_derive_proc_macros (num
);
245 auto sub_visitor
= [&] () {
246 // TODO: Find a way to keep this part clean without the double dispatch.
247 if (derive_macros
.has_value ())
249 insert_macros (derive_macros
.value (), ctx
);
250 for (auto ¯o
: derive_macros
.value ())
251 Analysis::Mappings::get ()->insert_derive_proc_macro_def (macro
);
253 if (attribute_macros
.has_value ())
255 insert_macros (attribute_macros
.value (), ctx
);
256 for (auto ¯o
: attribute_macros
.value ())
257 Analysis::Mappings::get ()->insert_attribute_proc_macro_def (macro
);
259 if (bang_macros
.has_value ())
261 insert_macros (bang_macros
.value (), ctx
);
262 for (auto ¯o
: bang_macros
.value ())
263 Analysis::Mappings::get ()->insert_bang_proc_macro_def (macro
);
267 if (crate
.has_as_clause ())
268 ctx
.scoped (Rib::Kind::Module
, crate
.get_node_id (), sub_visitor
,
269 crate
.get_as_clause ());
271 ctx
.scoped (Rib::Kind::Module
, crate
.get_node_id (), sub_visitor
,
272 crate
.get_referenced_crate ());
276 is_macro_export (AST::MacroRulesDefinition
&def
)
278 for (const auto &attr
: def
.get_outer_attrs ())
279 if (attr
.get_path ().as_string () == Values::Attributes::MACRO_EXPORT
)
286 TopLevel::visit (AST::MacroRulesDefinition
¯o
)
288 // we do not insert macros in the current rib as that needs to be done in the
289 // textual scope of the Early pass. we only insert them in the root of the
290 // crate if they are marked with #[macro_export]. The execption to this is
291 // macros 2.0, which get resolved and inserted like regular items.
293 if (is_macro_export (macro
))
295 auto res
= ctx
.macros
.insert_at_root (macro
.get_rule_name (),
296 macro
.get_node_id ());
297 if (!res
&& res
.error ().existing
!= macro
.get_node_id ())
300 rich_location
rich_loc (line_table
, macro
.get_locus ());
301 rich_loc
.add_range (node_locations
[res
.error ().existing
]);
303 rust_error_at (rich_loc
, ErrorCode::E0428
,
304 "macro %qs defined multiple times",
305 macro
.get_rule_name ().as_string ().c_str ());
309 if (macro
.get_kind () == AST::MacroRulesDefinition::MacroKind::DeclMacro
)
310 insert_or_error_out (macro
.get_rule_name (), macro
, Namespace::Macros
);
312 auto mappings
= Analysis::Mappings::get ();
313 AST::MacroRulesDefinition
*tmp
= nullptr;
314 if (mappings
->lookup_macro_def (macro
.get_node_id (), &tmp
))
317 mappings
->insert_macro_def (¯o
);
321 TopLevel::visit (AST::Function
&function
)
323 insert_or_error_out (function
.get_function_name (), function
,
326 DefaultResolver::visit (function
);
330 TopLevel::visit (AST::BlockExpr
&expr
)
332 // extracting the lambda from the `scoped` call otherwise the code looks like
333 // a hot turd thanks to our .clang-format
335 auto sub_vis
= [this, &expr
] () {
336 for (auto &stmt
: expr
.get_statements ())
337 stmt
->accept_vis (*this);
339 if (expr
.has_tail_expr ())
340 expr
.get_tail_expr ().accept_vis (*this);
343 ctx
.scoped (Rib::Kind::Normal
, expr
.get_node_id (), sub_vis
);
347 TopLevel::visit (AST::StaticItem
&static_item
)
350 = [this, &static_item
] () { static_item
.get_expr ().accept_vis (*this); };
352 ctx
.scoped (Rib::Kind::Item
, static_item
.get_node_id (), sub_vis
);
356 TopLevel::visit (AST::StructStruct
&struct_item
)
358 insert_or_error_out (struct_item
.get_struct_name (), struct_item
,
361 // Do we need to insert the constructor in the value namespace as well?
363 // Do we need to do anything if the struct is a unit struct?
364 if (struct_item
.is_unit_struct ())
365 insert_or_error_out (struct_item
.get_struct_name (), struct_item
,
370 TopLevel::visit (AST::TupleStruct
&tuple_struct
)
372 insert_or_error_out (tuple_struct
.get_struct_name (), tuple_struct
,
375 insert_or_error_out (tuple_struct
.get_struct_name (), tuple_struct
,
380 TopLevel::visit (AST::EnumItem
&variant
)
382 insert_or_error_out (variant
.get_identifier (), variant
, Namespace::Types
);
386 TopLevel::visit (AST::EnumItemTuple
&variant
)
388 insert_or_error_out (variant
.get_identifier (), variant
, Namespace::Types
);
392 TopLevel::visit (AST::EnumItemStruct
&variant
)
394 insert_or_error_out (variant
.get_identifier (), variant
, Namespace::Types
);
398 TopLevel::visit (AST::EnumItemDiscriminant
&variant
)
400 insert_or_error_out (variant
.get_identifier (), variant
, Namespace::Types
);
404 TopLevel::visit (AST::Enum
&enum_item
)
406 insert_or_error_out (enum_item
.get_identifier (), enum_item
,
409 auto field_vis
= [this, &enum_item
] () {
410 for (auto &variant
: enum_item
.get_variants ())
411 variant
->accept_vis (*this);
414 ctx
.scoped (Rib::Kind::Item
/* FIXME: Is that correct? */,
415 enum_item
.get_node_id (), field_vis
, enum_item
.get_identifier ());
419 TopLevel::visit (AST::Union
&union_item
)
421 insert_or_error_out (union_item
.get_identifier (), union_item
,
426 TopLevel::visit (AST::ConstantItem
&const_item
)
428 insert_or_error_out (const_item
.get_identifier (), const_item
,
432 = [this, &const_item
] () { const_item
.get_expr ().accept_vis (*this); };
434 ctx
.scoped (Rib::Kind::ConstantItem
, const_item
.get_node_id (), expr_vis
);
438 TopLevel::handle_use_glob (AST::SimplePath
&glob
)
440 auto resolved
= ctx
.types
.resolve_path (glob
.get_segments ());
441 if (!resolved
.has_value ())
445 = Analysis::Mappings::get ()->lookup_ast_module (resolved
->get_node_id ());
447 if (!result
.has_value ())
450 GlobbingVisitor
gvisitor (ctx
);
451 gvisitor
.go (result
.value ());
457 TopLevel::handle_use_dec (AST::SimplePath
&path
)
459 auto locus
= path
.get_final_segment ().get_locus ();
460 auto declared_name
= path
.get_final_segment ().as_string ();
462 // in what namespace do we perform path resolution? All of them? see which one
463 // matches? Error out on ambiguities?
464 // so, apparently, for each one that matches, add it to the proper namespace
469 auto resolve_and_insert
470 = [this, &found
, &declared_name
, locus
] (Namespace ns
,
471 const AST::SimplePath
&path
) {
472 tl::optional
<Rib::Definition
> resolved
= tl::nullopt
;
474 // FIXME: resolve_path needs to return an `expected<NodeId, Error>` so
475 // that we can improve it with hints or location or w/ever. and maybe
476 // only emit it the first time.
479 case Namespace::Values
:
480 resolved
= ctx
.values
.resolve_path (path
.get_segments ());
482 case Namespace::Types
:
483 resolved
= ctx
.types
.resolve_path (path
.get_segments ());
485 case Namespace::Macros
:
486 resolved
= ctx
.macros
.resolve_path (path
.get_segments ());
488 case Namespace::Labels
:
489 // TODO: Is that okay?
494 (void) resolved
.map ([this, &found
, &declared_name
, locus
, ns
,
495 path
] (Rib::Definition def
) {
498 // what do we do with the id?
499 insert_or_error_out (declared_name
, locus
, def
.get_node_id (), ns
);
500 auto result
= node_forwarding
.find (def
.get_node_id ());
501 if (result
!= node_forwarding
.cend ()
502 && result
->second
!= path
.get_node_id ())
503 rust_error_at (path
.get_locus (), "%qs defined multiple times",
504 declared_name
.c_str ());
505 else // No previous thing has inserted this into our scope
506 node_forwarding
.insert ({def
.get_node_id (), path
.get_node_id ()});
508 return def
.get_node_id ();
512 resolve_and_insert (Namespace::Values
, path
);
513 resolve_and_insert (Namespace::Types
, path
);
514 resolve_and_insert (Namespace::Macros
, path
);
520 TopLevel::handle_rebind (std::pair
<AST::SimplePath
, AST::UseTreeRebind
> &rebind
)
522 auto &path
= rebind
.first
;
524 location_t locus
= UNKNOWN_LOCATION
;
525 std::string declared_name
;
527 switch (rebind
.second
.get_new_bind_type ())
529 case AST::UseTreeRebind::NewBindType::IDENTIFIER
:
530 declared_name
= rebind
.second
.get_identifier ().as_string ();
531 locus
= rebind
.second
.get_identifier ().get_locus ();
533 case AST::UseTreeRebind::NewBindType::NONE
:
534 declared_name
= path
.get_final_segment ().as_string ();
535 locus
= path
.get_final_segment ().get_locus ();
537 case AST::UseTreeRebind::NewBindType::WILDCARD
:
542 // in what namespace do we perform path resolution? All
543 // of them? see which one matches? Error out on
544 // ambiguities? so, apparently, for each one that
545 // matches, add it to the proper namespace
549 auto resolve_and_insert
= [this, &found
, &declared_name
,
550 locus
] (Namespace ns
,
551 const AST::SimplePath
&path
) {
552 tl::optional
<Rib::Definition
> resolved
= tl::nullopt
;
553 tl::optional
<Rib::Definition
> resolved_bind
= tl::nullopt
;
555 std::vector
<AST::SimplePathSegment
> declaration_v
556 = {AST::SimplePathSegment (declared_name
, locus
)};
557 // FIXME: resolve_path needs to return an `expected<NodeId, Error>` so
558 // that we can improve it with hints or location or w/ever. and maybe
559 // only emit it the first time.
562 case Namespace::Values
:
563 resolved
= ctx
.values
.resolve_path (path
.get_segments ());
564 resolved_bind
= ctx
.values
.resolve_path (declaration_v
);
566 case Namespace::Types
:
567 resolved
= ctx
.types
.resolve_path (path
.get_segments ());
568 resolved_bind
= ctx
.types
.resolve_path (declaration_v
);
570 case Namespace::Macros
:
571 resolved
= ctx
.macros
.resolve_path (path
.get_segments ());
572 resolved_bind
= ctx
.macros
.resolve_path (declaration_v
);
574 case Namespace::Labels
:
575 // TODO: Is that okay?
579 resolved
.map ([this, &found
, &declared_name
, locus
, ns
, path
,
580 &resolved_bind
] (Rib::Definition def
) {
583 insert_or_error_out (declared_name
, locus
, def
.get_node_id (), ns
);
584 if (resolved_bind
.has_value ())
586 auto bind_def
= resolved_bind
.value ();
587 // what do we do with the id?
588 auto result
= node_forwarding
.find (bind_def
.get_node_id ());
589 if (result
!= node_forwarding
.cend ()
590 && result
->second
!= path
.get_node_id ())
591 rust_error_at (path
.get_locus (), "%qs defined multiple times",
592 declared_name
.c_str ());
596 // No previous thing has inserted this into our scope
597 node_forwarding
.insert ({def
.get_node_id (), path
.get_node_id ()});
599 return def
.get_node_id ();
603 // do this for all namespaces (even Labels?)
605 resolve_and_insert (Namespace::Values
, path
);
606 resolve_and_insert (Namespace::Types
, path
);
607 resolve_and_insert (Namespace::Macros
, path
);
609 // TODO: No labels? No, right?
616 const AST::UseTreeRebind
&glob
,
617 std::vector
<std::pair
<AST::SimplePath
, AST::UseTreeRebind
>> &rebind_paths
);
621 const AST::UseTreeList
&glob
, std::vector
<AST::SimplePath
> &paths
,
622 std::vector
<AST::SimplePath
> &glob_paths
,
623 std::vector
<std::pair
<AST::SimplePath
, AST::UseTreeRebind
>> &rebind_paths
,
624 NameResolutionContext
&ctx
);
626 flatten_glob (const AST::UseTreeGlob
&glob
,
627 std::vector
<AST::SimplePath
> &glob_paths
,
628 NameResolutionContext
&ctx
);
632 const AST::UseTree
*tree
, std::vector
<AST::SimplePath
> &paths
,
633 std::vector
<AST::SimplePath
> &glob_paths
,
634 std::vector
<std::pair
<AST::SimplePath
, AST::UseTreeRebind
>> &rebind_paths
,
635 NameResolutionContext
&ctx
)
637 switch (tree
->get_kind ())
639 case AST::UseTree::Rebind
: {
640 auto rebind
= static_cast<const AST::UseTreeRebind
*> (tree
);
641 flatten_rebind (*rebind
, rebind_paths
);
644 case AST::UseTree::List
: {
645 auto list
= static_cast<const AST::UseTreeList
*> (tree
);
646 flatten_list (*list
, paths
, glob_paths
, rebind_paths
, ctx
);
649 case AST::UseTree::Glob
: {
650 auto glob
= static_cast<const AST::UseTreeGlob
*> (tree
);
651 flatten_glob (*glob
, glob_paths
, ctx
);
660 const AST::UseTreeRebind
&rebind
,
661 std::vector
<std::pair
<AST::SimplePath
, AST::UseTreeRebind
>> &rebind_paths
)
663 rebind_paths
.emplace_back (rebind
.get_path (), rebind
);
666 /** Prefix a list of subpath
667 * @param prefix A prefix for all subpath
668 * @param subs List of subpath to prefix
669 * @param size List where results should be stored
672 prefix_subpaths (AST::SimplePath prefix
, std::vector
<AST::SimplePath
> subs
,
673 std::vector
<AST::SimplePath
> &results
)
675 for (auto &sub
: subs
)
677 auto new_path
= prefix
;
678 std::copy (sub
.get_segments ().begin (), sub
.get_segments ().end (),
679 std::back_inserter (new_path
.get_segments ()));
680 results
.emplace_back (new_path
);
686 AST::SimplePath prefix
,
687 std::vector
<std::pair
<AST::SimplePath
, AST::UseTreeRebind
>> subs
,
688 std::vector
<std::pair
<AST::SimplePath
, AST::UseTreeRebind
>> &results
)
690 for (auto &sub
: subs
)
692 auto new_path
= prefix
;
693 std::copy (sub
.first
.get_segments ().begin (),
694 sub
.first
.get_segments ().end (),
695 std::back_inserter (new_path
.get_segments ()));
696 results
.emplace_back (std::make_pair (new_path
, sub
.second
));
702 const AST::UseTreeList
&list
, std::vector
<AST::SimplePath
> &paths
,
703 std::vector
<AST::SimplePath
> &glob_paths
,
704 std::vector
<std::pair
<AST::SimplePath
, AST::UseTreeRebind
>> &rebind_paths
,
705 NameResolutionContext
&ctx
)
707 auto prefix
= AST::SimplePath::create_empty ();
708 if (list
.has_path ())
709 prefix
= list
.get_path ();
711 for (const auto &tree
: list
.get_trees ())
713 auto sub_paths
= std::vector
<AST::SimplePath
> ();
714 auto sub_globs
= std::vector
<AST::SimplePath
> ();
716 = std::vector
<std::pair
<AST::SimplePath
, AST::UseTreeRebind
>> ();
717 flatten (tree
.get (), sub_paths
, sub_globs
, sub_rebinds
, ctx
);
719 prefix_subpaths (prefix
, sub_paths
, paths
);
720 prefix_subpaths (prefix
, sub_globs
, glob_paths
);
721 prefix_rebinds (prefix
, sub_rebinds
, rebind_paths
);
726 flatten_glob (const AST::UseTreeGlob
&glob
, std::vector
<AST::SimplePath
> &paths
,
727 NameResolutionContext
&ctx
)
729 if (glob
.has_path ())
730 paths
.emplace_back (glob
.get_path ());
734 TopLevel::visit (AST::UseDeclaration
&use
)
736 auto paths
= std::vector
<AST::SimplePath
> ();
737 auto glob_path
= std::vector
<AST::SimplePath
> ();
739 = std::vector
<std::pair
<AST::SimplePath
, AST::UseTreeRebind
>> ();
741 // FIXME: How do we handle `use foo::{self}` imports? Some beforehand cleanup?
742 // How do we handle module imports in general? Should they get added to all
745 const auto &tree
= use
.get_tree ();
746 flatten (tree
.get (), paths
, glob_path
, rebind_path
, this->ctx
);
748 for (auto &path
: paths
)
749 if (!handle_use_dec (path
))
750 rust_error_at (path
.get_final_segment ().get_locus (), ErrorCode::E0433
,
751 "unresolved import %qs", path
.as_string ().c_str ());
753 for (auto &glob
: glob_path
)
754 if (!handle_use_glob (glob
))
755 rust_error_at (glob
.get_final_segment ().get_locus (), ErrorCode::E0433
,
756 "unresolved import %qs", glob
.as_string ().c_str ());
758 for (auto &rebind
: rebind_path
)
759 if (!handle_rebind (rebind
))
760 rust_error_at (rebind
.first
.get_final_segment ().get_locus (),
761 ErrorCode::E0433
, "unresolved import %qs",
762 rebind
.first
.as_string ().c_str ());
765 } // namespace Resolver2_0