Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/rustc_interface/src/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -791,7 +791,7 @@ fn resolver_for_lowering_raw<'tcx>(
&'tcx Steal<ast::Crate>,
&'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(
Expand Down
94 changes: 40 additions & 54 deletions compiler/rustc_resolve/src/build_reduced_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand All @@ -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, NameResolutionRef};
use crate::macros::{MacroRulesDecl, MacroRulesScope, MacroRulesScopeRef};
use crate::ref_mut::CmCell;
use crate::{
Expand Down Expand Up @@ -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<DefId>,
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,
Expand Down Expand Up @@ -347,11 +308,22 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
}
}

pub(crate) fn build_reduced_graph_external(&self, module: ExternModule<'ra>) {
#[must_use = "This does not insert the resolutions in to the module itself"]
Comment thread
LorrensP-2158466 marked this conversation as resolved.
pub(crate) fn build_reduced_graph_external(
&self,
module: ExternModule<'ra>,
) -> FxIndexMap<BindingKey, NameResolutionRef<'ra>> {
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()
Expand All @@ -361,8 +333,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.
Expand All @@ -372,6 +346,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
parent: ExternModule<'ra>,
child_index: usize,
ambig_child: Option<&ModChild>,
resolutions: &mut FxIndexMap<BindingKey, NameResolutionRef<'ra>>,
) {
let child_span = |this: &Self, reexport_chain: &[Reexport], res: def::Res<_>| {
this.def_span(
Expand All @@ -395,19 +370,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 key =
BindingKey::new_disambiguated(ident, ns, || (child_index + 1).try_into().unwrap());
if resolutions
.entry(key)

@petrochenkov petrochenkov Jul 9, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can use insert here, we are always adding a new entry, there's a span_bug check for this below.

View changes since the review

.or_insert_with(|| self.arenas.alloc_name_resolution(orig_ident_span))
.borrow_mut_unchecked() // only 1 thread builds extern tables
.non_glob_decl

@petrochenkov petrochenkov Jul 9, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

non_glob_decl can be set immediately after the resolution is created with alloc_name_resolution.

And if we hand-roll alloc_name_resolution we can even avoid borrow_mut_unchecked here.

View changes since the review

.replace(decl)
.is_some()
{
span_bug!(span, "an external binding was already defined");
}
};
match res {
Res::Def(
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_resolve/src/def_collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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| {
Expand Down
10 changes: 4 additions & 6 deletions compiler/rustc_resolve/src/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
{
Expand Down Expand Up @@ -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;
Expand Down
12 changes: 7 additions & 5 deletions compiler/rustc_resolve/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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<ResolverArenas<'ra>>,
dummy_decl: Decl<'ra>,
builtin_type_decls: FxHashMap<Symbol, Decl<'ra>>,
builtin_attr_decls: FxHashMap<Symbol, Decl<'ra>>,
Expand Down Expand Up @@ -1742,7 +1742,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<ResolverArenas<'ra>>,
) -> Resolver<'ra, 'tcx> {
let root_def_id = CRATE_DEF_ID.to_def_id();
let graph_root = LocalModule::new(
Expand Down Expand Up @@ -2174,7 +2174,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
}
Expand All @@ -2195,7 +2197,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
) -> NameResolutionRef<'ra> {
*self
.resolutions(module)
.borrow_mut_unchecked()
.borrow_mut(self)
.entry(key)
.or_insert_with(|| self.arenas.alloc_name_resolution(orig_ident_span))
}
Expand Down
Loading