about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-06-16 21:42:17 +0000
committerbors <bors@rust-lang.org>2017-06-16 21:42:17 +0000
commit3cb803460b109235cf83bbfc4173e5b038ce3396 (patch)
treee8d310ae57b498529cc572e15b26d9bedfe53fee
parentfe7227f6c8704f0186091085a14fd1027920e4bb (diff)
parente6dd8692606fc966dac7315c56e9a24932bb951c (diff)
downloadrust-3cb803460b109235cf83bbfc4173e5b038ce3396.tar.gz
rust-3cb803460b109235cf83bbfc4173e5b038ce3396.zip
Auto merge of #42598 - cramertj:track-more-metadata, r=nikomatsakis
Track more crate metadata

Part of https://github.com/rust-lang/rust/issues/41417
r? @nikomatsakis
-rw-r--r--src/librustc/dep_graph/dep_node.rs9
-rw-r--r--src/librustc/hir/def_id.rs2
-rw-r--r--src/librustc/middle/cstore.rs13
-rw-r--r--src/librustc/middle/dependency_format.rs43
-rw-r--r--src/librustc/ty/item_path.rs6
-rw-r--r--src/librustc/ty/maps.rs42
-rw-r--r--src/librustc_const_eval/eval.rs2
-rw-r--r--src/librustc_driver/driver.rs3
-rw-r--r--src/librustc_metadata/cstore.rs2
-rw-r--r--src/librustc_metadata/cstore_impl.rs61
-rw-r--r--src/librustc_mir/transform/copy_prop.rs3
-rw-r--r--src/librustc_mir/transform/qualify_consts.rs17
-rw-r--r--src/librustc_passes/consts.rs2
-rw-r--r--src/librustc_save_analysis/lib.rs2
-rw-r--r--src/librustc_trans/back/symbol_export.rs4
-rw-r--r--src/librustdoc/clean/inline.rs4
16 files changed, 122 insertions, 93 deletions
diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs
index 1c9ecdca0e2..b061663148d 100644
--- a/src/librustc/dep_graph/dep_node.rs
+++ b/src/librustc/dep_graph/dep_node.rs
@@ -81,7 +81,7 @@ macro_rules! define_dep_nodes {
     ($(
         $variant:ident $(( $($tuple_arg:tt),* ))*
                        $({ $($struct_arg_name:ident : $struct_arg_ty:ty),* })*
-      ),*
+      ,)*
     ) => (
         #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash,
                  RustcEncodable, RustcDecodable)]
