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.

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.
This commit is contained in:
Vadim Petrochenkov 2021-09-25 02:27:00 +03:00
parent b27661eb33
commit 5aa732a364
9 changed files with 71 additions and 29 deletions

View file

@ -127,7 +127,6 @@ impl<'a> Resolver<'a> {
/// If `def_id` refers to a module (in resolver's sense, i.e. a module item, crate root, enum,
/// or trait), then this function returns that module's resolver representation, otherwise it
/// returns `None`.
/// FIXME: `Module`s for local enums and traits are not currently found.
crate fn get_module(&mut self, def_id: DefId) -> Option<Module<'a>> {
if let module @ Some(..) = self.module_map.get(&def_id) {
return module.copied();
@ -146,17 +145,21 @@ impl<'a> Resolver<'a> {
} else {
def_key.disambiguated_data.data.get_opt_name().expect("module without name")
};
let expn_id = if def_kind == DefKind::Mod {
self.cstore().module_expansion_untracked(def_id, &self.session)
} else {
// FIXME: Parent expansions for enums and traits are not kept in metadata.
ExpnId::root()
};
let module = self.arenas.new_module(
Some(self.new_module(
parent,
ModuleKind::Def(def_kind, def_id, name),
self.cstore().module_expansion_untracked(def_id, &self.session),
expn_id,
self.cstore().get_span_untracked(def_id, &self.session),
// FIXME: Account for `#[no_implicit_prelude]` attributes.
parent.map_or(false, |module| module.no_implicit_prelude),
);
self.module_map.insert(def_id, module);
Some(module)
))
}
_ => None,
}
@ -759,7 +762,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
}
ItemKind::Mod(..) => {
let module = self.r.arenas.new_module(
let module = self.r.new_module(
Some(parent),
ModuleKind::Def(DefKind::Mod, def_id, ident.name),
expansion.to_expn_id(),
@ -768,7 +771,6 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
|| self.r.session.contains_name(&item.attrs, sym::no_implicit_prelude),
);
self.r.define(parent, ident, TypeNS, (module, vis, sp, expansion));
self.r.module_map.insert(def_id, module);
// Descend into the module.
self.parent_scope.module = module;
@ -799,7 +801,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
}
ItemKind::Enum(_, _) => {
let module = self.r.arenas.new_module(
let module = self.r.new_module(
Some(parent),
ModuleKind::Def(DefKind::Enum, def_id, ident.name),
expansion.to_expn_id(),
@ -873,7 +875,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
ItemKind::Trait(..) => {
// Add all the items within to a new module.
let module = self.r.arenas.new_module(
let module = self.r.new_module(
Some(parent),
ModuleKind::Def(DefKind::Trait, def_id, ident.name),
expansion.to_expn_id(),
@ -916,7 +918,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
let parent = self.parent_scope.module;
let expansion = self.parent_scope.expansion;
if self.block_needs_anonymous_module(block) {
let module = self.r.arenas.new_module(
let module = self.r.new_module(
Some(parent),
ModuleKind::Block(block.id),
expansion.to_expn_id(),
@ -936,15 +938,8 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
let expansion = self.parent_scope.expansion;
// Record primary definitions.
match res {
Res::Def(kind @ (DefKind::Mod | DefKind::Enum | DefKind::Trait), def_id) => {
let module = self.r.arenas.new_module(
Some(parent),
ModuleKind::Def(kind, def_id, ident.name),
expansion.to_expn_id(),
span,
// FIXME: Account for `#[no_implicit_prelude]` attributes.
parent.no_implicit_prelude,
);
Res::Def(DefKind::Mod | DefKind::Enum | DefKind::Trait, def_id) => {
let module = self.r.expect_module(def_id);
self.r.define(parent, ident, TypeNS, (module, vis, span, expansion));
}
Res::Def(

View file

@ -1071,12 +1071,17 @@ impl<'a> ResolverArenas<'a> {
expn_id: ExpnId,
span: Span,
no_implicit_prelude: bool,
module_map: &mut FxHashMap<DefId, Module<'a>>,
) -> Module<'a> {
let module =
self.modules.alloc(ModuleData::new(parent, kind, expn_id, span, no_implicit_prelude));
if module.def_id().map_or(true, |def_id| def_id.is_local()) {
let def_id = module.def_id();
if def_id.map_or(true, |def_id| def_id.is_local()) {
self.local_modules.borrow_mut().push(module);
}
if let Some(def_id) = def_id {
module_map.insert(def_id, module);
}
module
}
fn local_modules(&'a self) -> std::cell::Ref<'a, Vec<Module<'a>>> {
@ -1276,12 +1281,14 @@ impl<'a> Resolver<'a> {
arenas: &'a ResolverArenas<'a>,
) -> Resolver<'a> {
let root_def_id = CRATE_DEF_ID.to_def_id();
let mut module_map = FxHashMap::default();
let graph_root = arenas.new_module(
None,
ModuleKind::Def(DefKind::Mod, root_def_id, kw::Empty),
ExpnId::root(),
krate.span,
session.contains_name(&krate.attrs, sym::no_implicit_prelude),
&mut module_map,
);
let empty_module = arenas.new_module(
None,
@ -1289,9 +1296,8 @@ impl<'a> Resolver<'a> {
ExpnId::root(),
DUMMY_SP,
true,
&mut FxHashMap::default(),
);
let mut module_map = FxHashMap::default();
module_map.insert(root_def_id, graph_root);
let definitions = Definitions::new(session.local_stable_crate_id(), krate.span);
let root = definitions.get_root_def();
@ -1434,6 +1440,18 @@ impl<'a> Resolver<'a> {
resolver
}
fn new_module(
&mut self,
parent: Option<Module<'a>>,
kind: ModuleKind,
expn_id: ExpnId,
span: Span,
no_implicit_prelude: bool,
) -> Module<'a> {
let module_map = &mut self.module_map;
self.arenas.new_module(parent, kind, expn_id, span, no_implicit_prelude, module_map)
}
fn create_stable_hashing_context(&self) -> ExpandHasher<'_, 'a> {
ExpandHasher {
source_map: CachingSourceMapView::new(self.session.source_map()),