Skip to content

Commit d14731c

Browse files
committed
Auto merge of #89239 - petrochenkov:modcache, r=cjgillot
resolve: Cache module loading for all foreign modules It was previously cached for modules loaded from `fn get_module`, but not for modules loaded from `fn build_reduced_graph_for_external_crate_res`. This also makes all foreign modules use their real parent, span and expansion instead of possibly a parent/span/expansion of their reexport. Modules are also often compared using referential equality (`ptr::eq`), this change makes such comparisons correct in all cases. An ICE happening on attempt to decode expansions for foreign enums and traits is avoided. Also local enums and traits are now added to the module map. Follow up to #88872. r? `@cjgillot`
2 parents edebf77 + d7d0765 commit d14731c

13 files changed

+93
-44
lines changed

compiler/rustc_resolve/src/build_reduced_graph.rs

+16-22
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,6 @@ impl<'a> Resolver<'a> {
127127
/// If `def_id` refers to a module (in resolver's sense, i.e. a module item, crate root, enum,
128128
/// or trait), then this function returns that module's resolver representation, otherwise it
129129
/// returns `None`.
130-
/// FIXME: `Module`s for local enums and traits are not currently found.
131130
crate fn get_module(&mut self, def_id: DefId) -> Option<Module<'a>> {
132131
if let module @ Some(..) = self.module_map.get(&def_id) {
133132
return module.copied();
@@ -146,17 +145,21 @@ impl<'a> Resolver<'a> {
146145
} else {
147146
def_key.disambiguated_data.data.get_opt_name().expect("module without name")
148147
};
148+
let expn_id = if def_kind == DefKind::Mod {
149+
self.cstore().module_expansion_untracked(def_id, &self.session)
150+
} else {
151+
// FIXME: Parent expansions for enums and traits are not kept in metadata.
152+
ExpnId::root()
153+
};
149154

150-
let module = self.arenas.new_module(
155+
Some(self.new_module(
151156
parent,
152157
ModuleKind::Def(def_kind, def_id, name),
153-
self.cstore().module_expansion_untracked(def_id, &self.session),
158+
expn_id,
154159
self.cstore().get_span_untracked(def_id, &self.session),
155160
// FIXME: Account for `#[no_implicit_prelude]` attributes.
156161
parent.map_or(false, |module| module.no_implicit_prelude),
157-
);
158-
self.module_map.insert(def_id, module);
159-
Some(module)
162+
))
160163
}
161164
_ => None,
162165
}
@@ -217,8 +220,7 @@ impl<'a> Resolver<'a> {
217220
}
218221

