Skip to content

Commit 52a405b

Browse files
authored
Rollup merge of rust-lang#143550 - petrochenkov:lessmutres, r=lcnr
resolve: Use interior mutability for extern module map Module map for extern modules is a lazily populated cache, it's not *significantly* mutable. If some logic in name resolver is parallelized, then this cache can be populated from any thread, and without affecting results of any speculative resolution. Unblocks rust-lang#143884. This is a part of [#gsoc > Project: Parallel Macro Expansion](https://rust-lang.zulipchat.com/#narrow/channel/421156-gsoc/topic/Project.3A.20Parallel.20Macro.20Expansion/with/527348747). cc `@LorrensP-2158466`
2 parents 14b6ac4 + 6849f81 commit 52a405b

File tree

10 files changed

+140
-129
lines changed

10 files changed

+140
-129
lines changed

compiler/rustc_expand/src/base.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1062,7 +1062,7 @@ pub trait ResolverExpand {
10621062
fn next_node_id(&mut self) -> NodeId;
10631063
fn invocation_parent(&self, id: LocalExpnId) -> LocalDefId;
10641064

1065-
fn resolve_dollar_crates(&mut self);
1065+
fn resolve_dollar_crates(&self);
10661066
fn visit_ast_fragment_with_placeholders(
10671067
&mut self,
10681068
expn_id: LocalExpnId,

compiler/rustc_resolve/src/build_reduced_graph.rs

Lines changed: 37 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
8585
/// Reachable macros with block module parents exist due to `#[macro_export] macro_rules!`,
8686
/// but they cannot use def-site hygiene, so the assumption holds
8787
/// (<https://github.com/rust-lang/rust/pull/77984#issuecomment-712445508>).
88-
pub(crate) fn get_nearest_non_block_module(&mut self, mut def_id: DefId) -> Module<'ra> {
88+
pub(crate) fn get_nearest_non_block_module(&self, mut def_id: DefId) -> Module<'ra> {
8989
loop {
9090
match self.get_module(def_id) {
9191
Some(module) => return module,
@@ -94,44 +94,47 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
9494
}
9595
}
9696

97-
pub(crate) fn expect_module(&mut self, def_id: DefId) -> Module<'ra> {
97+
pub(crate) fn expect_module(&self, def_id: DefId) -> Module<'ra> {
9898
self.get_module(def_id).expect("argument `DefId` is not a module")
9999
}
100100

101101
/// If `def_id` refers to a module (in resolver's sense, i.e. a module item, crate root, enum,
102102
/// or trait), then this function returns that module's resolver representation, otherwise it
103103
/// returns `None`.
104-
pub(crate) fn get_module(&mut self, def_id: DefId) -> Option<Module<'ra>> {
105-
if let module @ Some(..) = self.module_map.get(&def_id) {
106-
return module.copied();
107-
}
104+
pub(crate) fn get_module(&self, def_id: DefId) -> Option<Module<'ra>> {
105+
match def_id.as_local() {
106+
Some(local_def_id) => self.local_module_map.get(&local_def_id).copied(),
107+
None => {
108+
if let module @ Some(..) = self.extern_module_map.borrow().get(&def_id) {
109+
return module.copied();
110+
}
108111

109-
if !def_id.is_local() {
110-
// Query `def_kind` is not used because query system overhead is too expensive here.
111-
let def_kind = self.cstore().def_kind_untracked(def_id);
112-
if def_kind.is_module_like() {
113-
let parent = self
114-
.tcx
115-
.opt_parent(def_id)
116-
.map(|parent_id| self.get_nearest_non_block_module(parent_id));
117-
// Query `expn_that_defined` is not used because
118-
// hashing spans in its result is expensive.
119-
let expn_id = self.cstore().expn_that_defined_untracked(def_id, self.tcx.sess);
120-
return Some(self.new_module(
121-
parent,
122-
ModuleKind::Def(def_kind, def_id, Some(self.tcx.item_name(def_id))),
123-
expn_id,
124-
self.def_span(def_id),
125-
// FIXME: Account for `#[no_implicit_prelude]` attributes.
126-
parent.is_some_and(|module| module.no_implicit_prelude),
127-
));
112+
// Query `def_kind` is not used because query system overhead is too expensive here.
113+
let def_kind = self.cstore().def_kind_untracked(def_id);
114+
if def_kind.is_module_like() {
115+
let parent = self
116+
.tcx
117+
.opt_parent(def_id)
118+
.map(|parent_id| self.get_nearest_non_block_module(parent_id));
119+
// Query `expn_that_defined` is not used because
120+
// hashing spans in its result is expensive.
121+
let expn_id = self.cstore().expn_that_defined_untracked(def_id, self.tcx.sess);
122+
return Some(self.new_extern_module(
123+
parent,
124+
ModuleKind::Def(def_kind, def_id, Some(self.tcx.item_name(def_id))),
125+
expn_id,
126+
self.def_span(def_id),
127+
// FIXME: Account for `#[no_implicit_prelude]` attributes.
128+
parent.is_some_and(|module| module.no_implicit_prelude),
129+
));
130+
}
131+
132+
None
128133
}
129134
}
130-
131-
None
132135
}
133136

134-
pub(crate) fn expn_def_scope(&mut self, expn_id: ExpnId) -> Module<'ra> {
137+
pub(crate) fn expn_def_scope(&self, expn_id: ExpnId) -> Module<'ra> {
135138
match expn_id.expn_data().macro_def_id {
136139
Some(def_id) => self.macro_def_scope(def_id),
137140
None => expn_id
@@ -141,7 +144,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
141144
}
142145
}
143146

144-
pub(crate) fn macro_def_scope(&mut self, def_id: DefId) -> Module<'ra> {
147+
pub(crate) fn macro_def_scope(&self, def_id: DefId) -> Module<'ra> {
145148
if let Some(id) = def_id.as_local() {
146149
self.local_macro_def_scopes[&id]
147150
} else {
@@ -403,7 +406,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
403406
self.r.field_visibility_spans.insert(def_id, field_vis);
404407
}
405408

406-
fn block_needs_anonymous_module(&mut self, block: &Block) -> bool {
409+
fn block_needs_anonymous_module(&self, block: &Block) -> bool {
407410
// If any statements are items, we need to create an anonymous module
408411
block
409412
.stmts
@@ -758,7 +761,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
758761
if let ast::ModKind::Loaded(_, _, _, Err(_)) = mod_kind {
759762
self.r.mods_with_parse_errors.insert(def_id);
760763
}
761-
self.parent_scope.module = self.r.new_module(
764+
self.parent_scope.module = self.r.new_local_module(
762765
Some(parent),
763766
ModuleKind::Def(def_kind, def_id, Some(ident.name)),
764767
expansion.to_expn_id(),
@@ -790,7 +793,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
790793
ItemKind::Enum(ident, _, _) | ItemKind::Trait(box ast::Trait { ident, .. }) => {
791794
self.r.define(parent, ident, TypeNS, res, vis, sp, expansion);
792795

793-
self.parent_scope.module = self.r.new_module(
796+
self.parent_scope.module = self.r.new_local_module(
794797
Some(parent),
795798
ModuleKind::Def(def_kind, def_id, Some(ident.name)),
796799
expansion.to_expn_id(),
@@ -986,7 +989,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
986989
let parent = self.parent_scope.module;
987990
let expansion = self.parent_scope.expansion;
988991
if self.block_needs_anonymous_module(block) {
989-
let module = self.r.new_module(
992+
let module = self.r.new_local_module(
990993
Some(parent),
991994
ModuleKind::Block,
992995
expansion.to_expn_id(),
@@ -1118,7 +1121,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
11181121
}
11191122

11201123
/// Returns `true` if this attribute list contains `macro_use`.
1121-
fn contains_macro_use(&mut self, attrs: &[ast::Attribute]) -> bool {
1124+
fn contains_macro_use(&self, attrs: &[ast::Attribute]) -> bool {
11221125
for attr in attrs {
11231126
if attr.has_name(sym::macro_escape) {
11241127
let inner_attribute = matches!(attr.style, ast::AttrStyle::Inner);

compiler/rustc_resolve/src/diagnostics.rs

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2149,7 +2149,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
21492149
}
21502150

21512151
pub(crate) fn find_similarly_named_module_or_crate(
2152-
&mut self,
2152+
&self,
21532153
ident: Symbol,
21542154
current_module: Module<'ra>,
21552155
) -> Option<Symbol> {
@@ -2158,7 +2158,16 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
21582158
.keys()
21592159
.map(|ident| ident.name)
21602160
.chain(
2161-
self.module_map
2161+
self.local_module_map
2162+
.iter()
2163+
.filter(|(_, module)| {
2164+
current_module.is_ancestor_of(**module) && current_module != **module
2165+
})
2166+
.flat_map(|(_, module)| module.kind.name()),
2167+
)
2168+
.chain(
2169+
self.extern_module_map
2170+
.borrow()
21622171
.iter()
21632172
.filter(|(_, module)| {
21642173
current_module.is_ancestor_of(**module) && current_module != **module
@@ -2434,7 +2443,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
24342443
}
24352444

24362445
fn undeclared_module_suggest_declare(
2437-
&mut self,
2446+
&self,
24382447
ident: Ident,
24392448
path: std::path::PathBuf,
24402449
) -> Option<(Vec<(Span, String)>, String, Applicability)> {
@@ -2449,7 +2458,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
24492458
))
24502459
}
24512460

2452-
fn undeclared_module_exists(&mut self, ident: Ident) -> Option<std::path::PathBuf> {
2461+
fn undeclared_module_exists(&self, ident: Ident) -> Option<std::path::PathBuf> {
24532462
let map = self.tcx.sess.source_map();
24542463

24552464
let src = map.span_to_filename(ident.span).into_local_path()?;
@@ -2808,24 +2817,23 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
28082817
return cached;
28092818
}
28102819
visited.insert(parent_module, false);
2811-
let res = r.module_map.get(&parent_module).is_some_and(|m| {
2812-
for importer in m.glob_importers.borrow().iter() {
2813-
if let Some(next_parent_module) = importer.parent_scope.module.opt_def_id()
2820+
let m = r.expect_module(parent_module);
2821+
let mut res = false;
2822+
for importer in m.glob_importers.borrow().iter() {
2823+
if let Some(next_parent_module) = importer.parent_scope.module.opt_def_id() {
2824+
if next_parent_module == module
2825+
|| comes_from_same_module_for_glob(
2826+
r,
2827+
next_parent_module,
2828+
module,
2829+
visited,
2830+
)
28142831
{
2815-
if next_parent_module == module
2816-
|| comes_from_same_module_for_glob(
2817-
r,
2818-
next_parent_module,
2819-
module,
2820-
visited,
2821-
)
2822-
{
2823-
return true;
2824-
}
2832+
res = true;
2833+
break;
28252834
}
28262835
}
2827-
false
2828-
});
2836+
}
28292837
visited.insert(parent_module, res);
28302838
res
28312839
}

compiler/rustc_resolve/src/effective_visibilities.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,11 @@ pub(crate) struct EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> {
3838
}
3939

4040
impl Resolver<'_, '_> {
41-
fn nearest_normal_mod(&mut self, def_id: LocalDefId) -> LocalDefId {
41+
fn nearest_normal_mod(&self, def_id: LocalDefId) -> LocalDefId {
4242
self.get_nearest_non_block_module(def_id.to_def_id()).nearest_parent_mod().expect_local()
4343
}
4444

45-
fn private_vis_import(&mut self, binding: NameBinding<'_>) -> Visibility {
45+
fn private_vis_import(&self, binding: NameBinding<'_>) -> Visibility {
4646
let NameBindingKind::Import { import, .. } = binding.kind else { unreachable!() };
4747
Visibility::Restricted(
4848
import
@@ -52,7 +52,7 @@ impl Resolver<'_, '_> {
5252
)
5353
}
5454

55-
fn private_vis_def(&mut self, def_id: LocalDefId) -> Visibility {
55+
fn private_vis_def(&self, def_id: LocalDefId) -> Visibility {
5656
// For mod items `nearest_normal_mod` returns its argument, but we actually need its parent.
5757
let normal_mod_id = self.nearest_normal_mod(def_id);
5858
if normal_mod_id == def_id {
@@ -113,8 +113,7 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> {
113113
/// Update effective visibilities of bindings in the given module,
114114
/// including their whole reexport chains.
115115
fn set_bindings_effective_visibilities(&mut self, module_id: LocalDefId) {
116-
assert!(self.r.module_map.contains_key(&module_id.to_def_id()));
117-
let module = self.r.get_module(module_id.to_def_id()).unwrap();
116+
let module = self.r.expect_module(module_id.to_def_id());
118117
let resolutions = self.r.resolutions(module);
119118

120119
for (_, name_resolution) in resolutions.borrow().iter() {

compiler/rustc_resolve/src/ident.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
219219
}
220220

221221
fn hygienic_lexical_parent(
222-
&mut self,
222+
&self,
223223
module: Module<'ra>,
224224
ctxt: &mut SyntaxContext,
225225
derive_fallback_lint_id: Option<NodeId>,
@@ -841,7 +841,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
841841
if ns == TypeNS {
842842
if ident.name == kw::Crate || ident.name == kw::DollarCrate {
843843
let module = self.resolve_crate_root(ident);
844-
return Ok(self.module_self_bindings[&module]);
844+
return Ok(module.self_binding.unwrap());
845845
} else if ident.name == kw::Super || ident.name == kw::SelfLower {
846846
// FIXME: Implement these with renaming requirements so that e.g.
847847
// `use super;` doesn't work, but `use super as name;` does.
@@ -885,7 +885,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
885885
);
886886
}
887887

888-
let check_usable = |this: &mut Self, binding: NameBinding<'ra>| {
888+
let check_usable = |this: &Self, binding: NameBinding<'ra>| {
889889
let usable = this.is_accessible_from(binding.vis, parent_scope.module);
890890
if usable { Ok(binding) } else { Err((Determined, Weak::No)) }
891891
};

compiler/rustc_resolve/src/imports.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
456456
f: F,
457457
) -> T
458458
where
459-
F: FnOnce(&mut Resolver<'ra, 'tcx>, &mut NameResolution<'ra>) -> T,
459+
F: FnOnce(&Resolver<'ra, 'tcx>, &mut NameResolution<'ra>) -> T,
460460
{
461461
// Ensure that `resolution` isn't borrowed when defining in the module's glob importers,
462462
// during which the resolution might end up getting re-defined via a glob cycle.

compiler/rustc_resolve/src/late.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2491,7 +2491,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
24912491

24922492
/// Searches the current set of local scopes for labels. Returns the `NodeId` of the resolved
24932493
/// label and reports an error if the label is not found or is unreachable.
2494-
fn resolve_label(&mut self, mut label: Ident) -> Result<(NodeId, Span), ResolutionError<'ra>> {
2494+
fn resolve_label(&self, mut label: Ident) -> Result<(NodeId, Span), ResolutionError<'ra>> {
24952495
let mut suggestion = None;
24962496

24972497
for i in (0..self.label_ribs.len()).rev() {

0 commit comments

Comments
 (0)