From 72e9ddc07f0382ab024ad2176b694006173eb27e Mon Sep 17 00:00:00 2001 From: LorrensP-2158466 Date: Mon, 6 Jul 2026 09:13:46 +0200 Subject: [PATCH] Wrap the resolver arenas into `WorkerLocal` in preperation of parallel import resolution. --- compiler/rustc_interface/src/passes.rs | 2 +- .../rustc_resolve/src/build_reduced_graph.rs | 93 ++++++++----------- compiler/rustc_resolve/src/def_collector.rs | 2 +- compiler/rustc_resolve/src/imports.rs | 10 +- compiler/rustc_resolve/src/lib.rs | 24 +++-- 5 files changed, 56 insertions(+), 75 deletions(-) diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index ca6e48cb67fe5..fad197acd2330 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -791,7 +791,7 @@ fn resolver_for_lowering_raw<'tcx>( &'tcx Steal, &'tcx ty::ResolverGlobalCtxt, ) { - let arenas = Resolver::arenas(); + let arenas = WorkerLocal::new(|_| Resolver::arenas()); let _ = tcx.registered_tools(()); // Uses `crate_for_resolver`. let (krate, pre_configured_attrs) = tcx.crate_for_resolver(()).steal(); let mut resolver = Resolver::new( diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index c35dc02fb1de1..f9a5db0a17cc7 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -14,6 +14,7 @@ use rustc_ast::{ StmtKind, TraitAlias, TyAlias, }; use rustc_attr_parsing::AttributeParser; +use rustc_data_structures::fx::FxIndexMap; use rustc_expand::base::{ResolverExpand, SyntaxExtension, SyntaxExtensionKind}; use rustc_hir::Attribute; use rustc_hir::attrs::{AttributeKind, MacroUseArgs}; @@ -32,7 +33,7 @@ use tracing::debug; use crate::Namespace::{MacroNS, TypeNS, ValueNS}; use crate::def_collector::DefCollector; use crate::error_helper::{OnUnknownData, StructCtor}; -use crate::imports::{ImportData, ImportKind}; +use crate::imports::{ImportData, ImportKind, NameResolution, NameResolutionRef}; use crate::macros::{MacroRulesDecl, MacroRulesScope, MacroRulesScopeRef}; use crate::ref_mut::CmCell; use crate::{ @@ -75,46 +76,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { self.plant_decl_into_local_module(ident, orig_ident.span, ns, decl); } - /// Create a name definition from the given components, and put it into the extern module. - fn define_extern( - &self, - parent: ExternModule<'ra>, - ident: IdentKey, - orig_ident_span: Span, - ns: Namespace, - child_index: usize, - res: Res, - vis: Visibility, - span: Span, - expansion: LocalExpnId, - ambiguity: Option<(Decl<'ra>, bool)>, - ) { - let decl = self.arenas.alloc_decl(DeclData { - kind: DeclKind::Def(res), - ambiguity: CmCell::new(ambiguity), - initial_vis: vis, - ambiguity_vis_max: CmCell::new(None), - ambiguity_vis_min: CmCell::new(None), - span, - expansion, - parent_module: Some(parent.to_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. - let key = - BindingKey::new_disambiguated(ident, ns, || (child_index + 1).try_into().unwrap()); // 0 indicates no underscore - if self - .resolution_or_default(parent.to_module(), key, orig_ident_span) - .borrow_mut_unchecked() - .non_glob_decl - .replace(decl) - .is_some() - { - span_bug!(span, "an external binding was already defined"); - } - } - /// Walks up the tree of definitions starting at `def_id`, /// stopping at the first encountered module. /// Parent block modules for arbitrary def-ids are not recorded for the local crate, @@ -347,11 +308,21 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } } - pub(crate) fn build_reduced_graph_external(&self, module: ExternModule<'ra>) { + pub(crate) fn build_reduced_graph_external( + &self, + module: ExternModule<'ra>, + ) -> FxIndexMap> { + let mut resolutions = FxIndexMap::default(); let def_id = module.def_id(); let children = self.tcx.module_children(def_id); for (i, child) in children.iter().enumerate() { - self.build_reduced_graph_for_external_crate_res(child, module, i, None) + self.build_reduced_graph_for_external_crate_res( + child, + module, + i, + None, + &mut resolutions, + ) } for (i, child) in self.cstore().ambig_module_children_untracked(self.tcx, def_id).enumerate() @@ -361,8 +332,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { module, children.len() + i, Some(&child.second), + &mut resolutions, ) } + resolutions } /// Builds the reduced graph for a single item in an external crate. @@ -372,6 +345,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { parent: ExternModule<'ra>, child_index: usize, ambig_child: Option<&ModChild>, + resolutions: &mut FxIndexMap>, ) { let child_span = |this: &Self, reexport_chain: &[Reexport], res: def::Res<_>| { this.def_span( @@ -395,19 +369,30 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { }); // Record primary definitions. - let define_extern = |ns| { - self.define_extern( - parent, - ident, - orig_ident.span, - ns, - child_index, - res, - vis, + let mut define_extern = |ns| { + let orig_ident_span = orig_ident.span; + let decl = self.arenas.alloc_decl(DeclData { + kind: DeclKind::Def(res), + ambiguity: CmCell::new(ambig), + initial_vis: vis, + ambiguity_vis_max: CmCell::new(None), + ambiguity_vis_min: CmCell::new(None), span, expansion, - ambig, - ) + parent_module: Some(parent.to_module()), + }); + let resolution = self.arenas.alloc_name_resolution(NameResolution { + non_glob_decl: Some(decl), + orig_ident_span, + single_imports: Default::default(), + .. + }); + + let key = + BindingKey::new_disambiguated(ident, ns, || (child_index + 1).try_into().unwrap()); + if resolutions.insert(key, resolution).is_some() { + span_bug!(span, "an external binding was already defined"); + } }; match res { Res::Def( diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index de3f8c380fc44..6ac922f38cb31 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -221,7 +221,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { i.span, |this, feed| { if let Some(ext) = opt_syn_ext { - this.r.local_macro_map.insert(feed.def_id(), self.r.arenas.alloc_macro(ext)); + this.r.local_macro_map.insert(feed.def_id(), this.r.arenas.alloc_macro(ext)); } this.with_parent(feed.def_id(), |this| { diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 379ae992c9a6e..4daa549b1e109 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -821,7 +821,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ) => { self.per_ns(|this, ns| { match import_decls[ns] { - PendingDecl::Ready(Some(import_decl)) => { + PendingDecl::Ready(Some(decl)) => { + // We need the `target`, `source` can be extracted. + let import_decl = this.new_import_decl(decl, import); if import_decl.is_assoc_item() && !this.features.import_trait_associated_functions() { @@ -1151,11 +1153,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { Some(import), ); let pending_decl = match binding_result { - Ok(binding) => { - // We need the `target`, `source` can be extracted. - let import_decl = this.new_import_decl(binding, import); - PendingDecl::Ready(Some(import_decl)) - } + Ok(binding) => PendingDecl::Ready(Some(binding)), Err(Determinacy::Determined) => PendingDecl::Ready(None), Err(Determinacy::Undetermined) => { indeterminate_count += 1; diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 911350665ed32..649d56fb11edf 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -47,7 +47,7 @@ use rustc_ast::{ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet, default}; use rustc_data_structures::intern::Interned; use rustc_data_structures::steal::Steal; -use rustc_data_structures::sync::{FreezeReadGuard, FreezeWriteGuard}; +use rustc_data_structures::sync::{FreezeReadGuard, FreezeWriteGuard, WorkerLocal}; use rustc_data_structures::unord::{UnordItems, UnordMap, UnordSet}; use rustc_errors::{Applicability, Diag, ErrCode, ErrorGuaranteed, LintBuffer}; use rustc_expand::base::{DeriveResolution, SyntaxExtension, SyntaxExtensionKind}; @@ -1388,7 +1388,7 @@ pub struct Resolver<'ra, 'tcx> { /// Crate-local macro expanded `macro_export` referred to by a module-relative path. macro_expanded_macro_export_errors: BTreeSet<(Span, Span)> = BTreeSet::new(), - arenas: &'ra ResolverArenas<'ra>, + arenas: &'ra WorkerLocal>, dummy_decl: Decl<'ra>, builtin_type_decls: FxHashMap>, builtin_attr_decls: FxHashMap>, @@ -1568,11 +1568,9 @@ impl<'ra> ResolverArenas<'ra> { // SAFETY: `Interned` is valid because values of this type have "identity". Interned::new_unchecked(self.imports.alloc(import)) } - fn alloc_name_resolution(&'ra self, orig_ident_span: Span) -> NameResolutionRef<'ra> { + fn alloc_name_resolution(&'ra self, resolution: NameResolution<'ra>) -> NameResolutionRef<'ra> { // SAFETY: `Interned` is valid because values of this type have "identity". - Interned::new_unchecked( - self.name_resolutions.alloc(CmRefCell::new(NameResolution::new(orig_ident_span))), - ) + Interned::new_unchecked(self.name_resolutions.alloc(CmRefCell::new(resolution))) } fn alloc_macro_rules_scope(&'ra self, scope: MacroRulesScope<'ra>) -> MacroRulesScopeRef<'ra> { self.dropless.alloc(CacheCell::new(scope)) @@ -1742,7 +1740,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { attrs: &[ast::Attribute], crate_span: Span, current_crate_outer_attr_insert_span: Span, - arenas: &'ra ResolverArenas<'ra>, + arenas: &'ra WorkerLocal>, ) -> Resolver<'ra, 'tcx> { let root_def_id = CRATE_DEF_ID.to_def_id(); let graph_root = LocalModule::new( @@ -2174,7 +2172,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { fn resolutions(&self, module: Module<'ra>) -> &'ra Resolutions<'ra> { if module.populate_on_access.get() { module.populate_on_access.set(false); - self.build_reduced_graph_external(module.expect_extern()); + // unchecked because extern + *module.lazy_resolutions.borrow_mut_unchecked() = + self.build_reduced_graph_external(module.expect_extern()); } &module.0.0.lazy_resolutions } @@ -2193,11 +2193,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { key: BindingKey, orig_ident_span: Span, ) -> NameResolutionRef<'ra> { - *self - .resolutions(module) - .borrow_mut_unchecked() - .entry(key) - .or_insert_with(|| self.arenas.alloc_name_resolution(orig_ident_span)) + *self.resolutions(module).borrow_mut(self).entry(key).or_insert_with(|| { + self.arenas.alloc_name_resolution(NameResolution::new(orig_ident_span)) + }) } /// Test if AmbiguityError ambi is any identical to any one inside ambiguity_errors