From a07cc548e43869de0c4aa047242c182757a750af Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 8 May 2026 14:41:27 +0300 Subject: [PATCH] resolve: Module-related refactorings --- .../rustc_resolve/src/build_reduced_graph.rs | 11 +- compiler/rustc_resolve/src/diagnostics.rs | 41 ++-- compiler/rustc_resolve/src/ident.rs | 24 +-- compiler/rustc_resolve/src/imports.rs | 4 +- compiler/rustc_resolve/src/late.rs | 2 +- .../rustc_resolve/src/late/diagnostics.rs | 13 +- compiler/rustc_resolve/src/lib.rs | 202 ++++++++++-------- compiler/rustc_resolve/src/macros.rs | 10 +- 8 files changed, 164 insertions(+), 143 deletions(-) diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 61da931df4d5d..4fb274188a8cf 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -253,7 +253,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { match vis.kind { ast::VisibilityKind::Public => Ok(Visibility::Public), ast::VisibilityKind::Inherited => { - Ok(match parent_scope.module.kind { + Ok(match parent_scope.module.expect_local().kind { // Any inherited visibility resolved directly inside an enum or trait // (i.e. variants, fields, and trait items) inherits from the visibility // of the enum or trait. @@ -535,7 +535,7 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> { root_id: NodeId, vis: Visibility, ) { - let current_module = self.parent_scope.module; + let current_module = self.parent_scope.module.expect_local(); let import = self.r.arenas.alloc_import(ImportData { kind, parent_scope: self.parent_scope, @@ -560,7 +560,7 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> { if target.name != kw::Underscore { self.r.per_ns(|this, ns| { let key = BindingKey::new(IdentKey::new(target), ns); - this.resolution_or_default(current_module, key, target.span) + this.resolution_or_default(current_module.to_module(), key, target.span) .borrow_mut(this) .single_imports .insert(import); @@ -1136,7 +1136,7 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> { if let Some(Attribute::Parsed(AttributeKind::MacroUse { span, arguments })) = AttributeParser::parse_limited(self.r.tcx.sess, &item.attrs, &[sym::macro_use]) { - if self.parent_scope.module.parent.is_some() { + if self.parent_scope.module.expect_local().parent.is_some() { self.r .dcx() .emit_err(errors::ExternCrateLoadingMacroNotAtCrateRoot { span: item.span }); @@ -1247,7 +1247,8 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> { /// directly into its parent scope's module. pub(crate) fn visit_invoc_in_module(&mut self, id: NodeId) -> MacroRulesScopeRef<'ra> { let invoc_id = self.visit_invoc(id); - self.parent_scope.module.unexpanded_invocations.borrow_mut(self.r).insert(invoc_id); + let module = self.parent_scope.module.expect_local(); + module.unexpanded_invocations.borrow_mut(self.r).insert(invoc_id); self.r.arenas.alloc_macro_rules_scope(MacroRulesScope::Invocation(invoc_id)) } diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 5e52ebcc3f194..4ba6106bf09e6 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -240,7 +240,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { return self.report_conflict(ident, ns, new_binding, old_binding); } - let container = match old_binding.parent_module.unwrap().kind { + let container = match old_binding.parent_module.unwrap().expect_local().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, def_id, _, _) => kind.descr(def_id), @@ -2597,7 +2597,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let module = module.to_module(); current_module.is_ancestor_of(module) && current_module != module }) - .flat_map(|(_, module)| module.kind.name()), + .flat_map(|(_, module)| module.name()), ) .chain( self.extern_module_map @@ -2607,7 +2607,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let module = module.to_module(); current_module.is_ancestor_of(module) && current_module != module }) - .flat_map(|(_, module)| module.kind.name()), + .flat_map(|(_, module)| module.name()), ) .filter(|c| !c.to_string().is_empty()) .collect::>(); @@ -2631,8 +2631,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ) -> (String, String, Option) { let is_last = failed_segment_idx == path.len() - 1; let ns = if is_last { opt_ns.unwrap_or(TypeNS) } else { TypeNS }; - let module_res = match module { - Some(ModuleOrUniformRoot::Module(module)) => module.res(), + let module_def_id = match module { + Some(ModuleOrUniformRoot::Module(module)) => module.opt_def_id(), _ => None, }; let scope = match &path[..failed_segment_idx] { @@ -2647,7 +2647,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { }; let message = format!("cannot find `{ident}` in {scope}"); - if module_res == self.graph_root.res() { + if module_def_id == Some(CRATE_DEF_ID.to_def_id()) { let is_mod = |res| matches!(res, Res::Def(DefKind::Mod, _)); let mut candidates = self.lookup_import_candidates(ident, TypeNS, parent_scope, is_mod); candidates @@ -3145,7 +3145,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { if !kinds.contains(MacroKinds::BANG) { return None; } - let module_name = crate_module.kind.name().unwrap_or(kw::Crate); + let module_name = crate_module.name().unwrap_or(kw::Crate); let import_snippet = match import.kind { ImportKind::Single { source, target, .. } if source != target => { format!("{source} as {target}") @@ -3290,20 +3290,23 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { return cached; } visited.insert(parent_module, false); - let m = r.expect_module(parent_module); let mut res = false; - for importer in m.glob_importers.borrow().iter() { - if let Some(next_parent_module) = importer.parent_scope.module.opt_def_id() { - if next_parent_module == module - || comes_from_same_module_for_glob( - r, - next_parent_module, - module, - visited, - ) + let m = r.expect_module(parent_module); + if m.is_local() { + for importer in m.glob_importers.borrow().iter() { + if let Some(next_parent_module) = importer.parent_scope.module.opt_def_id() { - res = true; - break; + if next_parent_module == module + || comes_from_same_module_for_glob( + r, + next_parent_module, + module, + visited, + ) + { + res = true; + break; + } } } } diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index b33b77d43999d..49461651412b2 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -643,10 +643,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { Err(ControlFlow::Break(..)) => return decl, } } - Scope::ModuleGlobs(module, _) - if let ModuleKind::Def(_, def_id, _, _) = module.kind - && !def_id.is_local() => - { + Scope::ModuleGlobs(module, _) if !module.is_local() => { // Fast path: external module decoding only creates non-glob declarations. Err(Determined) } @@ -699,9 +696,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } Scope::MacroUsePrelude => match self.macro_use_prelude.get(&ident.name).cloned() { Some(decl) => Ok(decl), - None => Err(Determinacy::determined( - self.graph_root.unexpanded_invocations.borrow().is_empty(), - )), + None => Err(Determinacy::determined(!self.graph_root.has_unexpanded_invocations())), }, Scope::BuiltinAttrs => match self.builtin_attr_decls.get(&ident.name) { Some(decl) => Ok(*decl), @@ -714,9 +709,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { finalize.is_some(), ) { Some(decl) => Ok(decl), - None => Err(Determinacy::determined( - self.graph_root.unexpanded_invocations.borrow().is_empty(), - )), + None => { + Err(Determinacy::determined(!self.graph_root.has_unexpanded_invocations())) + } } } Scope::ExternPreludeFlags => { @@ -1126,6 +1121,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { return if accessible { Ok(binding) } else { Err(ControlFlow::Break(Determined)) }; } + // In extern modules everything is determined from the start. + if !module.is_local() { + return Err(ControlFlow::Continue(Determined)); + }; + // Check if one of single imports can still define the name, block if it can. if self.reborrow().single_import_can_define_name( &resolution, @@ -1139,7 +1139,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } // Check if one of unexpanded macros can still define the name. - if !module.unexpanded_invocations.borrow().is_empty() { + if module.has_unexpanded_invocations() { return Err(ControlFlow::Continue(Undetermined)); } @@ -1223,7 +1223,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // scopes we return `Undetermined` with `ControlFlow::Continue`. // Check if one of unexpanded macros can still define the name, // if it can then our "no resolution" result is not determined and can be invalidated. - if !module.unexpanded_invocations.borrow().is_empty() { + if module.has_unexpanded_invocations() { return Err(ControlFlow::Continue(Undetermined)); } diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index b16347af7ba0c..3b948f2bed194 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -1790,7 +1790,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } // Add to module's glob_importers - module.glob_importers.borrow_mut_unchecked().push(import); + if module.is_local() { + module.glob_importers.borrow_mut_unchecked().push(import); + } // Ensure that `resolutions` isn't borrowed during `try_define`, // since it might get updated via a glob cycle. diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 3337a4626b040..79c95fe713ed6 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1477,7 +1477,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { // During late resolution we only track the module component of the parent scope, // although it may be useful to track other components as well for diagnostics. let graph_root = resolver.graph_root; - let parent_scope = ParentScope::module(graph_root.to_module(), resolver.arenas); + let parent_scope = ParentScope::module(graph_root, resolver.arenas); let start_rib_kind = RibKind::Module(graph_root); LateResolutionVisitor { r: resolver, diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 6f86759d46c5f..d7ce4f731e21b 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -38,8 +38,8 @@ use crate::late::{ }; use crate::ty::fast_reject::SimplifiedType; use crate::{ - Finalize, Module, ModuleKind, ModuleOrUniformRoot, ParentScope, PathResult, PathSource, Res, - Resolver, ScopeSet, Segment, errors, path_names_to_string, + Finalize, Module, ModuleOrUniformRoot, ParentScope, PathResult, PathSource, Res, Resolver, + ScopeSet, Segment, errors, path_names_to_string, }; /// A field or associated item from self type suggested in case of resolution failure. @@ -1698,7 +1698,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { && let TyKind::Path(_, self_ty_path) = &self_ty.kind && let PathResult::Module(ModuleOrUniformRoot::Module(module)) = self.resolve_path(&Segment::from_path(self_ty_path), Some(TypeNS), None, source) - && let ModuleKind::Def(DefKind::Trait, ..) = module.kind + && module.def_kind() == Some(DefKind::Trait) && trait_ref.path.span == span && let PathSource::Trait(_) = source && let Some(Res::Def(DefKind::Struct | DefKind::Enum | DefKind::Union, _)) = res @@ -3014,12 +3014,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { fn find_module(&self, def_id: DefId) -> Option<(Module<'ra>, ImportSuggestion)> { let mut result = None; let mut seen_modules = FxHashSet::default(); - let root_did = self.r.graph_root.def_id(); - let mut worklist = vec![( - self.r.graph_root.to_module(), - ThinVec::new(), - root_did.is_local() || !self.r.tcx.is_doc_hidden(root_did), - )]; + let mut worklist = vec![(self.r.graph_root.to_module(), ThinVec::new(), true)]; while let Some((in_module, path_segments, doc_visible)) = worklist.pop() { // abort if the module is already found diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 879a4dd3983a6..44a72fec56b95 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -61,7 +61,6 @@ use rustc_hir::definitions::{PerParentDisambiguatorState, PerParentDisambiguator use rustc_hir::{PrimTy, TraitCandidate, find_attr}; use rustc_index::bit_set::DenseBitSet; use rustc_metadata::creader::CStore; -use rustc_middle::bug; use rustc_middle::metadata::{AmbigModChild, ModChild, Reexport}; use rustc_middle::middle::privacy::EffectiveVisibilities; use rustc_middle::query::Providers; @@ -69,6 +68,7 @@ use rustc_middle::ty::{ self, DelegationInfo, MainDefinition, RegisteredTools, ResolverAstLowering, ResolverGlobalCtxt, TyCtxt, TyCtxtFeed, Visibility, }; +use rustc_middle::{bug, span_bug}; use rustc_session::config::CrateType; use rustc_session::lint::builtin::PRIVATE_MACRO_USE; use rustc_span::hygiene::{ExpnId, LocalExpnId, MacroKind, SyntaxContext, Transparency}; @@ -172,9 +172,9 @@ struct ParentScope<'ra> { impl<'ra> ParentScope<'ra> { /// Creates a parent scope with the passed argument used as the module scope component, /// and other scope components set to default empty values. - fn module(module: Module<'ra>, arenas: &'ra ResolverArenas<'ra>) -> ParentScope<'ra> { + fn module(module: LocalModule<'ra>, arenas: &'ra ResolverArenas<'ra>) -> ParentScope<'ra> { ParentScope { - module, + module: module.to_module(), expansion: LocalExpnId::ROOT, macro_rules: arenas.alloc_macro_rules_scope(MacroRulesScope::Empty), derives: &[], @@ -547,20 +547,23 @@ enum ModuleKind { } impl ModuleKind { - /// Get name of the module. - fn name(&self) -> Option { - match *self { - ModuleKind::Block => None, - ModuleKind::Def(.., name) => name, - } - } - fn opt_def_id(&self) -> Option { match self { ModuleKind::Def(_, def_id, _, _) => Some(*def_id), _ => None, } } + + fn def_id(&self) -> DefId { + self.opt_def_id().expect("`Module::def_id` is called on a block module") + } + + fn is_local(&self) -> bool { + match self { + ModuleKind::Def(_, def_id, ..) => def_id.is_local(), + ModuleKind::Block => true, + } + } } /// Combination of a symbol and its macros 2.0 normalized hygiene context. @@ -723,11 +726,16 @@ impl<'ra> ModuleData<'ra> { expansion: ExpnId, span: Span, no_implicit_prelude: bool, - self_decl: Option>, + vis: Visibility, + arenas: &'ra ResolverArenas<'ra>, ) -> Self { - let is_foreign = match kind { - ModuleKind::Def(_, def_id, _, _) => !def_id.is_local(), - ModuleKind::Block => false, + let is_foreign = !kind.is_local(); + let self_decl = match kind { + ModuleKind::Def(def_kind, def_id, ..) => { + let expn_id = expansion.as_local().unwrap_or(LocalExpnId::ROOT); + Some(arenas.new_def_decl(Res::Def(def_kind, def_id), vis, span, expn_id, parent)) + } + ModuleKind::Block => None, }; ModuleData { parent, @@ -746,12 +754,28 @@ impl<'ra> ModuleData<'ra> { } } + /// Get name of the module. + fn name(&self) -> Option { + match self.kind { + ModuleKind::Block => None, + ModuleKind::Def(.., name) => name, + } + } + fn opt_def_id(&self) -> Option { self.kind.opt_def_id() } fn def_id(&self) -> DefId { - self.opt_def_id().expect("`ModuleData::def_id` is called on a block module") + self.kind.def_id() + } + + fn is_local(&self) -> bool { + self.kind.is_local() + } + + fn has_unexpanded_invocations(&self) -> bool { + !self.unexpanded_invocations.borrow().is_empty() } fn res(&self) -> Option { @@ -760,6 +784,13 @@ impl<'ra> ModuleData<'ra> { _ => None, } } + + fn def_kind(&self) -> Option { + match self.kind { + ModuleKind::Def(def_kind, ..) => Some(def_kind), + ModuleKind::Block => None, + } + } } impl<'ra> Module<'ra> { @@ -813,16 +844,16 @@ impl<'ra> Module<'ra> { // `self` resolves to the first module ancestor that `is_normal`. fn is_normal(self) -> bool { - matches!(self.kind, ModuleKind::Def(DefKind::Mod, _, _, _)) + self.def_kind() == Some(DefKind::Mod) } fn is_trait(self) -> bool { - matches!(self.kind, ModuleKind::Def(DefKind::Trait, _, _, _)) + matches!(self.def_kind(), Some(DefKind::Trait)) } fn nearest_item_scope(self) -> Module<'ra> { - match self.kind { - ModuleKind::Def(DefKind::Enum | DefKind::Trait, ..) => { + match self.def_kind() { + Some(DefKind::Enum | DefKind::Trait) => { self.parent.expect("enum or trait module without a parent") } _ => self, @@ -862,7 +893,7 @@ impl<'ra> Module<'ra> { fn expect_local(self) -> LocalModule<'ra> { match self.kind { ModuleKind::Def(_, def_id, _, _) if !def_id.is_local() => { - panic!("`Module::expect_local` is called on a non-local module: {self:?}") + span_bug!(self.span, "unexpected extern module: {self:?}") } ModuleKind::Def(..) | ModuleKind::Block => LocalModule(self.0), } @@ -873,19 +904,49 @@ impl<'ra> Module<'ra> { match self.kind { ModuleKind::Def(_, def_id, _, _) if !def_id.is_local() => ExternModule(self.0), ModuleKind::Def(..) | ModuleKind::Block => { - panic!("`Module::expect_extern` is called on a local module: {self:?}") + span_bug!(self.span, "unexpected local module: {self:?}") } } } } impl<'ra> LocalModule<'ra> { + fn new( + parent: Option>, + kind: ModuleKind, + vis: Visibility, + expn_id: ExpnId, + span: Span, + no_implicit_prelude: bool, + arenas: &'ra ResolverArenas<'ra>, + ) -> LocalModule<'ra> { + assert!(kind.is_local()); + let parent = parent.map(|m| m.to_module()); + let data = ModuleData::new(parent, kind, expn_id, span, no_implicit_prelude, vis, arenas); + LocalModule(Interned::new_unchecked(arenas.modules.alloc(data))) + } + fn to_module(self) -> Module<'ra> { Module(self.0) } } impl<'ra> ExternModule<'ra> { + fn new( + parent: Option>, + kind: ModuleKind, + vis: Visibility, + expn_id: ExpnId, + span: Span, + no_implicit_prelude: bool, + arenas: &'ra ResolverArenas<'ra>, + ) -> ExternModule<'ra> { + assert!(!kind.is_local()); + let parent = parent.map(|m| m.to_module()); + let data = ModuleData::new(parent, kind, expn_id, span, no_implicit_prelude, vis, arenas); + ExternModule(Interned::new_unchecked(arenas.modules.alloc(data))) + } + fn to_module(self) -> Module<'ra> { Module(self.0) } @@ -917,9 +978,9 @@ impl<'ra> std::ops::Deref for ExternModule<'ra> { impl<'ra> fmt::Debug for Module<'ra> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self.kind { - ModuleKind::Block => write!(f, "block"), - ModuleKind::Def(..) => write!(f, "{:?}", self.res()), + match self.res() { + None => write!(f, "block"), + Some(res) => write!(f, "{:?}", res), } } } @@ -1208,8 +1269,7 @@ impl<'ra> DeclData<'ra> { fn determined(&self) -> bool { match &self.kind { DeclKind::Import { source_decl, import, .. } if import.is_glob() => { - import.parent_scope.module.unexpanded_invocations.borrow().is_empty() - && source_decl.determined() + !import.parent_scope.module.has_unexpanded_invocations() && source_decl.determined() } _ => true, } @@ -1538,31 +1598,6 @@ impl<'ra> ResolverArenas<'ra> { self.new_def_decl(res, Visibility::Public, span, expn_id, None) } - fn new_module( - &'ra self, - parent: Option>, - kind: ModuleKind, - vis: Visibility, - expn_id: ExpnId, - span: Span, - no_implicit_prelude: bool, - ) -> Module<'ra> { - let self_decl = match kind { - ModuleKind::Def(def_kind, def_id, _, _) => { - let expn_id = expn_id.as_local().unwrap_or(LocalExpnId::ROOT); - Some(self.new_def_decl(Res::Def(def_kind, def_id), vis, span, expn_id, parent)) - } - ModuleKind::Block => None, - }; - Module(Interned::new_unchecked(self.modules.alloc(ModuleData::new( - parent, - kind, - expn_id, - span, - no_implicit_prelude, - self_decl, - )))) - } fn alloc_decl(&'ra self, data: DeclData<'ra>) -> Decl<'ra> { Interned::new_unchecked(self.dropless.alloc(data)) } @@ -1724,26 +1759,26 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { arenas: &'ra ResolverArenas<'ra>, ) -> Resolver<'ra, 'tcx> { let root_def_id = CRATE_DEF_ID.to_def_id(); - let graph_root = arenas.new_module( + let graph_root = LocalModule::new( None, ModuleKind::Def(DefKind::Mod, root_def_id, CRATE_NODE_ID, None), Visibility::Public, ExpnId::root(), crate_span, attr::contains_name(attrs, sym::no_implicit_prelude), + arenas, ); - let graph_root = graph_root.expect_local(); let local_modules = vec![graph_root]; let local_module_map = FxIndexMap::from_iter([(CRATE_DEF_ID, graph_root)]); - let empty_module = arenas.new_module( + let empty_module = LocalModule::new( None, ModuleKind::Def(DefKind::Mod, root_def_id, CRATE_NODE_ID, None), Visibility::Public, ExpnId::root(), DUMMY_SP, true, + arenas, ); - let empty_module = empty_module.expect_local(); let mut node_id_to_def_id = NodeMap::default(); let crate_feed = tcx.create_local_crate_def_id(crate_span); @@ -1825,7 +1860,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { .. }; - let root_parent_scope = ParentScope::module(graph_root.to_module(), resolver.arenas); + let root_parent_scope = ParentScope::module(graph_root, resolver.arenas); resolver.invocation_parent_scopes.insert(LocalExpnId::ROOT, root_parent_scope); resolver.feed_visibility(crate_feed, Visibility::Public); @@ -1840,13 +1875,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { span: Span, no_implicit_prelude: bool, ) -> LocalModule<'ra> { - let parent = parent.map(|m| m.to_module()); let vis = kind.opt_def_id().map_or(Visibility::Public, |def_id| self.tcx.visibility(def_id)); - let module = self - .arenas - .new_module(parent, kind, vis, expn_id, span, no_implicit_prelude) - .expect_local(); + let module = + LocalModule::new(parent, kind, vis, expn_id, span, no_implicit_prelude, self.arenas); self.local_modules.push(module); if let Some(def_id) = module.opt_def_id() { self.local_module_map.insert(def_id.expect_local(), module); @@ -1862,14 +1894,17 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { span: Span, no_implicit_prelude: bool, ) -> ExternModule<'ra> { - let parent = parent.map(|m| m.to_module()); - let vis = - kind.opt_def_id().map_or(Visibility::Public, |def_id| self.tcx.visibility(def_id)); - let module = self - .arenas - .new_module(parent, kind, vis, expn_id, span, no_implicit_prelude) - .expect_extern(); - self.extern_module_map.borrow_mut().insert(module.def_id(), module); + let def_id = kind.def_id(); + let module = ExternModule::new( + parent, + kind, + self.tcx.visibility(def_id), + expn_id, + span, + no_implicit_prelude, + self.arenas, + ); + self.extern_module_map.borrow_mut().insert(def_id, module); module } @@ -2220,7 +2255,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // Do not report the lint if the macro name resolves in stdlib prelude // even without the problematic `macro_use` import. let found_in_stdlib_prelude = self.prelude.is_some_and(|prelude| { - let empty_module = self.empty_module.to_module(); + let empty_module = self.empty_module; let arenas = self.arenas; self.cm() .maybe_resolve_ident_in_module( @@ -2341,7 +2376,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { "resolve_crate_root({:?}): got module {:?} ({:?}) (ident.span = {:?})", ident, module, - module.kind.name(), + module.name(), ident.span ); module @@ -2586,12 +2621,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { return; } - let module = self.graph_root.to_module(); + let module = self.graph_root; let ident = Ident::with_dummy_span(sym::main); let parent_scope = &ParentScope::module(module, self.arenas); let Ok(name_binding) = self.cm().maybe_resolve_ident_in_module( - ModuleOrUniformRoot::Module(module), + ModuleOrUniformRoot::Module(module.to_module()), ident, ValueNS, parent_scope, @@ -2685,22 +2720,9 @@ fn path_names_to_string(path: &Path) -> String { /// A somewhat inefficient routine to obtain the name of a module. fn module_to_string(mut module: Module<'_>) -> Option { let mut names = Vec::new(); - loop { - if let ModuleKind::Def(.., name) = module.kind { - if let Some(parent) = module.parent { - // `unwrap` is safe: the presence of a parent means it's not the crate root. - names.push(name.unwrap()); - module = parent - } else { - break; - } - } else { - names.push(sym::opaque_module_name_placeholder); - let Some(parent) = module.parent else { - return None; - }; - module = parent; - } + while let Some(parent) = module.parent { + names.push(module.name().unwrap_or(sym::opaque_module_name_placeholder)); + module = parent; } if names.is_empty() { return None; diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index f4464138ef1fc..206e32f61b485 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -175,10 +175,7 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> { fn resolve_dollar_crates(&self) { hygiene::update_dollar_crate_names(|ctxt| { let ident = Ident::new(kw::DollarCrate, DUMMY_SP.with_ctxt(ctxt)); - match self.resolve_crate_root(ident).kind { - ModuleKind::Def(.., name) if let Some(name) = name => name, - _ => kw::Crate, - } + self.resolve_crate_root(ident).name().unwrap_or(kw::Crate) }); } @@ -193,7 +190,8 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> { let output_macro_rules_scope = collect_definitions(self, fragment, parent_scope); self.output_macro_rules_scopes.insert(expansion, output_macro_rules_scope); - parent_scope.module.unexpanded_invocations.borrow_mut(self).remove(&expansion); + let module = parent_scope.module.expect_local(); + module.unexpanded_invocations.borrow_mut(self).remove(&expansion); if let Some(unexpanded_invocations) = self.impl_unexpanded_invocations.get_mut(&self.invocation_parent(expansion)) { @@ -523,7 +521,7 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> { star_span: Span, ) -> Result)>, Indeterminate> { let target_trait = self.expect_module(trait_def_id); - if !target_trait.unexpanded_invocations.borrow().is_empty() { + if target_trait.has_unexpanded_invocations() { return Err(Indeterminate); } // FIXME: Instead of waiting try generating all trait methods, and pruning