@@ -394,6 +394,7 @@ define_dep_nodes!(
     ItemSignature(DefId),
     ItemVarianceConstraints(DefId),
     ItemVariances(DefId),
+    IsConstFn(DefId),
     IsForeignItem(DefId),
     TypeParamPredicates { item_id: DefId, param_id: DefId },
     SizedConstraint(DefId),
@@ -475,7 +476,11 @@ define_dep_nodes!(
     IsExportedSymbol(DefId),
     IsMirAvailable(DefId),
     ItemAttrs(DefId),
-    FnArgNames(DefId)
+    FnArgNames(DefId),
+    DylibDepFormats(DefId),
+    IsAllocator(DefId),
+    IsPanicRuntime(DefId),
+    ExternCrate(DefId),
 );
 
 trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> {
diff --git a/src/librustc/hir/def_id.rs b/src/librustc/hir/def_id.rs
index ce2baa73897..95a27f06599 100644
--- a/src/librustc/hir/def_id.rs
+++ b/src/librustc/hir/def_id.rs
@@ -58,6 +58,8 @@ impl CrateNum {
     pub fn as_u32(&self) -> u32 {
         self.0
     }
+
+    pub fn as_def_id(&self) -> DefId { DefId { krate: *self, index: CRATE_DEF_INDEX } }
 }
 
 impl fmt::Display for CrateNum {
diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs
index 15cfcbb244a..960d616cd4c 100644
--- a/src/librustc/middle/cstore.rs
+++ b/src/librustc/middle/cstore.rs
@@ -243,24 +243,18 @@ pub trait CrateStore {
     fn associated_item_cloned(&self, def: DefId) -> ty::AssociatedItem;
 
     // flags
-    fn is_const_fn(&self, did: DefId) -> bool;
     fn is_dllimport_foreign_item(&self, def: DefId) -> bool;
     fn is_statically_included_foreign_item(&self, def_id: DefId) -> bool;
 
     // crate metadata
-    fn dylib_dependency_formats(&self, cnum: CrateNum)
-                                    -> Vec<(CrateNum, LinkagePreference)>;
     fn dep_kind(&self, cnum: CrateNum) -> DepKind;
     fn export_macros(&self, cnum: CrateNum);
     fn lang_items(&self, cnum: CrateNum) -> Vec<(DefIndex, usize)>;
     fn missing_lang_items(&self, cnum: CrateNum) -> Vec<lang_items::LangItem>;
-    fn is_allocator(&self, cnum: CrateNum) -> bool;
-    fn is_panic_runtime(&self, cnum: CrateNum) -> bool;
     fn is_compiler_builtins(&self, cnum: CrateNum) -> bool;
     fn is_sanitizer_runtime(&self, cnum: CrateNum) -> bool;
     fn is_profiler_runtime(&self, cnum: CrateNum) -> bool;
     fn panic_strategy(&self, cnum: CrateNum) -> PanicStrategy;
-    fn extern_crate(&self, cnum: CrateNum) -> Option<ExternCrate>;
     /// The name of the crate as it is referred to in source code of the current
     /// crate.
     fn crate_name(&self, cnum: CrateNum) -> Symbol;
@@ -365,29 +359,22 @@ impl CrateStore for DummyCrateStore {
         { bug!("associated_item_cloned") }
 
     // flags
-    fn is_const_fn(&self, did: DefId) -> bool { bug!("is_const_fn") }
     fn is_dllimport_foreign_item(&self, id: DefId) -> bool { false }
     fn is_statically_included_foreign_item(&self, def_id: DefId) -> bool { false }
 
     // crate metadata
-    fn dylib_dependency_formats(&self, cnum: CrateNum)
-                                    -> Vec<(CrateNum, LinkagePreference)>
-        { bug!("dylib_dependency_formats") }
     fn lang_items(&self, cnum: CrateNum) -> Vec<(DefIndex, usize)>
         { bug!("lang_items") }
     fn missing_lang_items(&self, cnum: CrateNum) -> Vec<lang_items::LangItem>
         { bug!("missing_lang_items") }
     fn dep_kind(&self, cnum: CrateNum) -> DepKind { bug!("is_explicitly_linked") }
     fn export_macros(&self, cnum: CrateNum) { bug!("export_macros") }
-    fn is_allocator(&self, cnum: CrateNum) -> bool { bug!("is_allocator") }
-    fn is_panic_runtime(&self, cnum: CrateNum) -> bool { bug!("is_panic_runtime") }
     fn is_compiler_builtins(&self, cnum: CrateNum) -> bool { bug!("is_compiler_builtins") }
     fn is_profiler_runtime(&self, cnum: CrateNum) -> bool { bug!("is_profiler_runtime") }
     fn is_sanitizer_runtime(&self, cnum: CrateNum) -> bool { bug!("is_sanitizer_runtime") }
     fn panic_strategy(&self, cnum: CrateNum) -> PanicStrategy {
         bug!("panic_strategy")
     }
-    fn extern_crate(&self, cnum: CrateNum) -> Option<ExternCrate> { bug!("extern_crate") }
     fn crate_name(&self, cnum: CrateNum) -> Symbol { bug!("crate_name") }
     fn original_crate_name(&self, cnum: CrateNum) -> Symbol {
         bug!("original_crate_name")
diff --git a/src/librustc/middle/dependency_format.rs b/src/librustc/middle/dependency_format.rs
index e60d0533c9f..4e1f06cca06 100644
--- a/src/librustc/middle/dependency_format.rs
+++ b/src/librustc/middle/dependency_format.rs
@@ -65,6 +65,7 @@ use hir::def_id::CrateNum;
 
 use session;
 use session::config;
+use ty::TyCtxt;
 use middle::cstore::DepKind;
 use middle::cstore::LinkagePreference::{self, RequireStatic, RequireDynamic};
 use util::nodemap::FxHashMap;
@@ -91,18 +92,22 @@ pub enum Linkage {
     Dynamic,
 }
 
-pub fn calculate(sess: &session::Session) {
+pub fn calculate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
+    let sess = &tcx.sess;
     let mut fmts = sess.dependency_formats.borrow_mut();
     for &ty in sess.crate_types.borrow().iter() {
-        let linkage = calculate_type(sess, ty);
-        verify_ok(sess, &linkage);
+        let linkage = calculate_type(tcx, ty);
+        verify_ok(tcx, &linkage);
         fmts.insert(ty, linkage);
     }
     sess.abort_if_errors();
 }
 
-fn calculate_type(sess: &session::Session,
-                  ty: config::CrateType) -> DependencyList {
+fn calculate_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                            ty: config::CrateType) -> DependencyList {
+
+    let sess = &tcx.sess;
+
     if !sess.opts.output_types.should_trans() {
         return Vec::new();
     }
@@ -111,7 +116,7 @@ fn calculate_type(sess: &session::Session,
         // If the global prefer_dynamic switch is turned off, first attempt
         // static linkage (this can fail).
         config::CrateTypeExecutable if !sess.opts.cg.prefer_dynamic => {
-            if let Some(v) = attempt_static(sess) {
+            if let Some(v) = attempt_static(tcx) {
                 return v;
             }
         }
@@ -124,7 +129,7 @@ fn calculate_type(sess: &session::Session,
         // to be found, we generate some nice pretty errors.
         config::CrateTypeStaticlib |
         config::CrateTypeCdylib => {
-            if let Some(v) = attempt_static(sess) {
+            if let Some(v) = attempt_static(tcx) {
                 return v;
             }
             for cnum in sess.cstore.crates() {
@@ -141,7 +146,7 @@ fn calculate_type(sess: &session::Session,
         // to try to eagerly statically link all dependencies. This is normally
         // done for end-product dylibs, not intermediate products.
         config::CrateTypeDylib if !sess.opts.cg.prefer_dynamic => {
-            if let Some(v) = attempt_static(sess) {
+            if let Some(v) = attempt_static(tcx) {
                 return v;
             }
         }
@@ -167,8 +172,8 @@ fn calculate_type(sess: &session::Session,
         if src.dylib.is_some() {
             info!("adding dylib: {}", name);
             add_library(sess, cnum, RequireDynamic, &mut formats);
-            let deps = sess.cstore.dylib_dependency_formats(cnum);
-            for &(depnum, style) in &deps {
+            let deps = tcx.dylib_dependency_formats(cnum.as_def_id());
+            for &(depnum, style) in deps.iter() {
                 info!("adding {:?}: {}", style,
                       sess.cstore.crate_name(depnum));
                 add_library(sess, depnum, style, &mut formats);
@@ -210,9 +215,9 @@ fn calculate_type(sess: &session::Session,
     // Things like allocators and panic runtimes may not have been activated
     // quite yet, so do so here.
     activate_injected_dep(sess.injected_allocator.get(), &mut ret,
-                          &|cnum| sess.cstore.is_allocator(cnum));
+                          &|cnum| tcx.is_allocator(cnum.as_def_id()));
     activate_injected_dep(sess.injected_panic_runtime.get(), &mut ret,
-                          &|cnum| sess.cstore.is_panic_runtime(cnum));
+                          &|cnum| tcx.is_panic_runtime(cnum.as_def_id()));
 
     // When dylib B links to dylib A, then when using B we must also link to A.
     // It could be the case, however, that the rlib for A is present (hence we
@@ -269,7 +274,8 @@ fn add_library(sess: &session::Session,
     }
 }
 
-fn attempt_static(sess: &session::Session) -> Option<DependencyList> {
+fn attempt_static<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Option<DependencyList> {
+    let sess = &tcx.sess;
     let crates = sess.cstore.used_crates(RequireStatic);
     if !crates.iter().by_ref().all(|&(_, ref p)| p.is_some()) {
         return None
@@ -290,9 +296,9 @@ fn attempt_static(sess: &session::Session) -> Option<DependencyList> {
     // explicitly linked, which is the case for any injected dependency. Handle
     // that here and activate them.
     activate_injected_dep(sess.injected_allocator.get(), &mut ret,
-                          &|cnum| sess.cstore.is_allocator(cnum));
+                          &|cnum| tcx.is_allocator(cnum.as_def_id()));
     activate_injected_dep(sess.injected_panic_runtime.get(), &mut ret,
-                          &|cnum| sess.cstore.is_panic_runtime(cnum));
+                          &|cnum| tcx.is_panic_runtime(cnum.as_def_id()));
 
     Some(ret)
 }
@@ -327,7 +333,8 @@ fn activate_injected_dep(injected: Option<CrateNum>,
 
 // After the linkage for a crate has been determined we need to verify that
 // there's only going to be one allocator in the output.
-fn verify_ok(sess: &session::Session, list: &[Linkage]) {
+fn verify_ok<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, list: &[Linkage]) {
+    let sess = &tcx.sess;
     if list.len() == 0 {
         return
     }
@@ -338,7 +345,7 @@ fn verify_ok(sess: &session::Session, list: &[Linkage]) {
             continue
         }
         let cnum = CrateNum::new(i + 1);
-        if sess.cstore.is_allocator(cnum) {
+        if tcx.is_allocator(cnum.as_def_id()) {
             if let Some(prev) = allocator {
                 let prev_name = sess.cstore.crate_name(prev);
                 let cur_name = sess.cstore.crate_name(cnum);
@@ -349,7 +356,7 @@ fn verify_ok(sess: &session::Session, list: &[Linkage]) {
             allocator = Some(cnum);
         }
 
-        if sess.cstore.is_panic_runtime(cnum) {
+        if tcx.is_panic_runtime(cnum.as_def_id()) {
             if let Some((prev, _)) = panic_runtime {
                 let prev_name = sess.cstore.crate_name(prev);
                 let cur_name = sess.cstore.crate_name(cnum);
diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs
index 30dcc3fc810..09a3bcd0613 100644
--- a/src/librustc/ty/item_path.rs
+++ b/src/librustc/ty/item_path.rs
@@ -100,7 +100,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
                 //
                 // Returns `None` for the local crate.
                 if cnum != LOCAL_CRATE {
-                    let opt_extern_crate = self.sess.cstore.extern_crate(cnum);
+                    let opt_extern_crate = self.extern_crate(cnum.as_def_id());
                     let opt_extern_crate = opt_extern_crate.and_then(|extern_crate| {
                         if extern_crate.direct {
                             Some(extern_crate.def_id)
@@ -136,8 +136,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
             // If `cur_def` is a direct or injected extern crate, push the path to the crate
             // followed by the path to the item within the crate and return.
             if cur_def.index == CRATE_DEF_INDEX {
-                match self.sess.cstore.extern_crate(cur_def.krate) {
-                    Some(extern_crate) if extern_crate.direct => {
+                match *self.extern_crate(cur_def) {
+                    Some(ref extern_crate) if extern_crate.direct => {
                         self.push_item_path(buffer, extern_crate.def_id);
                         cur_path.iter().rev().map(|segment| buffer.push(&segment.as_str())).count();
                         return true;
diff --git a/src/librustc/ty/maps.rs b/src/librustc/ty/maps.rs
index 162a734aa19..524cf57472b 100644
--- a/src/librustc/ty/maps.rs
+++ b/src/librustc/ty/maps.rs
@@ -13,6 +13,7 @@ use hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId, LOCAL_CRATE};
 use hir::def::Def;
 use hir;
 use middle::const_val;
+use middle::cstore::{ExternCrate, LinkagePreference};
 use middle::privacy::AccessLevels;
 use middle::region::RegionMaps;
 use mir;
@@ -476,6 +477,36 @@ impl<'tcx> QueryDescription for queries::is_object_safe<'tcx> {
     }
 }
 
+impl<'tcx> QueryDescription for queries::is_const_fn<'tcx> {
+    fn describe(tcx: TyCtxt, def_id: DefId) -> String {
+        format!("checking if item is const fn: `{}`", tcx.item_path_str(def_id))
+    }
+}
+
+impl<'tcx> QueryDescription for queries::dylib_dependency_formats<'tcx> {
+    fn describe(_: TyCtxt, _: DefId) -> String {
+        "dylib dependency formats of crate".to_string()
+    }
+}
+
+impl<'tcx> QueryDescription for queries::is_allocator<'tcx> {
+    fn describe(_: TyCtxt, _: DefId) -> String {
+        "checking if the crate is_allocator".to_string()
+    }
+}
+
+impl<'tcx> QueryDescription for queries::is_panic_runtime<'tcx> {
+    fn describe(_: TyCtxt, _: DefId) -> String {
+        "checking if the crate is_panic_runtime".to_string()
+    }
+}
+
+impl<'tcx> QueryDescription for queries::extern_crate<'tcx> {
+    fn describe(_: TyCtxt, _: DefId) -> String {
+        "getting crate's ExternCrateData".to_string()
+    }
+}
+
 macro_rules! define_maps {
     (<$tcx:tt>
      $($(#[$attr:meta])*
@@ -791,6 +822,9 @@ define_maps! { <'tcx>
     [] adt_sized_constraint: SizedConstraint(DefId) -> &'tcx [Ty<'tcx>],
     [] adt_dtorck_constraint: DtorckConstraint(DefId) -> ty::DtorckConstraint<'tcx>,
 
+    /// True if this is a const fn
+    [] is_const_fn: IsConstFn(DefId) -> bool,
+
     /// True if this is a foreign item (i.e., linked via `extern { ... }`).
     [] is_foreign_item: IsForeignItem(DefId) -> bool,
 
@@ -929,6 +963,14 @@ define_maps! { <'tcx>
     [] needs_drop_raw: needs_drop_dep_node(ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool,
     [] layout_raw: layout_dep_node(ty::ParamEnvAnd<'tcx, Ty<'tcx>>)
                                   -> Result<&'tcx Layout, LayoutError<'tcx>>,
+
+    [] dylib_dependency_formats: DylibDepFormats(DefId)
+                                    -> Rc<Vec<(CrateNum, LinkagePreference)>>,
+
+    [] is_allocator: IsAllocator(DefId) -> bool,
+    [] is_panic_runtime: IsPanicRuntime(DefId) -> bool,
+
+    [] extern_crate: ExternCrate(DefId) -> Rc<Option<ExternCrate>>,
 }
 
 fn type_param_predicates((item_id, param_id): (DefId, DefId)) -> DepConstructor {
diff --git a/src/librustc_const_eval/eval.rs b/src/librustc_const_eval/eval.rs
index ec7510546a0..4ce985568ce 100644
--- a/src/librustc_const_eval/eval.rs
+++ b/src/librustc_const_eval/eval.rs
@@ -351,7 +351,7 @@ fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>,
                 signal!(e, TypeckError)
             }
           } else {
-            if tcx.sess.cstore.is_const_fn(def_id) {
+            if tcx.is_const_fn(def_id) {
                 tcx.sess.cstore.item_body(tcx, def_id)
             } else {
                 signal!(e, TypeckError)
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index 142454e0c4e..792be8bc6df 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -900,6 +900,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
     reachable::provide(&mut local_providers);
     rustc_const_eval::provide(&mut local_providers);
     middle::region::provide(&mut local_providers);
+    cstore::provide_local(&mut local_providers);
 
     let mut extern_providers = ty::maps::Providers::default();
     cstore::provide(&mut extern_providers);
@@ -1050,7 +1051,7 @@ pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
     time(time_passes,
          "resolving dependency formats",
-         || dependency_format::calculate(&tcx.sess));
+         || dependency_format::calculate(tcx));
 
     let translation =
         time(time_passes,
diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs
index 24647f26cf6..86146fe3947 100644
--- a/src/librustc_metadata/cstore.rs
+++ b/src/librustc_metadata/cstore.rs
@@ -34,7 +34,7 @@ pub use rustc::middle::cstore::{NativeLibrary, NativeLibraryKind, LinkagePrefere
 pub use rustc::middle::cstore::NativeLibraryKind::*;
 pub use rustc::middle::cstore::{CrateSource, LinkMeta, LibSource};
 
-pub use cstore_impl::provide;
+pub use cstore_impl::{provide, provide_local};
 
 // A map from external crate numbers (as decoded from some crate file) to
 // local crate numbers (as generated during this session). Each external
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index 34bd309a09c..c49712086d5 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -14,7 +14,7 @@ use schema;
 
 use rustc::dep_graph::DepTrackingMapConfig;
 use rustc::middle::cstore::{CrateStore, CrateSource, LibSource, DepKind,
-                            ExternCrate, NativeLibrary, MetadataLoader, LinkMeta,
+                            NativeLibrary, MetadataLoader, LinkMeta,
                             LinkagePreference, LoadedMacro, EncodedMetadata};
 use rustc::hir::def;
 use rustc::middle::lang_items;
@@ -23,6 +23,7 @@ use rustc::ty::{self, TyCtxt};
 use rustc::ty::maps::Providers;
 use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
 use rustc::hir::map::{DefKey, DefPath, DisambiguatedDefPathData, DefPathHash};
+use rustc::hir::map::blocks::FnLikeNode;
 use rustc::hir::map::definitions::{DefPathTable, GlobalMetaDataKind};
 use rustc::util::nodemap::{NodeSet, DefIdMap};
 use rustc_back::PanicStrategy;
@@ -39,7 +40,7 @@ use rustc::hir::svh::Svh;
 use rustc::hir;
 
 macro_rules! provide {
-    (<$lt:tt> $tcx:ident, $def_id:ident, $cdata:ident $($name:ident => $compute:block)*) => {
+    (<$lt:tt> $tcx:ident, $def_id:ident, $cdata:ident, $($name:ident => $compute:block)*) => {
         pub fn provide<$lt>(providers: &mut Providers<$lt>) {
             $(fn $name<'a, $lt:$lt>($tcx: TyCtxt<'a, $lt, $lt>, $def_id: DefId)
                                     -> <ty::queries::$name<$lt> as
@@ -65,7 +66,7 @@ macro_rules! provide {
     }
 }
 
-provide! { <'tcx> tcx, def_id, cdata
+provide! { <'tcx> tcx, def_id, cdata,
     type_of => { cdata.get_type(def_id.index, tcx) }
     generics_of => { tcx.alloc_generics(cdata.get_generics(def_id.index)) }
     predicates_of => { cdata.get_predicates(def_id.index, tcx) }
@@ -81,7 +82,8 @@ provide! { <'tcx> tcx, def_id, cdata
     variances_of => { Rc::new(cdata.get_item_variances(def_id.index)) }
     associated_item_def_ids => {
         let mut result = vec![];
-        cdata.each_child_of_item(def_id.index, |child| result.push(child.def.def_id()), tcx.sess);
+        cdata.each_child_of_item(def_id.index,
+          |child| result.push(child.def.def_id()), tcx.sess);
         Rc::new(result)
     }
     associated_item => { cdata.get_associated_item(def_id.index) }
@@ -106,6 +108,7 @@ provide! { <'tcx> tcx, def_id, cdata
     closure_kind => { cdata.closure_kind(def_id.index) }
     closure_type => { cdata.closure_ty(def_id.index, tcx) }
     inherent_impls => { Rc::new(cdata.get_inherent_implementations_for_type(def_id.index)) }
+    is_const_fn => { cdata.is_const_fn(def_id.index) }
     is_foreign_item => { cdata.is_foreign_item(def_id.index) }
     is_default_impl => { cdata.is_default_impl(def_id.index) }
     describe_def => { cdata.get_def(def_id.index) }
@@ -129,6 +132,29 @@ provide! { <'tcx> tcx, def_id, cdata
         cdata.const_is_rvalue_promotable_to_static(def_id.index)
     }
     is_mir_available => { cdata.is_item_mir_available(def_id.index) }
+
+    dylib_dependency_formats => { Rc::new(cdata.get_dylib_dependency_formats(&tcx.dep_graph)) }
+    is_allocator => { cdata.is_allocator(&tcx.dep_graph) }
+    is_panic_runtime => { cdata.is_panic_runtime(&tcx.dep_graph) }
+    extern_crate => { Rc::new(cdata.extern_crate.get()) }
+}
+
+pub fn provide_local<'tcx>(providers: &mut Providers<'tcx>) {
+    fn is_const_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> bool {
+        let node_id = tcx.hir.as_local_node_id(def_id)
+                             .expect("Non-local call to local provider is_const_fn");
+
+        if let Some(fn_like) = FnLikeNode::from_node(tcx.hir.get(node_id)) {
+            fn_like.constness() == hir::Constness::Const
+        } else {
+            false
+        }
+    }
+
+    *providers = Providers {
+        is_const_fn,
+        ..*providers
+    };
 }
 
 impl CrateStore for cstore::CStore {
@@ -172,12 +198,6 @@ impl CrateStore for cstore::CStore {
         self.get_crate_data(def.krate).get_associated_item(def.index)
     }
 
-    fn is_const_fn(&self, did: DefId) -> bool
-    {
-        self.read_dep_node(did);
-        self.get_crate_data(did.krate).is_const_fn(did.index)
-    }
-
     fn is_statically_included_foreign_item(&self, def_id: DefId) -> bool
     {
         self.do_is_statically_included_foreign_item(def_id)
@@ -192,12 +212,6 @@ impl CrateStore for cstore::CStore {
         }
     }
 
-    fn dylib_dependency_formats(&self, cnum: CrateNum)
-                                -> Vec<(CrateNum, LinkagePreference)>
-    {
-        self.get_crate_data(cnum).get_dylib_dependency_formats(&self.dep_graph)
-    }
-
     fn dep_kind(&self, cnum: CrateNum) -> DepKind
     {
         let data = self.get_crate_data(cnum);
@@ -227,16 +241,6 @@ impl CrateStore for cstore::CStore {
         self.get_crate_data(cnum).get_missing_lang_items(&self.dep_graph)
     }
 
-    fn is_allocator(&self, cnum: CrateNum) -> bool
-    {
-        self.get_crate_data(cnum).is_allocator(&self.dep_graph)
-    }
-
-    fn is_panic_runtime(&self, cnum: CrateNum) -> bool
-    {
-        self.get_crate_data(cnum).is_panic_runtime(&self.dep_graph)
-    }
-
     fn is_compiler_builtins(&self, cnum: CrateNum) -> bool {
         self.get_crate_data(cnum).is_compiler_builtins(&self.dep_graph)
     }
@@ -263,11 +267,6 @@ impl CrateStore for cstore::CStore {
         self.get_crate_data(cnum).name()
     }
 
-    fn extern_crate(&self, cnum: CrateNum) -> Option<ExternCrate>
-    {
-        self.get_crate_data(cnum).extern_crate.get()
-    }
-
     fn crate_hash(&self, cnum: CrateNum) -> Svh
     {
         self.get_crate_hash(cnum)
diff --git a/src/librustc_mir/transform/copy_prop.rs b/src/librustc_mir/transform/copy_prop.rs
index 08a4961c6cd..dec0717e9e3 100644
--- a/src/librustc_mir/transform/copy_prop.rs
+++ b/src/librustc_mir/transform/copy_prop.rs
@@ -34,7 +34,6 @@ use rustc::mir::transform::{MirPass, MirSource};
 use rustc::mir::visit::MutVisitor;
 use rustc::ty::TyCtxt;
 use util::def_use::DefUseAnalysis;
-use transform::qualify_consts;
 
 pub struct CopyPropagation;
 
@@ -55,7 +54,7 @@ impl MirPass for CopyPropagation {
                 return
             }
             MirSource::Fn(function_node_id) => {
-                if qualify_consts::is_const_fn(tcx, tcx.hir.local_def_id(function_node_id)) {
+                if tcx.is_const_fn(tcx.hir.local_def_id(function_node_id)) {
                     // Don't run on const functions, as, again, trans might not be able to evaluate
                     // the optimized IR.
                     return
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index d60e761bc0b..8342d0ff491 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -19,7 +19,6 @@ use rustc_data_structures::indexed_vec::{IndexVec, Idx};
 use rustc::hir;
 use rustc::hir::map as hir_map;
 use rustc::hir::def_id::DefId;
-use rustc::hir::map::blocks::FnLikeNode;
 use rustc::traits::{self, Reveal};
 use rustc::ty::{self, TyCtxt, Ty, TypeFoldable};
 use rustc::ty::cast::CastTy;
@@ -109,18 +108,6 @@ impl fmt::Display for Mode {
     }
 }
 
-pub fn is_const_fn(tcx: TyCtxt, def_id: DefId) -> bool {
-    if let Some(node_id) = tcx.hir.as_local_node_id(def_id) {
-        if let Some(fn_like) = FnLikeNode::from_node(tcx.hir.get(node_id)) {
-            fn_like.constness() == hir::Constness::Const
-        } else {
-            false
-        }
-    } else {
-        tcx.sess.cstore.is_const_fn(def_id)
-    }
-}
-
 struct Qualifier<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
     mode: Mode,
     span: Span,
@@ -766,7 +753,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
                 ty::TyFnDef(def_id, _, f) => {
                     (f.abi() == Abi::PlatformIntrinsic &&
                      self.tcx.item_name(def_id).as_str().starts_with("simd_shuffle"),
-                     is_const_fn(self.tcx, def_id))
+                     self.tcx.is_const_fn(def_id))
                 }
                 _ => (false, false)
             };
@@ -957,7 +944,7 @@ impl MirPass for QualifyAndPromoteConstants {
         let def_id = tcx.hir.local_def_id(id);
         let mode = match src {
             MirSource::Fn(_) => {
-                if is_const_fn(tcx, def_id) {
+                if tcx.is_const_fn(def_id) {
                     Mode::ConstFn
                 } else {
                     Mode::Fn
diff --git a/src/librustc_passes/consts.rs b/src/librustc_passes/consts.rs
index e539cc1ae8b..bec4c083905 100644
--- a/src/librustc_passes/consts.rs
+++ b/src/librustc_passes/consts.rs
@@ -101,7 +101,7 @@ impl<'a, 'gcx> CheckCrateVisitor<'a, 'gcx> {
                 fn_like.constness() == hir::Constness::Const
             })
         } else {
-            self.tcx.sess.cstore.is_const_fn(def_id)
+            self.tcx.is_const_fn(def_id)
         };
     }
 }
diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs
index 4802494f08e..4ab2c1aa63c 100644
--- a/src/librustc_save_analysis/lib.rs
+++ b/src/librustc_save_analysis/lib.rs
@@ -107,7 +107,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
         let mut result = Vec::new();
 
         for n in self.tcx.sess.cstore.crates() {
-            let span = match self.tcx.sess.cstore.extern_crate(n) {
+            let span = match *self.tcx.extern_crate(n.as_def_id()) {
                 Some(ref c) => c.span,
                 None => {
                     debug!("Skipping crate {}, no data", n);
diff --git a/src/librustc_trans/back/symbol_export.rs b/src/librustc_trans/back/symbol_export.rs
index ef75de04045..b38dc188389 100644
--- a/src/librustc_trans/back/symbol_export.rs
+++ b/src/librustc_trans/back/symbol_export.rs
@@ -92,8 +92,8 @@ impl ExportedSymbols {
             // Down below we'll hardwire all of the symbols to the `Rust` export
             // level instead.
             let special_runtime_crate =
-                scx.sess().cstore.is_allocator(cnum) ||
-                scx.sess().cstore.is_panic_runtime(cnum) ||
+                scx.tcx().is_allocator(cnum.as_def_id()) ||
+                scx.tcx().is_panic_runtime(cnum.as_def_id()) ||
                 scx.sess().cstore.is_compiler_builtins(cnum);
 
             let crate_exports = scx
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index a5797a5224d..aeade470482 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -151,7 +151,7 @@ pub fn build_external_trait(cx: &DocContext, did: DefId) -> clean::Trait {
 fn build_external_function(cx: &DocContext, did: DefId) -> clean::Function {
     let sig = cx.tcx.type_of(did).fn_sig();
 
-    let constness = if cx.tcx.sess.cstore.is_const_fn(did) {
+    let constness = if cx.tcx.is_const_fn(did) {
         hir::Constness::Const
     } else {
         hir::Constness::NotConst
@@ -352,7 +352,7 @@ pub fn build_impl(cx: &DocContext, did: DefId, ret: &mut Vec<clean::Item>) {
                     clean::TyMethodItem(clean::TyMethod {
                         unsafety, decl, generics, abi
                     }) => {
-                        let constness = if tcx.sess.cstore.is_const_fn(item.def_id) {
+                        let constness = if tcx.is_const_fn(item.def_id) {
                             hir::Constness::Const
                         } else {
                             hir::Constness::NotConst