diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 4e0e561f661..13abdaf109a 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -423,7 +423,7 @@ pub enum LoadedMacros { } pub trait CrateLoader { - fn load_macros(&mut self, extern_crate: &ast::Item) -> LoadedMacros; - fn process_item(&mut self, item: &ast::Item, defs: &Definitions); + fn process_item(&mut self, item: &ast::Item, defs: &Definitions, load_macros: bool) + -> Option; fn postprocess(&mut self, krate: &ast::Crate); } diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 440571de240..6f739efdc92 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -23,7 +23,7 @@ use rustc::session::search_paths::PathKind; use rustc::middle; use rustc::middle::cstore::{CrateStore, validate_crate_name, ExternCrate}; use rustc::util::nodemap::{FnvHashMap, FnvHashSet}; -use rustc::hir::map as hir_map; +use rustc::hir::map::Definitions; use std::cell::{RefCell, Cell}; use std::ops::Deref; @@ -631,8 +631,6 @@ impl<'a> CrateLoader<'a> { use rustc_back::dynamic_lib::DynamicLibrary; use syntax_ext::deriving::custom::CustomDerive; - self.cstore.add_used_for_derive_macros(item); - // Make sure the path contains a / or the linker will search for it. let path = env::current_dir().unwrap().join(path); let lib = match DynamicLibrary::open(Some(&path)) { @@ -1020,13 +1018,19 @@ impl<'a> middle::cstore::CrateLoader for CrateLoader<'a> { self.register_statically_included_foreign_items(); } - fn process_item(&mut self, item: &ast::Item, definitions: &hir_map::Definitions) { + fn process_item(&mut self, item: &ast::Item, definitions: &Definitions, load_macros: bool) + -> Option { match item.node { ast::ItemKind::ExternCrate(_) => {} - ast::ItemKind::ForeignMod(ref fm) => return self.process_foreign_mod(item, fm), - _ => return, + ast::ItemKind::ForeignMod(ref fm) => { + self.process_foreign_mod(item, fm); + return None; + } + _ => return None, } + let loaded_macros = if load_macros { Some(self.read_macros(item)) } else { None }; + // If this `extern crate` item has `#[macro_use]` then we can safely skip it. // These annotations were processed during macro expansion and are already loaded // (if necessary) into our crate store. @@ -1034,15 +1038,13 @@ impl<'a> middle::cstore::CrateLoader for CrateLoader<'a> { // Note that it's important we *don't* fall through below as some `#[macro_use]` // crates are explicitly not linked (e.g. macro crates) so we want to ensure // we avoid `resolve_crate` with those. - if attr::contains_name(&item.attrs, "macro_use") { - if self.cstore.was_used_for_derive_macros(item) { - return - } + if let Some(LoadedMacros::CustomDerives(..)) = loaded_macros { + return loaded_macros; } if let Some(info) = self.extract_crate_info(item) { if !info.should_link { - return; + return loaded_macros; } let (cnum, ..) = self.resolve_crate( @@ -1058,9 +1060,7 @@ impl<'a> middle::cstore::CrateLoader for CrateLoader<'a> { self.cstore.add_extern_mod_stmt_cnum(info.id, cnum); } - } - fn load_macros(&mut self, extern_crate: &ast::Item) -> LoadedMacros { - self.read_macros(extern_crate) + loaded_macros } } diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index a87e61c4c94..781ebf81d59 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -21,14 +21,13 @@ use rustc::hir::svh::Svh; use rustc::middle::cstore::ExternCrate; use rustc_back::PanicStrategy; use rustc_data_structures::indexed_vec::IndexVec; -use rustc::util::nodemap::{FnvHashMap, NodeMap, NodeSet, DefIdMap, FnvHashSet}; +use rustc::util::nodemap::{FnvHashMap, NodeMap, NodeSet, DefIdMap}; use std::cell::{RefCell, Cell}; use std::rc::Rc; use std::path::PathBuf; use flate::Bytes; -use syntax::ast::{self, Ident}; -use syntax::attr; +use syntax::{ast, attr}; use syntax_pos; pub use rustc::middle::cstore::{NativeLibraryKind, LinkagePreference}; @@ -105,7 +104,6 @@ pub struct CStore { pub inlined_item_cache: RefCell>>, pub defid_for_inlined_node: RefCell>, pub visible_parent_map: RefCell>, - pub used_for_derive_macro: RefCell>, } impl CStore { @@ -121,7 +119,6 @@ impl CStore { visible_parent_map: RefCell::new(FnvHashMap()), inlined_item_cache: RefCell::new(FnvHashMap()), defid_for_inlined_node: RefCell::new(FnvHashMap()), - used_for_derive_macro: RefCell::new(FnvHashSet()), } } @@ -277,14 +274,6 @@ impl CStore { { self.extern_mod_crate_map.borrow().get(&emod_id).cloned() } - - pub fn was_used_for_derive_macros(&self, i: &ast::Item) -> bool { - self.used_for_derive_macro.borrow().contains(&i.ident) - } - - pub fn add_used_for_derive_macros(&self, i: &ast::Item) { - self.used_for_derive_macro.borrow_mut().insert(i.ident); - } } impl CrateMetadata { diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 69210b98e3a..db86840fd38 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -215,12 +215,11 @@ impl<'b> Resolver<'b> { } let loaded_macros = if legacy_imports != LegacyMacroImports::default() { - Some(self.crate_loader.load_macros(item)) + self.crate_loader.process_item(item, &self.definitions, true) } else { - None + self.crate_loader.process_item(item, &self.definitions, false) }; - self.crate_loader.process_item(item, &self.definitions); // 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 { @@ -270,7 +269,9 @@ impl<'b> Resolver<'b> { self.current_module = module; } - ItemKind::ForeignMod(..) => self.crate_loader.process_item(item, &self.definitions), + ItemKind::ForeignMod(..) => { + self.crate_loader.process_item(item, &self.definitions, false); + } // These items live in the value namespace. ItemKind::Static(_, m, _) => {