diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 810355dc2c0f8..caa912c7c8baf 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -574,6 +574,7 @@ define_dep_nodes!( <'tcx> [] MaybeUnusedTraitImport(HirId), [] MaybeUnusedExternCrates, [] StabilityIndex, + [] AllCrateNums, ); trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug { diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 68d871c4b30ec..a7d874386d1c9 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -255,7 +255,7 @@ pub trait CrateStore { // This is basically a 1-based range of ints, which is a little // silly - I may fix that. - fn crates(&self) -> Vec; + fn crates_untracked(&self) -> Vec; // utility functions fn encode_metadata<'a, 'tcx>(&self, @@ -334,9 +334,7 @@ impl CrateStore for DummyCrateStore { } fn load_macro_untracked(&self, did: DefId, sess: &Session) -> LoadedMacro { bug!("load_macro") } - // This is basically a 1-based range of ints, which is a little - // silly - I may fix that. - fn crates(&self) -> Vec { vec![] } + fn crates_untracked(&self) -> Vec { vec![] } // utility functions fn extern_mod_stmt_cnum_untracked(&self, emod_id: ast::NodeId) -> Option { None } @@ -370,8 +368,9 @@ pub trait CrateLoader { // positions. pub fn used_crates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)> { - let mut libs = tcx.sess.cstore.crates() - .into_iter() + let mut libs = tcx.crates() + .iter() + .cloned() .filter_map(|cnum| { if tcx.dep_kind(cnum).macros_only() { return None diff --git a/src/librustc/middle/dependency_format.rs b/src/librustc/middle/dependency_format.rs index 81c406f3cb183..1c7d0b76a643e 100644 --- a/src/librustc/middle/dependency_format.rs +++ b/src/librustc/middle/dependency_format.rs @@ -132,7 +132,7 @@ fn calculate_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, if let Some(v) = attempt_static(tcx) { return v; } - for cnum in sess.cstore.crates() { + for &cnum in tcx.crates().iter() { if tcx.dep_kind(cnum).macros_only() { continue } let src = tcx.used_crate_source(cnum); if src.rlib.is_some() { continue } @@ -165,7 +165,7 @@ fn calculate_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // Sweep all crates for found dylibs. Add all dylibs, as well as their // dependencies, ensuring there are no conflicts. The only valid case for a // dependency to be relied upon twice is for both cases to rely on a dylib. - for cnum in sess.cstore.crates() { + for &cnum in tcx.crates().iter() { if tcx.dep_kind(cnum).macros_only() { continue } let name = tcx.crate_name(cnum); let src = tcx.used_crate_source(cnum); @@ -181,7 +181,7 @@ fn calculate_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } // Collect what we've got so far in the return vector. - let last_crate = sess.cstore.crates().len(); + let last_crate = tcx.crates().len(); let mut ret = (1..last_crate+1).map(|cnum| { match formats.get(&CrateNum::new(cnum)) { Some(&RequireDynamic) => Linkage::Dynamic, @@ -195,7 +195,7 @@ fn calculate_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // // If the crate hasn't been included yet and it's not actually required // (e.g. it's an allocator) then we skip it here as well. - for cnum in sess.cstore.crates() { + for &cnum in tcx.crates().iter() { let src = tcx.used_crate_source(cnum); if src.dylib.is_none() && !formats.contains_key(&cnum) && @@ -281,7 +281,7 @@ fn attempt_static<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Option Option { pub fn collect<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> LanguageItems { let mut collector = LanguageItemCollector::new(tcx); - for cnum in tcx.sess.cstore.crates() { + for &cnum in tcx.crates().iter() { for &(index, item_index) in tcx.defined_lang_items(cnum).iter() { let def_id = DefId { krate: cnum, index: index }; collector.collect_item(item_index, def_id); diff --git a/src/librustc/middle/weak_lang_items.rs b/src/librustc/middle/weak_lang_items.rs index ad6702ed21f8d..50fb584070262 100644 --- a/src/librustc/middle/weak_lang_items.rs +++ b/src/librustc/middle/weak_lang_items.rs @@ -83,7 +83,7 @@ fn verify<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } let mut missing = HashSet::new(); - for cnum in tcx.sess.cstore.crates() { + for &cnum in tcx.crates().iter() { for &item in tcx.missing_lang_items(cnum).iter() { missing.insert(item); } diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 15e649e7cec0c..18f286ebf5576 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -994,14 +994,14 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { let interners = CtxtInterners::new(arena); let common_types = CommonTypes::new(&interners); let dep_graph = hir.dep_graph.clone(); - let max_cnum = s.cstore.crates().iter().map(|c| c.as_usize()).max().unwrap_or(0); + let max_cnum = s.cstore.crates_untracked().iter().map(|c| c.as_usize()).max().unwrap_or(0); let mut providers = IndexVec::from_elem_n(extern_providers, max_cnum + 1); providers[LOCAL_CRATE] = local_providers; let def_path_hash_to_def_id = if s.opts.build_dep_graph() { let upstream_def_path_tables: Vec<(CrateNum, Rc<_>)> = s .cstore - .crates() + .crates_untracked() .iter() .map(|&cnum| (cnum, s.cstore.def_path_table(cnum))) .collect(); @@ -1121,6 +1121,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { self.stability_index(LOCAL_CRATE) }) } + + pub fn crates(self) -> Rc> { + self.all_crate_nums(LOCAL_CRATE) + } } impl<'gcx: 'tcx, 'tcx> GlobalCtxt<'gcx> { diff --git a/src/librustc/ty/maps.rs b/src/librustc/ty/maps.rs index 29e5e4e343134..48b92d101edb3 100644 --- a/src/librustc/ty/maps.rs +++ b/src/librustc/ty/maps.rs @@ -754,6 +754,12 @@ impl<'tcx> QueryDescription for queries::stability_index<'tcx> { } } +impl<'tcx> QueryDescription for queries::all_crate_nums<'tcx> { + fn describe(_tcx: TyCtxt, _: CrateNum) -> String { + format!("fetching all foreign CrateNum instances") + } +} + // If enabled, send a message to the profile-queries thread macro_rules! profq_msg { ($tcx:expr, $msg:expr) => { @@ -1376,6 +1382,7 @@ define_maps! { <'tcx> -> Rc>, [] fn stability_index: stability_index_node(CrateNum) -> Rc>, + [] fn all_crate_nums: all_crate_nums_node(CrateNum) -> Rc>, } fn type_param_predicates<'tcx>((item_id, param_id): (DefId, DefId)) -> DepConstructor<'tcx> { @@ -1485,3 +1492,7 @@ fn maybe_unused_extern_crates_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> { fn stability_index_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> { DepConstructor::StabilityIndex } + +fn all_crate_nums_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> { + DepConstructor::AllCrateNums +} diff --git a/src/librustc/ty/trait_def.rs b/src/librustc/ty/trait_def.rs index 4687fc6540924..3aadacfe826fd 100644 --- a/src/librustc/ty/trait_def.rs +++ b/src/librustc/ty/trait_def.rs @@ -146,7 +146,7 @@ pub(super) fn trait_impls_of_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // Traits defined in the current crate can't have impls in upstream // crates, so we don't bother querying the cstore. if !trait_id.is_local() { - for cnum in tcx.sess.cstore.crates() { + for &cnum in tcx.crates().iter() { let impls = tcx.implementations_of_trait((cnum, trait_id)); remote_impls.extend(impls.iter().cloned()); } diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 61881bc033bea..776fd35829000 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -281,6 +281,11 @@ pub fn provide_local<'tcx>(providers: &mut Providers<'tcx>) { tcx.sess.cstore.extern_mod_stmt_cnum_untracked(id) }, + all_crate_nums: |tcx, cnum| { + assert_eq!(cnum, LOCAL_CRATE); + Rc::new(tcx.sess.cstore.crates_untracked()) + }, + // Returns a map from a sufficiently visible external item (i.e. an // external item that is visible from at least one local module) to a // sufficiently visible parent (considering modules that re-export the @@ -292,7 +297,7 @@ pub fn provide_local<'tcx>(providers: &mut Providers<'tcx>) { assert_eq!(cnum, LOCAL_CRATE); let mut visible_parent_map: DefIdMap = DefIdMap(); - for cnum in tcx.sess.cstore.crates() { + for &cnum in tcx.crates().iter() { // Ignore crates without a corresponding local `extern crate` item. if tcx.missing_extern_crate_item(cnum) { continue @@ -481,7 +486,7 @@ impl CrateStore for cstore::CStore { }) } - fn crates(&self) -> Vec + fn crates_untracked(&self) -> Vec { let mut result = vec![]; self.iter_crate_data(|cnum, _| result.push(cnum)); diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index d3b3396413c13..a27a85a63e8a7 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -1288,7 +1288,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { } fn encode_crate_deps(&mut self, _: ()) -> LazySeq { - let crates = self.tcx.sess.cstore.crates(); + let crates = self.tcx.crates(); let mut deps = crates .iter() diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 3dc3bad602a90..3de5fda0d45c1 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -109,7 +109,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { pub fn get_external_crates(&self) -> Vec { let mut result = Vec::new(); - for n in self.tcx.sess.cstore.crates() { + for &n in self.tcx.crates().iter() { let span = match *self.tcx.extern_crate(n.as_def_id()) { Some(ref c) => c.span, None => { diff --git a/src/librustc_trans/back/symbol_export.rs b/src/librustc_trans/back/symbol_export.rs index 68f30b589c2c5..b546059b4c51d 100644 --- a/src/librustc_trans/back/symbol_export.rs +++ b/src/librustc_trans/back/symbol_export.rs @@ -110,7 +110,7 @@ impl ExportedSymbols { let mut exports = FxHashMap(); exports.insert(LOCAL_CRATE, local_crate); - for cnum in tcx.sess.cstore.crates() { + for &cnum in tcx.crates().iter() { debug_assert!(cnum != LOCAL_CRATE); // If this crate is a plugin and/or a custom derive crate, then diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index b3db5a8730a0a..6cfde9c7bbc73 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -1524,7 +1524,7 @@ impl CrateInfo { used_crate_source: FxHashMap(), }; - for cnum in tcx.sess.cstore.crates() { + for &cnum in tcx.crates().iter() { info.native_libraries.insert(cnum, tcx.native_libraries(cnum)); info.crate_name.insert(cnum, tcx.crate_name(cnum).to_string()); info.used_crate_source.insert(cnum, tcx.used_crate_source(cnum)); diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 5b327566a13ed..7fa3dd7472db8 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -559,7 +559,7 @@ pub fn all_traits<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> AllTraits<'a> _ => {} } } - for cnum in tcx.sess.cstore.crates() { + for &cnum in tcx.crates().iter() { let def_id = DefId { krate: cnum, index: CRATE_DEF_INDEX, diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 11fe8a64d4102..70563b3d26713 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -236,7 +236,7 @@ pub fn build_impls(cx: &DocContext, did: DefId) -> Vec { cx.populated_all_crate_impls.set(true); - for cnum in tcx.sess.cstore.crates() { + for &cnum in tcx.crates().iter() { for did in tcx.all_trait_implementations(cnum).iter() { build_impl(cx, *did, &mut impls); } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index e8927e28d753b..3a5786f668919 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -131,7 +131,7 @@ impl<'a, 'tcx> Clean for visit_ast::RustdocVisitor<'a, 'tcx> { } let mut externs = Vec::new(); - for cnum in cx.sess().cstore.crates() { + for &cnum in cx.tcx.crates().iter() { externs.push((cnum, cnum.clean(cx))); // Analyze doc-reachability for extern items LibEmbargoVisitor::new(cx).visit_lib(cnum);