From 624a9b73113bdacc6a92d2d2b0704735093fae3c Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Fri, 28 Oct 2016 05:17:06 +0000 Subject: [PATCH] Avoid building multiple reduced graphs for a crate that is referenced by multiple `extern crate` items. --- src/librustc_resolve/build_reduced_graph.rs | 22 ++++++++++++--------- src/librustc_resolve/lib.rs | 2 ++ 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index ca6e72dd4f4..d987930544e 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -24,7 +24,7 @@ use rustc::middle::cstore::LoadedMacros; use rustc::hir::def::*; -use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId}; +use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId}; use rustc::ty; use rustc::util::nodemap::FxHashMap; @@ -233,14 +233,7 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, expansion: Mark) { // n.b. we don't need to look at the path option here, because cstore already did let crate_id = self.session.cstore.extern_mod_stmt_cnum(item.id); let module = if let Some(crate_id) = crate_id { - let def_id = DefId { - krate: crate_id, - index: CRATE_DEF_INDEX, - }; - let module = self.arenas.alloc_module(ModuleS { - populated: Cell::new(false), - ..ModuleS::new(Some(parent), ModuleKind::Def(Def::Mod(def_id), name)) - }); + let module = self.get_extern_crate_root(crate_id); let binding = (module, sp, ty::Visibility::Public).to_name_binding(); let binding = self.arenas.alloc_name_binding(binding); let directive = self.arenas.alloc_import_directive(ImportDirective { @@ -504,6 +497,17 @@ fn build_reduced_graph_for_external_crate_def(&mut self, parent: Module<'b>, } } + fn get_extern_crate_root(&mut self, cnum: CrateNum) -> Module<'b> { + let def_id = DefId { krate: cnum, index: CRATE_DEF_INDEX }; + let arenas = self.arenas; + *self.extern_crate_roots.entry(cnum).or_insert_with(|| { + arenas.alloc_module(ModuleS { + populated: Cell::new(false), + ..ModuleS::new(None, ModuleKind::Def(Def::Mod(def_id), keywords::Invalid.name())) + }) + }) + } + /// Ensures that the reduced graph rooted at the given external module /// is built, building it if it is not. pub fn populate_module_if_necessary(&mut self, module: Module<'b>) { diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 4de272bc3a0..b16b61b46b8 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1083,6 +1083,7 @@ pub struct Resolver<'a> { // There will be an anonymous module created around `g` with the ID of the // entry block for `f`. module_map: NodeMap>, + extern_crate_roots: FxHashMap>, // Whether or not to print error messages. Can be set to true // when getting additional info for error message suggestions, @@ -1276,6 +1277,7 @@ pub fn new(session: &'a Session, export_map: NodeMap(), trait_map: NodeMap(), module_map: module_map, + extern_crate_roots: FxHashMap(), emit_errors: true, make_glob_map: make_glob_map == MakeGlobMap::Yes, -- GitLab