From 02640f9d5985f87b4dccaf987e6c34d2b7a40fdd Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 18 Aug 2023 16:53:06 +0800 Subject: [PATCH] resolve: Make bindings for crate roots unique instead of creating a new every time `crate` or `$crate` is used --- compiler/rustc_resolve/src/ident.rs | 4 +--- compiler/rustc_resolve/src/lib.rs | 24 ++++++++++++++++++++++-- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 21bc54ede4d..7412b2d0581 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -833,9 +833,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { if ns == TypeNS { if ident.name == kw::Crate || ident.name == kw::DollarCrate { let module = self.resolve_crate_root(ident); - let binding = (module, Visibility::Public, module.span, LocalExpnId::ROOT) - .to_name_binding(self.arenas); - return Ok(binding); + return Ok(self.module_self_bindings[&module]); } else if ident.name == kw::Super || ident.name == kw::SelfLower { // FIXME: Implement these with renaming requirements so that e.g. // `use super;` doesn't work, but `use super as name;` does. diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 6c63abe47fb..a2ee6c7b529 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -519,7 +519,7 @@ struct ModuleData<'a> { /// All modules are unique and allocated on a same arena, /// so we can use referential equality to compare them. -#[derive(Clone, Copy, PartialEq)] +#[derive(Clone, Copy, PartialEq, Eq, Hash)] #[rustc_pass_by_value] struct Module<'a>(Interned<'a, ModuleData<'a>>); @@ -1007,6 +1007,9 @@ pub struct Resolver<'a, 'tcx> { builtin_types_bindings: FxHashMap>, builtin_attrs_bindings: FxHashMap>, registered_tool_bindings: FxHashMap>, + /// Binding for implicitly declared names that come with a module, + /// like `self` (not yet used), or `crate`/`$crate` (for root modules). + module_self_bindings: FxHashMap, NameBinding<'a>>, used_extern_options: FxHashSet, macro_names: FxHashSet, @@ -1122,6 +1125,7 @@ impl<'a> ResolverArenas<'a> { span: Span, no_implicit_prelude: bool, module_map: &mut FxHashMap>, + module_self_bindings: &mut FxHashMap, NameBinding<'a>>, ) -> Module<'a> { let module = Module(Interned::new_unchecked(self.modules.alloc(ModuleData::new( parent, @@ -1136,6 +1140,9 @@ impl<'a> ResolverArenas<'a> { } if let Some(def_id) = def_id { module_map.insert(def_id, module); + let vis = ty::Visibility::::Public; + let binding = (module, vis, module.span, LocalExpnId::ROOT).to_name_binding(self); + module_self_bindings.insert(module, binding); } module } @@ -1247,6 +1254,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { ) -> Resolver<'a, 'tcx> { let root_def_id = CRATE_DEF_ID.to_def_id(); let mut module_map = FxHashMap::default(); + let mut module_self_bindings = FxHashMap::default(); let graph_root = arenas.new_module( None, ModuleKind::Def(DefKind::Mod, root_def_id, kw::Empty), @@ -1254,6 +1262,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { crate_span, attr::contains_name(attrs, sym::no_implicit_prelude), &mut module_map, + &mut module_self_bindings, ); let empty_module = arenas.new_module( None, @@ -1262,6 +1271,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { DUMMY_SP, true, &mut FxHashMap::default(), + &mut FxHashMap::default(), ); let mut visibilities = FxHashMap::default(); @@ -1368,6 +1378,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { (*ident, binding) }) .collect(), + module_self_bindings, used_extern_options: Default::default(), macro_names: FxHashSet::default(), @@ -1437,7 +1448,16 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { no_implicit_prelude: bool, ) -> Module<'a> { let module_map = &mut self.module_map; - self.arenas.new_module(parent, kind, expn_id, span, no_implicit_prelude, module_map) + let module_self_bindings = &mut self.module_self_bindings; + self.arenas.new_module( + parent, + kind, + expn_id, + span, + no_implicit_prelude, + module_map, + module_self_bindings, + ) } fn next_node_id(&mut self) -> NodeId {