From c4820e6cb45407c8d34ebf7fe7a8bdd683f2003f Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 9 Jan 2026 14:40:20 +0300 Subject: [PATCH] resolve: Refactor away the side table `decl_parent_modules` Instead keep parent modules in `DeclData` itself --- .../rustc_resolve/src/build_reduced_graph.rs | 33 ++++++++++--------- compiler/rustc_resolve/src/diagnostics.rs | 27 +++++++-------- compiler/rustc_resolve/src/imports.rs | 9 ++--- compiler/rustc_resolve/src/lib.rs | 31 +++++++---------- 4 files changed, 46 insertions(+), 54 deletions(-) diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 752d8c46beb48..736648c125b69 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -48,14 +48,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { /// and report an error in case of a collision. pub(crate) fn plant_decl_into_local_module( &mut self, - parent: Module<'ra>, ident: Macros20NormalizedIdent, ns: Namespace, decl: Decl<'ra>, ) { - if let Err(old_decl) = self.try_plant_decl_into_local_module(parent, ident, ns, decl, false) - { - self.report_conflict(parent, ident.0, ns, old_decl, decl); + if let Err(old_decl) = self.try_plant_decl_into_local_module(ident, ns, decl, false) { + self.report_conflict(ident.0, ns, old_decl, decl); } } @@ -70,9 +68,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { span: Span, expn_id: LocalExpnId, ) { - let decl = self.arenas.new_def_decl(res, vis.to_def_id(), span, expn_id); + let decl = self.arenas.new_def_decl(res, vis.to_def_id(), span, expn_id, Some(parent)); let ident = Macros20NormalizedIdent::new(ident); - self.plant_decl_into_local_module(parent, ident, ns, decl); + self.plant_decl_into_local_module(ident, ns, decl); } /// Create a name definitinon from the given components, and put it into the extern module. @@ -96,6 +94,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { vis: CmCell::new(vis), span, expansion, + parent_module: Some(parent), }); // Even if underscore names cannot be looked up, we still need to add them to modules, // because they can be fetched by glob imports from those modules, and bring traits @@ -289,7 +288,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let ModChild { ident: _, res, vis, ref reexport_chain } = *ambig_child; let span = child_span(self, reexport_chain, res); let res = res.expect_non_local(); - self.arenas.new_def_decl(res, vis, span, expansion) + self.arenas.new_def_decl(res, vis, span, expansion, Some(parent)) }); // Record primary definitions. @@ -844,7 +843,6 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { ident, local_def_id, vis, - parent, ); } @@ -976,10 +974,10 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { ident: Ident, local_def_id: LocalDefId, vis: Visibility, - parent: Module<'ra>, ) { let sp = item.span; let parent_scope = self.parent_scope; + let parent = parent_scope.module; let expansion = parent_scope.expansion; let (used, module, decl) = if orig_name.is_none() && ident.name == kw::SelfLower { @@ -1009,7 +1007,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { let import = self.r.arenas.alloc_import(ImportData { kind: ImportKind::ExternCrate { source: orig_name, target: ident, id: item.id }, root_id: item.id, - parent_scope: self.parent_scope, + parent_scope, imported_module: CmCell::new(module), has_attributes: !item.attrs.is_empty(), use_span_with_attributes: item.span_with_attributes(), @@ -1057,7 +1055,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { }), }; } - self.r.plant_decl_into_local_module(parent, ident, TypeNS, import_decl); + self.r.plant_decl_into_local_module(ident, TypeNS, import_decl); } /// Constructs the reduced graph for one foreign item. @@ -1300,14 +1298,19 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { } else { Visibility::Restricted(CRATE_DEF_ID) }; - let decl = self.r.arenas.new_def_decl(res, vis.to_def_id(), span, expansion); - self.r.set_decl_parent_module(decl, parent_scope.module); + let decl = self.r.arenas.new_def_decl( + res, + vis.to_def_id(), + span, + expansion, + Some(parent_scope.module), + ); self.r.all_macro_rules.insert(ident.name); if is_macro_export { let import = self.r.arenas.alloc_import(ImportData { kind: ImportKind::MacroExport, root_id: item.id, - parent_scope: self.parent_scope, + parent_scope: ParentScope { module: self.r.graph_root, ..parent_scope }, imported_module: CmCell::new(None), has_attributes: false, use_span_with_attributes: span, @@ -1320,7 +1323,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { }); self.r.import_use_map.insert(import, Used::Other); let import_decl = self.r.new_import_decl(decl, import); - self.r.plant_decl_into_local_module(self.r.graph_root, ident, MacroNS, import_decl); + self.r.plant_decl_into_local_module(ident, MacroNS, import_decl); } else { self.r.check_reserved_macro_name(ident.0, res); self.insert_unused_macro(ident.0, def_id, item.id); diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 7bc08f1de5462..b80011e8c0cb7 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -210,7 +210,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { pub(crate) fn report_conflict( &mut self, - parent: Module<'_>, ident: Ident, ns: Namespace, new_binding: Decl<'ra>, @@ -218,13 +217,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ) { // Error on the second of two conflicting names if old_binding.span.lo() > new_binding.span.lo() { - return self.report_conflict(parent, ident, ns, old_binding, new_binding); + return self.report_conflict(ident, ns, old_binding, new_binding); } - let container = match parent.kind { + let container = match old_binding.parent_module.unwrap().kind { // Avoid using TyCtxt::def_kind_descr in the resolver, because it // indirectly *calls* the resolver, and would cause a query cycle. - ModuleKind::Def(kind, _, _) => kind.descr(parent.def_id()), + ModuleKind::Def(kind, def_id, _) => kind.descr(def_id), ModuleKind::Block => "block", }; @@ -2034,15 +2033,17 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { help_msgs.push(format!("use `::{ident}` to refer to this {thing} unambiguously")) } - if let Scope::ModuleNonGlobs(module, _) | Scope::ModuleGlobs(module, _) = scope { - if module == self.graph_root { - help_msgs.push(format!( - "use `crate::{ident}` to refer to this {thing} unambiguously" - )); - } else if module != self.empty_module && module.is_normal() { - help_msgs.push(format!( - "use `self::{ident}` to refer to this {thing} unambiguously" - )); + if kind != AmbiguityKind::GlobVsGlob { + if let Scope::ModuleNonGlobs(module, _) | Scope::ModuleGlobs(module, _) = scope { + if module == self.graph_root { + help_msgs.push(format!( + "use `crate::{ident}` to refer to this {thing} unambiguously" + )); + } else if module.is_normal() { + help_msgs.push(format!( + "use `self::{ident}` to refer to this {thing} unambiguously" + )); + } } } diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 4447374b8b06c..e525abd00f998 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -340,6 +340,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { span: import.span, vis: CmCell::new(vis), expansion: import.parent_scope.expansion, + parent_module: Some(import.parent_scope.module), }) } @@ -409,15 +410,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { /// and return existing declaration if there is a collision. pub(crate) fn try_plant_decl_into_local_module( &mut self, - module: Module<'ra>, ident: Macros20NormalizedIdent, ns: Namespace, decl: Decl<'ra>, warn_ambiguity: bool, ) -> Result<(), Decl<'ra>> { + let module = decl.parent_module.unwrap(); let res = decl.res(); self.check_reserved_macro_name(ident.0, res); - self.set_decl_parent_module(decl, module); // Even if underscore names cannot be looked up, we still need to add them to modules, // because they can be fetched by glob imports from those modules, and bring traits // into scope both directly and through glob imports. @@ -511,7 +511,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { if self.is_accessible_from(binding.vis(), scope) { let import_decl = self.new_import_decl(binding, *import); let _ = self.try_plant_decl_into_local_module( - import.parent_scope.module, ident, key.ns, import_decl, @@ -535,7 +534,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { self.per_ns(|this, ns| { let module = import.parent_scope.module; let ident = Macros20NormalizedIdent::new(target); - let _ = this.try_plant_decl_into_local_module(module, ident, ns, dummy_decl, false); + let _ = this.try_plant_decl_into_local_module(ident, ns, dummy_decl, false); // Don't remove underscores from `single_imports`, they were never added. if target.name != kw::Underscore { let key = BindingKey::new(ident, ns); @@ -916,7 +915,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // We need the `target`, `source` can be extracted. let import_decl = this.new_import_decl(binding, import); this.get_mut_unchecked().plant_decl_into_local_module( - parent, Macros20NormalizedIdent::new(target), ns, import_decl, @@ -1542,7 +1540,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { .and_then(|r| r.binding()) .is_some_and(|binding| binding.warn_ambiguity_recursive()); let _ = self.try_plant_decl_into_local_module( - import.parent_scope.module, key.ident, key.ns, import_decl, diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index c4c1e06f94ae2..2c22aacb32412 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -67,7 +67,6 @@ use rustc_metadata::creader::CStore; use rustc_middle::metadata::{AmbigModChild, ModChild, Reexport}; use rustc_middle::middle::privacy::EffectiveVisibilities; use rustc_middle::query::Providers; -use rustc_middle::span_bug; use rustc_middle::ty::{ self, DelegationFnSig, DelegationInfo, Feed, MainDefinition, RegisteredTools, ResolverAstLowering, ResolverGlobalCtxt, TyCtxt, TyCtxtFeed, Visibility, @@ -812,6 +811,7 @@ struct DeclData<'ra> { expansion: LocalExpnId, span: Span, vis: CmCell>, + parent_module: Option>, } /// All name declarations are unique and allocated on a same arena, @@ -922,7 +922,6 @@ struct AmbiguityError<'ra> { ident: Ident, b1: Decl<'ra>, b2: Decl<'ra>, - // `empty_module` in module scope serves as an unknown module here. scope1: Scope<'ra>, scope2: Scope<'ra>, warning: Option, @@ -1186,7 +1185,6 @@ pub struct Resolver<'ra, 'tcx> { local_module_map: FxIndexMap>, /// Lazily populated cache of modules loaded from external crates. extern_module_map: CacheRefCell>>, - decl_parent_modules: FxHashMap, Module<'ra>>, /// Maps glob imports to the names of items actually imported. glob_map: FxIndexMap>, @@ -1349,6 +1347,7 @@ impl<'ra> ResolverArenas<'ra> { vis: Visibility, span: Span, expansion: LocalExpnId, + parent_module: Option>, ) -> Decl<'ra> { self.alloc_decl(DeclData { kind: DeclKind::Def(res), @@ -1357,11 +1356,12 @@ impl<'ra> ResolverArenas<'ra> { vis: CmCell::new(vis), span, expansion, + parent_module, }) } fn new_pub_def_decl(&'ra self, res: Res, span: Span, expn_id: LocalExpnId) -> Decl<'ra> { - self.new_def_decl(res, Visibility::Public, span, expn_id) + self.new_def_decl(res, Visibility::Public, span, expn_id, None) } fn new_module( @@ -1616,7 +1616,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { local_module_map, extern_module_map: Default::default(), block_map: Default::default(), - decl_parent_modules: FxHashMap::default(), ast_transform_scopes: FxHashMap::default(), glob_map: Default::default(), @@ -2071,8 +2070,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ident, b1: used_decl, b2, - scope1: Scope::ModuleGlobs(self.empty_module, None), - scope2: Scope::ModuleGlobs(self.empty_module, None), + scope1: Scope::ModuleGlobs(used_decl.parent_module.unwrap(), None), + scope2: Scope::ModuleGlobs(b2.parent_module.unwrap(), None), warning: if warn_ambiguity { Some(AmbiguityWarning::GlobImport) } else { None }, }; if !self.matches_previous_ambiguity_error(&ambiguity_error) { @@ -2237,14 +2236,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { vis.is_accessible_from(module.nearest_parent_mod(), self.tcx) } - fn set_decl_parent_module(&mut self, decl: Decl<'ra>, module: Module<'ra>) { - if let Some(old_module) = self.decl_parent_modules.insert(decl, module) { - if module != old_module { - span_bug!(decl.span, "parent module is reset for a name declaration"); - } - } - } - fn disambiguate_macro_rules_vs_modularized( &self, macro_rules: Decl<'ra>, @@ -2254,13 +2245,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // is disambiguated to mitigate regressions from macro modularization. // Scoping for `macro_rules` behaves like scoping for `let` at module level, in general. // - // panic on index should be impossible, the only name_bindings passed in should be from + // Panic on unwrap should be impossible, the only name_bindings passed in should be from // `resolve_ident_in_scope_set` which will always refer to a local binding from an - // import or macro definition - let macro_rules = &self.decl_parent_modules[¯o_rules]; - let modularized = &self.decl_parent_modules[&modularized]; + // import or macro definition. + let macro_rules = macro_rules.parent_module.unwrap(); + let modularized = modularized.parent_module.unwrap(); macro_rules.nearest_parent_mod() == modularized.nearest_parent_mod() - && modularized.is_ancestor_of(*macro_rules) + && modularized.is_ancestor_of(macro_rules) } fn extern_prelude_get_item<'r>(