219222
crate fn build_reduced_graph_external(&mut self, module: Module<'a>) {
220-
let def_id = module.def_id().expect("unpopulated module without a def-id");
221-
for child in self.cstore().item_children_untracked(def_id, self.session) {
223+
for child in self.cstore().item_children_untracked(module.def_id(), self.session) {
222224
let parent_scope = ParentScope::module(module, self);
223225
BuildReducedGraphVisitor { r: self, parent_scope }
224226
.build_reduced_graph_for_external_crate_res(child);
@@ -759,7 +761,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
759761
}
760762

761763
ItemKind::Mod(..) => {
762-
let module = self.r.arenas.new_module(
764+
let module = self.r.new_module(
763765
Some(parent),
764766
ModuleKind::Def(DefKind::Mod, def_id, ident.name),
765767
expansion.to_expn_id(),
@@ -768,7 +770,6 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
768770
|| self.r.session.contains_name(&item.attrs, sym::no_implicit_prelude),
769771
);
770772
self.r.define(parent, ident, TypeNS, (module, vis, sp, expansion));
771-
self.r.module_map.insert(def_id, module);
772773

773774
// Descend into the module.
774775
self.parent_scope.module = module;
@@ -799,7 +800,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
799800
}
800801

801802
ItemKind::Enum(_, _) => {
802-
let module = self.r.arenas.new_module(
803+
let module = self.r.new_module(
803804
Some(parent),
804805
ModuleKind::Def(DefKind::Enum, def_id, ident.name),
805806
expansion.to_expn_id(),
@@ -873,7 +874,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
873874

874875
ItemKind::Trait(..) => {
875876
// Add all the items within to a new module.
876-
let module = self.r.arenas.new_module(
877+
let module = self.r.new_module(
877878
Some(parent),
878879
ModuleKind::Def(DefKind::Trait, def_id, ident.name),
879880
expansion.to_expn_id(),
@@ -916,7 +917,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
916917
let parent = self.parent_scope.module;
917918
let expansion = self.parent_scope.expansion;
918919
if self.block_needs_anonymous_module(block) {
919-
let module = self.r.arenas.new_module(
920+
let module = self.r.new_module(
920921
Some(parent),
921922
ModuleKind::Block(block.id),
922923
expansion.to_expn_id(),
@@ -936,15 +937,8 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
936937
let expansion = self.parent_scope.expansion;
937938
// Record primary definitions.
938939
match res {
939-
Res::Def(kind @ (DefKind::Mod | DefKind::Enum | DefKind::Trait), def_id) => {
940-
let module = self.r.arenas.new_module(
941-
Some(parent),
942-
ModuleKind::Def(kind, def_id, ident.name),
943-
expansion.to_expn_id(),
944-
span,
945-
// FIXME: Account for `#[no_implicit_prelude]` attributes.
946-
parent.no_implicit_prelude,
947-
);
940+
Res::Def(DefKind::Mod | DefKind::Enum | DefKind::Trait, def_id) => {
941+
let module = self.r.expect_module(def_id);
948942
self.r.define(parent, ident, TypeNS, (module, vis, span, expansion));
949943
}
950944
Res::Def(

compiler/rustc_resolve/src/diagnostics.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -801,7 +801,7 @@ impl<'a> Resolver<'a> {
801801
None => worklist_via_import.pop(),
802802
Some(x) => Some(x),
803803
} {
804-
let in_module_is_extern = !in_module.def_id().unwrap().is_local();
804+
let in_module_is_extern = !in_module.def_id().is_local();
805805
// We have to visit module children in deterministic order to avoid
806806
// instabilities in reported imports (#43552).
807807
in_module.for_each_child(self, |this, ident, ns, name_binding| {
@@ -884,7 +884,7 @@ impl<'a> Resolver<'a> {
884884

885885
if !is_extern_crate_that_also_appears_in_prelude {
886886
// add the module to the lookup
887-
if seen_modules.insert(module.def_id().unwrap()) {
887+
if seen_modules.insert(module.def_id()) {
888888
if via_import { &mut worklist_via_import } else { &mut worklist }
889889
.push((module, path_segments, child_accessible));
890890
}

compiler/rustc_resolve/src/imports.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -989,7 +989,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
989989
}
990990

991991
if let ModuleOrUniformRoot::Module(module) = module {
992-
if module.def_id() == import.parent_scope.module.def_id() {
992+
if ptr::eq(module, import.parent_scope.module) {
993993
// Importing a module into itself is not allowed.
994994
return Some(UnresolvedImportError {
995995
span: import.span,
@@ -1341,7 +1341,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
13411341
if module.is_trait() {
13421342
self.r.session.span_err(import.span, "items in traits are not importable.");
13431343
return;
1344-
} else if module.def_id() == import.parent_scope.module.def_id() {
1344+
} else if ptr::eq(module, import.parent_scope.module) {
13451345
return;
13461346
} else if let ImportKind::Glob { is_prelude: true, .. } = import.kind {
13471347
self.r.prelude = Some(module);
@@ -1400,7 +1400,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
14001400
});
14011401

14021402
if !reexports.is_empty() {
1403-
if let Some(def_id) = module.def_id() {
1403+
if let Some(def_id) = module.opt_def_id() {
14041404
// Call to `expect_local` should be fine because current
14051405
// code is only called for local modules.
14061406
self.r.export_map.insert(def_id.expect_local(), reexports);

compiler/rustc_resolve/src/late/diagnostics.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1491,7 +1491,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
14911491
// form the path
14921492
let mut path_segments = path_segments.clone();
14931493
path_segments.push(ast::PathSegment::from_ident(ident));
1494-
let module_def_id = module.def_id().unwrap();
1494+
let module_def_id = module.def_id();
14951495
if module_def_id == def_id {
14961496
let path =
14971497
Path { span: name_binding.span, segments: path_segments, tokens: None };

compiler/rustc_resolve/src/lib.rs

+32-9
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ impl ModuleOrUniformRoot<'_> {
413413
fn same_def(lhs: Self, rhs: Self) -> bool {
414414
match (lhs, rhs) {
415415
(ModuleOrUniformRoot::Module(lhs), ModuleOrUniformRoot::Module(rhs)) => {
416-
lhs.def_id() == rhs.def_id()
416+
ptr::eq(lhs, rhs)
417417
}
418418
(
419419
ModuleOrUniformRoot::CrateRootAndExternPrelude,
@@ -602,7 +602,11 @@ impl<'a> ModuleData<'a> {
602602
}
603603
}
604604

605-
fn def_id(&self) -> Option<DefId> {
605+
fn def_id(&self) -> DefId {
606+
self.opt_def_id().expect("`ModuleData::def_id` is called on a block module")
607+
}
608+
609+
fn opt_def_id(&self) -> Option<DefId> {
606610
match self.kind {
607611
ModuleKind::Def(_, def_id, _) => Some(def_id),
608612
_ => None,
@@ -1071,12 +1075,17 @@ impl<'a> ResolverArenas<'a> {
10711075
expn_id: ExpnId,
10721076
span: Span,
10731077
no_implicit_prelude: bool,
1078+
module_map: &mut FxHashMap<DefId, Module<'a>>,
10741079
) -> Module<'a> {
10751080
let module =
10761081
self.modules.alloc(ModuleData::new(parent, kind, expn_id, span, no_implicit_prelude));
1077-
if module.def_id().map_or(true, |def_id| def_id.is_local()) {
1082+
let def_id = module.opt_def_id();
1083+
if def_id.map_or(true, |def_id| def_id.is_local()) {
10781084
self.local_modules.borrow_mut().push(module);
10791085
}
1086+
if let Some(def_id) = def_id {
1087+
module_map.insert(def_id, module);
1088+
}
10801089
module
10811090
}
10821091
fn local_modules(&'a self) -> std::cell::Ref<'a, Vec<Module<'a>>> {
@@ -1276,22 +1285,23 @@ impl<'a> Resolver<'a> {
12761285
arenas: &'a ResolverArenas<'a>,
12771286
) -> Resolver<'a> {
12781287
let root_def_id = CRATE_DEF_ID.to_def_id();
1288+
let mut module_map = FxHashMap::default();
12791289
let graph_root = arenas.new_module(
12801290
None,
12811291
ModuleKind::Def(DefKind::Mod, root_def_id, kw::Empty),
12821292
ExpnId::root(),
12831293
krate.span,
12841294
session.contains_name(&krate.attrs, sym::no_implicit_prelude),
1295+
&mut module_map,
12851296
);
12861297
let empty_module = arenas.new_module(
12871298
None,
12881299
ModuleKind::Def(DefKind::Mod, root_def_id, kw::Empty),
12891300
ExpnId::root(),
12901301
DUMMY_SP,
12911302
true,
1303+
&mut FxHashMap::default(),
12921304
);
1293-
let mut module_map = FxHashMap::default();
1294-
module_map.insert(root_def_id, graph_root);
12951305

12961306
let definitions = Definitions::new(session.local_stable_crate_id(), krate.span);
12971307
let root = definitions.get_root_def();
@@ -1434,6 +1444,18 @@ impl<'a> Resolver<'a> {
14341444
resolver
14351445
}
14361446

1447+
fn new_module(
1448+
&mut self,
1449+
parent: Option<Module<'a>>,
1450+
kind: ModuleKind,
1451+
expn_id: ExpnId,
1452+
span: Span,
1453+
no_implicit_prelude: bool,
1454+
) -> Module<'a> {
1455+
let module_map = &mut self.module_map;
1456+
self.arenas.new_module(parent, kind, expn_id, span, no_implicit_prelude, module_map)
1457+
}
1458+
14371459
fn create_stable_hashing_context(&self) -> ExpandHasher<'_, 'a> {
14381460
ExpandHasher {
14391461
source_map: CachingSourceMapView::new(self.session.source_map()),
@@ -1570,7 +1592,7 @@ impl<'a> Resolver<'a> {
15701592

15711593
if let Some(module) = current_trait {
15721594
if self.trait_may_have_item(Some(module), assoc_item) {
1573-
let def_id = module.def_id().unwrap();
1595+
let def_id = module.def_id();
15741596
found_traits.push(TraitCandidate { def_id, import_ids: smallvec![] });
15751597
}
15761598
}
@@ -2171,8 +2193,9 @@ impl<'a> Resolver<'a> {
21712193
return self.graph_root;
21722194
}
21732195
};
2174-
let module = self
2175-
.expect_module(module.def_id().map_or(LOCAL_CRATE, |def_id| def_id.krate).as_def_id());
2196+
let module = self.expect_module(
2197+
module.opt_def_id().map_or(LOCAL_CRATE, |def_id| def_id.krate).as_def_id(),
2198+
);
21762199
debug!(
21772200
"resolve_crate_root({:?}): got module {:?} ({:?}) (ident.span = {:?})",
21782201
ident,
@@ -2999,7 +3022,7 @@ impl<'a> Resolver<'a> {
29993022
}
30003023

30013024
let container = match parent.kind {
3002-
ModuleKind::Def(kind, _, _) => kind.descr(parent.def_id().unwrap()),
3025+
ModuleKind::Def(kind, _, _) => kind.descr(parent.def_id()),
30033026
ModuleKind::Block(..) => "block",
30043027
};
30053028

compiler/rustc_span/src/hygiene.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -601,7 +601,10 @@ pub fn debug_hygiene_data(verbose: bool) -> String {
601601
let expn_data = expn_data.as_ref().expect("no expansion data for an expansion ID");
602602
debug_expn_data((&id.to_expn_id(), expn_data))
603603
});
604-
data.foreign_expn_data.iter().for_each(debug_expn_data);
604+
// Sort the hash map for more reproducible output.
605+
let mut foreign_expn_data: Vec<_> = data.foreign_expn_data.iter().collect();
606+
foreign_expn_data.sort_by_key(|(id, _)| (id.krate, id.local_id));
607+
foreign_expn_data.into_iter().for_each(debug_expn_data);
605608
s.push_str("\n\nSyntaxContexts:");
606609
data.syntax_context_data.iter().enumerate().for_each(|(id, ctxt)| {
607610
s.push_str(&format!(
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#![feature(decl_macro)]
2+
3+
mod inner1 {
4+
pub struct Struct {}
5+
6+
pub mod inner2 {
7+
pub macro mac() {
8+
super::Struct
9+
}
10+
}
11+
}
12+
13+
pub use inner1::inner2 as public;
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// `super` in a `macro` refers to the parent module of the macro itself and not its reexport.
2+
3+
// check-pass
4+
// aux-build:macro-def-site-super.rs
5+
6+
extern crate macro_def_site_super;
7+
8+
type A = macro_def_site_super::public::mac!();
9+
10+
fn main() {}

src/test/ui/proc-macro/meta-macro-hygiene.rs

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
// compile-flags: -Z span-debug -Z macro-backtrace -Z unpretty=expanded,hygiene -Z trim-diagnostic-paths=no
55
// check-pass
66
// normalize-stdout-test "\d+#" -> "0#"
7+
// normalize-stdout-test "expn\d{3,}" -> "expnNNN"
78
//
89
// We don't care about symbol ids, so we set them all to 0
910
// in the stdout

src/test/ui/proc-macro/meta-macro-hygiene.stdout

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
Def site: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#5)
2-
Input: TokenStream [Ident { ident: "$crate", span: $DIR/meta-macro-hygiene.rs:23:37: 23:43 (#4) }, Punct { ch: ':', spacing: Joint, span: $DIR/meta-macro-hygiene.rs:23:43: 23:45 (#4) }, Punct { ch: ':', spacing: Alone, span: $DIR/meta-macro-hygiene.rs:23:43: 23:45 (#4) }, Ident { ident: "dummy", span: $DIR/meta-macro-hygiene.rs:23:45: 23:50 (#4) }, Punct { ch: '!', spacing: Alone, span: $DIR/meta-macro-hygiene.rs:23:50: 23:51 (#4) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: $DIR/meta-macro-hygiene.rs:23:51: 23:53 (#4) }]
2+
Input: TokenStream [Ident { ident: "$crate", span: $DIR/meta-macro-hygiene.rs:24:37: 24:43 (#4) }, Punct { ch: ':', spacing: Joint, span: $DIR/meta-macro-hygiene.rs:24:43: 24:45 (#4) }, Punct { ch: ':', spacing: Alone, span: $DIR/meta-macro-hygiene.rs:24:43: 24:45 (#4) }, Ident { ident: "dummy", span: $DIR/meta-macro-hygiene.rs:24:45: 24:50 (#4) }, Punct { ch: '!', spacing: Alone, span: $DIR/meta-macro-hygiene.rs:24:50: 24:51 (#4) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: $DIR/meta-macro-hygiene.rs:24:51: 24:53 (#4) }]
33
Respanned: TokenStream [Ident { ident: "$crate", span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#5) }, Punct { ch: ':', spacing: Joint, span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#5) }, Punct { ch: ':', spacing: Alone, span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#5) }, Ident { ident: "dummy", span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#5) }, Punct { ch: '!', spacing: Alone, span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#5) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#5) }]
44
#![feature /* 0#0 */(prelude_import)]
55
// aux-build:make-macro.rs
@@ -8,6 +8,7 @@ Respanned: TokenStream [Ident { ident: "$crate", span: $DIR/auxiliary/make-macro
88
// compile-flags: -Z span-debug -Z macro-backtrace -Z unpretty=expanded,hygiene -Z trim-diagnostic-paths=no
99
// check-pass
1010
// normalize-stdout-test "\d+#" -> "0#"
11+
// normalize-stdout-test "expn\d{3,}" -> "expnNNN"
1112
//
1213
// We don't care about symbol ids, so we set them all to 0
1314
// in the stdout
@@ -48,6 +49,7 @@ crate0::{{expn1}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt:
4849
crate0::{{expn2}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Bang, "produce_it")
4950
crate0::{{expn3}}: parent: crate0::{{expn2}}, call_site_ctxt: #4, def_site_ctxt: #0, kind: Macro(Bang, "meta_macro::print_def_site")
5051
crate0::{{expn4}}: parent: crate0::{{expn3}}, call_site_ctxt: #5, def_site_ctxt: #0, kind: Macro(Bang, "$crate::dummy")
52+
crate1::{{expnNNN}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Bang, "include")
5153
crate2::{{expn1}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: AstPass(StdImports)
5254

5355
SyntaxContexts:

src/test/ui/proc-macro/nonterminal-token-hygiene.rs

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
// compile-flags: -Z span-debug -Z macro-backtrace -Z unpretty=expanded,hygiene
55
// compile-flags: -Z trim-diagnostic-paths=no
66
// normalize-stdout-test "\d+#" -> "0#"
7+
// normalize-stdout-test "expn\d{3,}" -> "expnNNN"
78
// aux-build:test-macros.rs
89

910
#![feature(decl_macro)]

src/test/ui/proc-macro/nonterminal-token-hygiene.stdout

+6-4
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,19 @@ PRINT-BANG INPUT (DEBUG): TokenStream [
66
stream: TokenStream [
77
Ident {
88
ident: "struct",
9-
span: $DIR/nonterminal-token-hygiene.rs:30:5: 30:11 (#5),
9+
span: $DIR/nonterminal-token-hygiene.rs:31:5: 31:11 (#5),
1010
},
1111
Ident {
1212
ident: "S",
13-
span: $DIR/nonterminal-token-hygiene.rs:30:12: 30:13 (#5),
13+
span: $DIR/nonterminal-token-hygiene.rs:31:12: 31:13 (#5),
1414
},
1515
Punct {
1616
ch: ';',
1717
spacing: Alone,
18-
span: $DIR/nonterminal-token-hygiene.rs:30:13: 30:14 (#5),
18+
span: $DIR/nonterminal-token-hygiene.rs:31:13: 31:14 (#5),
1919
},
2020
],
21-
span: $DIR/nonterminal-token-hygiene.rs:20:27: 20:32 (#6),
21+
span: $DIR/nonterminal-token-hygiene.rs:21:27: 21:32 (#6),
2222
},
2323
]
2424
#![feature /* 0#0 */(prelude_import)]
@@ -29,6 +29,7 @@ PRINT-BANG INPUT (DEBUG): TokenStream [
2929
// compile-flags: -Z span-debug -Z macro-backtrace -Z unpretty=expanded,hygiene
3030
// compile-flags: -Z trim-diagnostic-paths=no
3131
// normalize-stdout-test "\d+#" -> "0#"
32+
// normalize-stdout-test "expn\d{3,}" -> "expnNNN"
3233
// aux-build:test-macros.rs
3334

3435
#![feature /* 0#0 */(decl_macro)]
@@ -72,6 +73,7 @@ crate0::{{expn1}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt:
7273
crate0::{{expn2}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Bang, "outer")
7374
crate0::{{expn3}}: parent: crate0::{{expn2}}, call_site_ctxt: #4, def_site_ctxt: #4, kind: Macro(Bang, "inner")
7475
crate0::{{expn4}}: parent: crate0::{{expn3}}, call_site_ctxt: #6, def_site_ctxt: #0, kind: Macro(Bang, "print_bang")
76+
crate1::{{expnNNN}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Bang, "include")
7577
crate2::{{expn1}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: AstPass(StdImports)
7678

7779
SyntaxContexts:

0 commit comments

Comments
 (0)