resolve: Refactor away the side table decl_parent_modules

Instead keep parent modules in `DeclData` itself
This commit is contained in:
Vadim Petrochenkov 2026-01-09 14:40:20 +03:00
parent 9b81629631
commit c4820e6cb4
4 changed files with 46 additions and 54 deletions

View file

@ -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);

View file

@ -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"
));
}
}
}

View file

@ -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,

View file

@ -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<Visibility<DefId>>,
parent_module: Option<Module<'ra>>,
}
/// 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<AmbiguityWarning>,
@ -1186,7 +1185,6 @@ pub struct Resolver<'ra, 'tcx> {
local_module_map: FxIndexMap<LocalDefId, Module<'ra>>,
/// Lazily populated cache of modules loaded from external crates.
extern_module_map: CacheRefCell<FxIndexMap<DefId, Module<'ra>>>,
decl_parent_modules: FxHashMap<Decl<'ra>, Module<'ra>>,
/// Maps glob imports to the names of items actually imported.
glob_map: FxIndexMap<LocalDefId, FxIndexSet<Symbol>>,
@ -1349,6 +1347,7 @@ impl<'ra> ResolverArenas<'ra> {
vis: Visibility<DefId>,
span: Span,
expansion: LocalExpnId,
parent_module: Option<Module<'ra>>,
) -> 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[&macro_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>(