From ef96a417a714855b3765a003d6d0055d1f570ba0 Mon Sep 17 00:00:00 2001
From: Michael Woerister <michaelwoerister@posteo>
Date: Tue, 5 Sep 2017 16:48:24 +0200
Subject: [PATCH] Remove the `cstore` reference from Session in order to
 prepare encapsulating CrateStore access in tcx.

---
 src/librustc/hir/lowering.rs                 |   9 +-
 src/librustc/infer/error_reporting/mod.rs    |   2 +-
 src/librustc/middle/dependency_format.rs     |  63 ++++++------
 src/librustc/middle/lang_items.rs            |  23 +++--
 src/librustc/middle/resolve_lifetime.rs      |  13 ++-
 src/librustc/middle/stability.rs             |   4 +-
 src/librustc/middle/weak_lang_items.rs       |  12 ++-
 src/librustc/session/config.rs               |  17 ++--
 src/librustc/session/mod.rs                  |  14 +--
 src/librustc/traits/util.rs                  |   4 +-
 src/librustc/ty/context.rs                   |  23 +++--
 src/librustc/ty/item_path.rs                 |   4 +-
 src/librustc/ty/mod.rs                       |  12 +--
 src/librustc/ty/trait_def.rs                 |   2 +-
 src/librustc_const_eval/eval.rs              |   4 +-
 src/librustc_const_eval/pattern.rs           |   2 +-
 src/librustc_driver/driver.rs                |  28 +++--
 src/librustc_driver/lib.rs                   |  27 +++--
 src/librustc_driver/pretty.rs                |   9 ++
 src/librustc_driver/test.rs                  |   8 +-
 src/librustc_incremental/persist/fs.rs       |   2 +-
 src/librustc_incremental/persist/hash.rs     |   2 +-
 src/librustc_lint/builtin.rs                 |   4 +-
 src/librustc_metadata/cstore_impl.rs         |   2 +-
 src/librustc_metadata/encoder.rs             |   5 +-
 src/librustc_privacy/lib.rs                  |   2 +-
 src/librustc_resolve/build_reduced_graph.rs  |  26 ++---
 src/librustc_resolve/lib.rs                  |   8 +-
 src/librustc_resolve/macros.rs               |   2 +-
 src/librustc_resolve/resolve_imports.rs      |   2 +-
 src/librustc_save_analysis/lib.rs            |   4 +-
 src/librustc_trans/back/link.rs              | 101 +++++++++++--------
 src/librustc_trans/back/symbol_export.rs     |  11 +-
 src/librustc_trans/back/write.rs             |   9 +-
 src/librustc_trans/base.rs                   |   6 +-
 src/librustc_trans/callee.rs                 |   2 +-
 src/librustc_trans/consts.rs                 |   2 +-
 src/librustc_typeck/check/method/suggest.rs  |   4 +-
 src/librustc_typeck/check_unused.rs          |   2 +-
 src/librustdoc/clean/inline.rs               |  10 +-
 src/librustdoc/clean/mod.rs                  |   4 +-
 src/librustdoc/core.rs                       |   3 +-
 src/librustdoc/test.rs                       |   4 +-
 src/librustdoc/visit_ast.rs                  |   6 +-
 src/librustdoc/visit_lib.rs                  |   2 +-
 src/test/run-make/issue-19371/foo.rs         |   2 +-
 src/test/run-pass-fulldeps/compiler-calls.rs |   2 +
 47 files changed, 291 insertions(+), 218 deletions(-)

diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 0f69c06c417a1..1dbe4517ab39e 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -46,6 +46,7 @@ use hir::map::definitions::DefPathData;
 use hir::def_id::{DefIndex, DefId, CRATE_DEF_INDEX};
 use hir::def::{Def, PathResolution};
 use lint::builtin::PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES;
+use middle::cstore::CrateStore;
 use rustc_data_structures::indexed_vec::IndexVec;
 use session::Session;
 use util::common::FN_OUTPUT_NAME;
@@ -75,6 +76,8 @@ pub struct LoweringContext<'a> {
     // Use to assign ids to hir nodes that do not directly correspond to an ast node
     sess: &'a Session,
 
+    cstore: &'a CrateStore,
+
     // As we walk the AST we must keep track of the current 'parent' def id (in
     // the form of a DefIndex) so that if we create a new node which introduces
     // a definition, then we can properly create the def id.
@@ -119,6 +122,7 @@ pub trait Resolver {
 }
 
 pub fn lower_crate(sess: &Session,
+                   cstore: &CrateStore,
                    krate: &Crate,
                    resolver: &mut Resolver)
                    -> hir::Crate {
@@ -130,6 +134,7 @@ pub fn lower_crate(sess: &Session,
     LoweringContext {
         crate_root: std_inject::injected_crate_name(krate),
         sess,
+        cstore,
         parent_def: None,
         resolver,
         name_map: FxHashMap(),
@@ -535,7 +540,7 @@ impl<'a> LoweringContext<'a> {
         if id.is_local() {
             self.resolver.definitions().def_key(id.index)
         } else {
-            self.sess.cstore.def_key(id)
+            self.cstore.def_key(id)
         }
     }
 
@@ -787,7 +792,7 @@ impl<'a> LoweringContext<'a> {
                         return n;
                     }
                     assert!(!def_id.is_local());
-                    let n = self.sess.cstore.item_generics_cloned(def_id).regions.len();
+                    let n = self.cstore.item_generics_cloned(def_id).regions.len();
                     self.type_def_lifetime_params.insert(def_id, n);
                     n
                 });
diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs
index 476bf94714268..2cd46ea383823 100644
--- a/src/librustc/infer/error_reporting/mod.rs
+++ b/src/librustc/infer/error_reporting/mod.rs
@@ -357,7 +357,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                 // for imported and non-imported crates
                 if exp_path == found_path
                 || exp_abs_path == found_abs_path {
-                    let crate_name = self.tcx.sess.cstore.crate_name(did1.krate);
+                    let crate_name = self.tcx.cstore().crate_name(did1.krate);
                     err.span_note(sp, &format!("Perhaps two different versions \
                                                 of crate `{}` are being used?",
                                                crate_name));
diff --git a/src/librustc/middle/dependency_format.rs b/src/librustc/middle/dependency_format.rs
index 837ab4fd4a3cc..6022b5001c605 100644
--- a/src/librustc/middle/dependency_format.rs
+++ b/src/librustc/middle/dependency_format.rs
@@ -66,7 +66,7 @@ use hir::def_id::CrateNum;
 use session;
 use session::config;
 use ty::TyCtxt;
-use middle::cstore::DepKind;
+use middle::cstore::{CrateStore, DepKind};
 use middle::cstore::LinkagePreference::{self, RequireStatic, RequireDynamic};
 use util::nodemap::FxHashMap;
 use rustc_back::PanicStrategy;
@@ -132,12 +132,12 @@ 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() {
-                if sess.cstore.dep_kind(cnum).macros_only() { continue }
-                let src = sess.cstore.used_crate_source(cnum);
+            for cnum in tcx.cstore().crates() {
+                if tcx.cstore().dep_kind(cnum).macros_only() { continue }
+                let src = tcx.cstore().used_crate_source(cnum);
                 if src.rlib.is_some() { continue }
                 sess.err(&format!("dependency `{}` not found in rlib format",
-                                  sess.cstore.crate_name(cnum)));
+                                  tcx.cstore().crate_name(cnum)));
             }
             return Vec::new();
         }
@@ -165,24 +165,24 @@ 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() {
-        if sess.cstore.dep_kind(cnum).macros_only() { continue }
-        let name = sess.cstore.crate_name(cnum);
-        let src = sess.cstore.used_crate_source(cnum);
+    for cnum in tcx.cstore().crates() {
+        if tcx.cstore().dep_kind(cnum).macros_only() { continue }
+        let name = tcx.cstore().crate_name(cnum);
+        let src = tcx.cstore().used_crate_source(cnum);
         if src.dylib.is_some() {
             info!("adding dylib: {}", name);
-            add_library(sess, cnum, RequireDynamic, &mut formats);
+            add_library(sess, tcx.cstore(), cnum, RequireDynamic, &mut formats);
             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);
+                      tcx.cstore().crate_name(depnum));
+                add_library(sess, tcx.cstore(), depnum, style, &mut formats);
             }
         }
     }
 
     // Collect what we've got so far in the return vector.
-    let last_crate = sess.cstore.crates().len();
+    let last_crate = tcx.cstore().crates().len();
     let mut ret = (1..last_crate+1).map(|cnum| {
         match formats.get(&CrateNum::new(cnum)) {
             Some(&RequireDynamic) => Linkage::Dynamic,
@@ -196,14 +196,14 @@ 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() {
-        let src = sess.cstore.used_crate_source(cnum);
+    for cnum in tcx.cstore().crates() {
+        let src = tcx.cstore().used_crate_source(cnum);
         if src.dylib.is_none() &&
            !formats.contains_key(&cnum) &&
-           sess.cstore.dep_kind(cnum) == DepKind::Explicit {
+           tcx.cstore().dep_kind(cnum) == DepKind::Explicit {
             assert!(src.rlib.is_some() || src.rmeta.is_some());
-            info!("adding staticlib: {}", sess.cstore.crate_name(cnum));
-            add_library(sess, cnum, RequireStatic, &mut formats);
+            info!("adding staticlib: {}", tcx.cstore().crate_name(cnum));
+            add_library(sess, tcx.cstore(), cnum, RequireStatic, &mut formats);
             ret[cnum.as_usize() - 1] = Linkage::Static;
         }
     }
@@ -226,7 +226,7 @@ fn calculate_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     // making sure that everything is available in the requested format.
     for (cnum, kind) in ret.iter().enumerate() {
         let cnum = CrateNum::new(cnum + 1);
-        let src = sess.cstore.used_crate_source(cnum);
+        let src = tcx.cstore().used_crate_source(cnum);
         match *kind {
             Linkage::NotLinked |
             Linkage::IncludedFromDylib => {}
@@ -237,7 +237,7 @@ fn calculate_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                     Linkage::Static => "rlib",
                     _ => "dylib",
                 };
-                let name = sess.cstore.crate_name(cnum);
+                let name = tcx.cstore().crate_name(cnum);
                 sess.err(&format!("crate `{}` required to be available in {}, \
                                   but it was not available in this form",
                                   name, kind));
@@ -249,6 +249,7 @@ fn calculate_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 }
 
 fn add_library(sess: &session::Session,
+               cstore: &CrateStore,
                cnum: CrateNum,
                link: LinkagePreference,
                m: &mut FxHashMap<CrateNum, LinkagePreference>) {
@@ -263,7 +264,7 @@ fn add_library(sess: &session::Session,
             // can be refined over time.
             if link2 != link || link == RequireStatic {
                 sess.struct_err(&format!("cannot satisfy dependencies so `{}` only \
-                                          shows up once", sess.cstore.crate_name(cnum)))
+                                          shows up once", cstore.crate_name(cnum)))
                     .help("having upstream crates all available in one format \
                            will likely make this go away")
                     .emit();
@@ -275,16 +276,16 @@ fn add_library(sess: &session::Session,
 
 fn attempt_static<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Option<DependencyList> {
     let sess = &tcx.sess;
-    let crates = sess.cstore.used_crates(RequireStatic);
+    let crates = tcx.cstore().used_crates(RequireStatic);
     if !crates.iter().by_ref().all(|&(_, ref p)| p.is_some()) {
         return None
     }
 
     // All crates are available in an rlib format, so we're just going to link
     // everything in explicitly so long as it's actually required.
-    let last_crate = sess.cstore.crates().len();
+    let last_crate = tcx.cstore().crates().len();
     let mut ret = (1..last_crate+1).map(|cnum| {
-        if sess.cstore.dep_kind(CrateNum::new(cnum)) == DepKind::Explicit {
+        if tcx.cstore().dep_kind(CrateNum::new(cnum)) == DepKind::Explicit {
             Linkage::Static
         } else {
             Linkage::NotLinked
@@ -357,13 +358,13 @@ fn verify_ok<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, list: &[Linkage]) {
 
         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);
+                let prev_name = tcx.cstore().crate_name(prev);
+                let cur_name = tcx.cstore().crate_name(cnum);
                 sess.err(&format!("cannot link together two \
                                    panic runtimes: {} and {}",
                                   prev_name, cur_name));
             }
-            panic_runtime = Some((cnum, sess.cstore.panic_strategy(cnum)));
+            panic_runtime = Some((cnum, tcx.cstore().panic_strategy(cnum)));
         }
     }
 
@@ -379,7 +380,7 @@ fn verify_ok<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, list: &[Linkage]) {
             sess.err(&format!("the linked panic runtime `{}` is \
                                not compiled with this crate's \
                                panic strategy `{}`",
-                              sess.cstore.crate_name(cnum),
+                              tcx.cstore().crate_name(cnum),
                               desired_strategy.desc()));
         }
 
@@ -395,8 +396,8 @@ fn verify_ok<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, list: &[Linkage]) {
                 continue
             }
             let cnum = CrateNum::new(i + 1);
-            let found_strategy = sess.cstore.panic_strategy(cnum);
-            let is_compiler_builtins = sess.cstore.is_compiler_builtins(cnum);
+            let found_strategy = tcx.cstore().panic_strategy(cnum);
+            let is_compiler_builtins = tcx.cstore().is_compiler_builtins(cnum);
             if is_compiler_builtins || desired_strategy == found_strategy {
                 continue
             }
@@ -405,7 +406,7 @@ fn verify_ok<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, list: &[Linkage]) {
                                panic strategy `{}` which is \
                                incompatible with this crate's \
                                strategy of `{}`",
-                              sess.cstore.crate_name(cnum),
+                              tcx.cstore().crate_name(cnum),
                               found_strategy.desc(),
                               desired_strategy.desc()));
         }
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index ae3e3a30f371e..9d62991bd5c97 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -25,6 +25,7 @@ use hir::map as hir_map;
 use session::Session;
 use hir::def_id::DefId;
 use ty;
+use middle::cstore::CrateStore;
 use middle::weak_lang_items;
 use util::nodemap::FxHashMap;
 
@@ -115,11 +116,9 @@ impl LanguageItems {
 
 struct LanguageItemCollector<'a, 'tcx: 'a> {
     items: LanguageItems,
-
     hir_map: &'a hir_map::Map<'tcx>,
-
     session: &'a Session,
-
+    cstore: &'a CrateStore,
     item_refs: FxHashMap<&'static str, usize>,
 }
 
@@ -149,7 +148,9 @@ impl<'a, 'v, 'tcx> ItemLikeVisitor<'v> for LanguageItemCollector<'a, 'tcx> {
 }
 
 impl<'a, 'tcx> LanguageItemCollector<'a, 'tcx> {
-    pub fn new(session: &'a Session, hir_map: &'a hir_map::Map<'tcx>)
+    pub fn new(session: &'a Session,
+               cstore: &'a CrateStore,
+               hir_map: &'a hir_map::Map<'tcx>)
                -> LanguageItemCollector<'a, 'tcx> {
         let mut item_refs = FxHashMap();
 
@@ -157,6 +158,7 @@ impl<'a, 'tcx> LanguageItemCollector<'a, 'tcx> {
 
         LanguageItemCollector {
             session,
+            cstore,
             hir_map,
             items: LanguageItems::new(),
             item_refs,
@@ -168,7 +170,7 @@ impl<'a, 'tcx> LanguageItemCollector<'a, 'tcx> {
         // Check for duplicates.
         match self.items.items[item_index] {
             Some(original_def_id) if original_def_id != item_def_id => {
-                let cstore = &self.session.cstore;
+                let cstore = self.cstore;
                 let name = LanguageItems::item_name(item_index);
                 let mut err = match self.hir_map.span_if_local(item_def_id) {
                     Some(span) => struct_span_err!(
@@ -205,10 +207,8 @@ impl<'a, 'tcx> LanguageItemCollector<'a, 'tcx> {
     }
 
     pub fn collect_external_language_items(&mut self) {
-        let cstore = &self.session.cstore;
-
-        for cnum in cstore.crates() {
-            for (index, item_index) in cstore.lang_items(cnum) {
+        for cnum in self.cstore.crates() {
+            for (index, item_index) in self.cstore.lang_items(cnum) {
                 let def_id = DefId { krate: cnum, index: index };
                 self.collect_item(item_index, def_id);
             }
@@ -234,13 +234,14 @@ pub fn extract(attrs: &[ast::Attribute]) -> Option<Symbol> {
 }
 
 pub fn collect_language_items(session: &Session,
+                              cstore: &CrateStore,
                               map: &hir_map::Map)
                               -> LanguageItems {
     let krate: &hir::Crate = map.krate();
-    let mut collector = LanguageItemCollector::new(session, map);
+    let mut collector = LanguageItemCollector::new(session, cstore, map);
     collector.collect(krate);
     let LanguageItemCollector { mut items, .. } = collector;
-    weak_lang_items::check_crate(krate, session, &mut items);
+    weak_lang_items::check_crate(krate, session, cstore, &mut items);
     items
 }
 
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index a8e98e53db394..2a6302407df68 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -16,9 +16,10 @@
 //! way. Therefore we break lifetime name resolution into a separate pass.
 
 use hir::map::Map;
-use session::Session;
 use hir::def::Def;
 use hir::def_id::DefId;
+use middle::cstore::CrateStore;
+use session::Session;
 use ty;
 
 use std::cell::Cell;
@@ -160,6 +161,7 @@ pub struct NamedRegionMap {
 
 struct LifetimeContext<'a, 'tcx: 'a> {
     sess: &'a Session,
+    cstore: &'a CrateStore,
     hir_map: &'a Map<'tcx>,
     map: &'a mut NamedRegionMap,
     scope: ScopeRef<'a>,
@@ -251,6 +253,7 @@ type ScopeRef<'a> = &'a Scope<'a>;
 const ROOT_SCOPE: ScopeRef<'static> = &Scope::Root;
 
 pub fn krate(sess: &Session,
+             cstore: &CrateStore,
              hir_map: &Map)
              -> Result<NamedRegionMap, ErrorReported> {
     let krate = hir_map.krate();
@@ -262,6 +265,7 @@ pub fn krate(sess: &Session,
     sess.track_errors(|| {
         let mut visitor = LifetimeContext {
             sess,
+            cstore,
             hir_map,
             map: &mut map,
             scope: ROOT_SCOPE,
@@ -765,12 +769,13 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
     fn with<F>(&mut self, wrap_scope: Scope, f: F) where
         F: for<'b> FnOnce(ScopeRef, &mut LifetimeContext<'b, 'tcx>),
     {
-        let LifetimeContext {sess, hir_map, ref mut map, ..} = *self;
+        let LifetimeContext {sess, cstore, hir_map, ref mut map, ..} = *self;
         let labels_in_fn = replace(&mut self.labels_in_fn, vec![]);
         let xcrate_object_lifetime_defaults =
             replace(&mut self.xcrate_object_lifetime_defaults, DefIdMap());
         let mut this = LifetimeContext {
             sess,
+            cstore,
             hir_map,
             map: *map,
             scope: &wrap_scope,
@@ -932,7 +937,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
             let def_key = if def_id.is_local() {
                 this.hir_map.def_key(def_id)
             } else {
-                this.sess.cstore.def_key(def_id)
+                this.cstore.def_key(def_id)
             };
             DefId {
                 krate: def_id.krate,
@@ -976,7 +981,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
             let unsubst = if let Some(id) = self.hir_map.as_local_node_id(def_id) {
                 &map.object_lifetime_defaults[&id]
             } else {
-                let cstore = &self.sess.cstore;
+                let cstore = self.cstore;
                 self.xcrate_object_lifetime_defaults.entry(def_id).or_insert_with(|| {
                     cstore.item_generics_cloned(def_id).types.into_iter().map(|def| {
                         def.object_lifetime_default
diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs
index d2ed29a3a0ff6..4664b2393d340 100644
--- a/src/librustc/middle/stability.rs
+++ b/src/librustc/middle/stability.rs
@@ -476,7 +476,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
             _ => {}
         }
 
-        let visibility = self.sess.cstore.visibility(def_id);
+        let visibility = self.cstore().visibility(def_id);
 
         match visibility {
             // must check stability for pub items.
@@ -610,7 +610,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
                 // compiler-generated `extern crate` items have a dummy span.
                 if item.span == DUMMY_SP { return }
 
-                let cnum = match self.tcx.sess.cstore.extern_mod_stmt_cnum(item.id) {
+                let cnum = match self.tcx.cstore().extern_mod_stmt_cnum(item.id) {
                     Some(cnum) => cnum,
                     None => return,
                 };
diff --git a/src/librustc/middle/weak_lang_items.rs b/src/librustc/middle/weak_lang_items.rs
index acb506878e6b6..cdbd74dae274f 100644
--- a/src/librustc/middle/weak_lang_items.rs
+++ b/src/librustc/middle/weak_lang_items.rs
@@ -13,6 +13,7 @@
 use session::config;
 use session::Session;
 use middle::lang_items;
+use middle::cstore::CrateStore;
 
 use rustc_back::PanicStrategy;
 use syntax::ast;
@@ -36,6 +37,7 @@ struct Context<'a> {
 /// language items required by this crate, but not defined yet.
 pub fn check_crate(krate: &hir::Crate,
                    sess: &Session,
+                   cstore: &CrateStore,
                    items: &mut lang_items::LanguageItems) {
     // These are never called by user code, they're generated by the compiler.
     // They will never implicitly be added to the `missing` array unless we do
@@ -52,7 +54,7 @@ pub fn check_crate(krate: &hir::Crate,
         let mut cx = Context { sess: sess, items: items };
         krate.visit_all_item_likes(&mut cx.as_deep_visitor());
     }
-    verify(sess, items);
+    verify(sess, cstore, items);
 }
 
 pub fn link_name(attrs: &[ast::Attribute]) -> Option<Symbol> {
@@ -65,7 +67,9 @@ pub fn link_name(attrs: &[ast::Attribute]) -> Option<Symbol> {
     })
 }
 
-fn verify(sess: &Session, items: &lang_items::LanguageItems) {
+fn verify(sess: &Session,
+          cstore: &CrateStore,
+          items: &lang_items::LanguageItems) {
     // We only need to check for the presence of weak lang items if we're
     // emitting something that's not an rlib.
     let needs_check = sess.crate_types.borrow().iter().any(|kind| {
@@ -83,8 +87,8 @@ fn verify(sess: &Session, items: &lang_items::LanguageItems) {
     }
 
     let mut missing = HashSet::new();
-    for cnum in sess.cstore.crates() {
-        for item in sess.cstore.missing_lang_items(cnum) {
+    for cnum in cstore.crates() {
+        for item in cstore.missing_lang_items(cnum) {
             missing.insert(item);
         }
     }
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 99fe8e60ae52b..f967c4e9c5d83 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -1949,13 +1949,12 @@ mod tests {
     use errors;
     use getopts;
     use lint;
-    use middle::cstore::{self, DummyCrateStore};
+    use middle::cstore;
     use session::config::{build_configuration, build_session_options_and_crate_config};
     use session::build_session;
     use std::collections::{BTreeMap, BTreeSet};
     use std::iter::FromIterator;
     use std::path::PathBuf;
-    use std::rc::Rc;
     use super::{OutputType, OutputTypes, Externs};
     use rustc_back::{PanicStrategy, RelroLevel};
     use syntax::symbol::Symbol;
@@ -1987,7 +1986,7 @@ mod tests {
             };
         let registry = errors::registry::Registry::new(&[]);
         let (sessopts, cfg) = build_session_options_and_crate_config(matches);
-        let sess = build_session(sessopts, &dep_graph, None, registry, Rc::new(DummyCrateStore));
+        let sess = build_session(sessopts, &dep_graph, None, registry);
         let cfg = build_configuration(&sess, cfg);
         assert!(cfg.contains(&(Symbol::intern("test"), None)));
     }
@@ -2006,8 +2005,7 @@ mod tests {
             };
         let registry = errors::registry::Registry::new(&[]);
         let (sessopts, cfg) = build_session_options_and_crate_config(matches);
-        let sess = build_session(sessopts, &dep_graph, None, registry,
-                                 Rc::new(DummyCrateStore));
+        let sess = build_session(sessopts, &dep_graph, None, registry);
         let cfg = build_configuration(&sess, cfg);
         let mut test_items = cfg.iter().filter(|&&(name, _)| name == "test");
         assert!(test_items.next().is_some());
@@ -2023,8 +2021,7 @@ mod tests {
             ]).unwrap();
             let registry = errors::registry::Registry::new(&[]);
             let (sessopts, _) = build_session_options_and_crate_config(&matches);
-            let sess = build_session(sessopts, &dep_graph, None, registry,
-                                     Rc::new(DummyCrateStore));
+            let sess = build_session(sessopts, &dep_graph, None, registry);
             assert!(!sess.diagnostic().can_emit_warnings);
         }
 
@@ -2035,8 +2032,7 @@ mod tests {
             ]).unwrap();
             let registry = errors::registry::Registry::new(&[]);
             let (sessopts, _) = build_session_options_and_crate_config(&matches);
-            let sess = build_session(sessopts, &dep_graph, None, registry,
-                                     Rc::new(DummyCrateStore));
+            let sess = build_session(sessopts, &dep_graph, None, registry);
             assert!(sess.diagnostic().can_emit_warnings);
         }
 
@@ -2046,8 +2042,7 @@ mod tests {
             ]).unwrap();
             let registry = errors::registry::Registry::new(&[]);
             let (sessopts, _) = build_session_options_and_crate_config(&matches);
-            let sess = build_session(sessopts, &dep_graph, None, registry,
-                                     Rc::new(DummyCrateStore));
+            let sess = build_session(sessopts, &dep_graph, None, registry);
             assert!(sess.diagnostic().can_emit_warnings);
         }
     }
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index 823a637c7e0d4..87afdae116ed4 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -15,7 +15,6 @@ use dep_graph::DepGraph;
 use hir::def_id::{CrateNum, DefIndex};
 
 use lint;
-use middle::cstore::CrateStore;
 use middle::allocator::AllocatorKind;
 use middle::dependency_format;
 use session::search_paths::PathKind;
@@ -63,7 +62,6 @@ pub struct Session {
     pub target: config::Config,
     pub host: Target,
     pub opts: config::Options,
-    pub cstore: Rc<CrateStore>,
     pub parse_sess: ParseSess,
     // For a library crate, this is always none
     pub entry_fn: RefCell<Option<(NodeId, Span)>>,
@@ -617,8 +615,7 @@ impl Session {
 pub fn build_session(sopts: config::Options,
                      dep_graph: &DepGraph,
                      local_crate_source_file: Option<PathBuf>,
-                     registry: errors::registry::Registry,
-                     cstore: Rc<CrateStore>)
+                     registry: errors::registry::Registry)
                      -> Session {
     let file_path_mapping = sopts.file_path_mapping();
 
@@ -626,7 +623,6 @@ pub fn build_session(sopts: config::Options,
                                dep_graph,
                                local_crate_source_file,
                                registry,
-                               cstore,
                                Rc::new(codemap::CodeMap::new(file_path_mapping)),
                                None)
 }
@@ -635,7 +631,6 @@ pub fn build_session_with_codemap(sopts: config::Options,
                                   dep_graph: &DepGraph,
                                   local_crate_source_file: Option<PathBuf>,
                                   registry: errors::registry::Registry,
-                                  cstore: Rc<CrateStore>,
                                   codemap: Rc<codemap::CodeMap>,
                                   emitter_dest: Option<Box<Write + Send>>)
                                   -> Session {
@@ -676,16 +671,14 @@ pub fn build_session_with_codemap(sopts: config::Options,
                    dep_graph,
                    local_crate_source_file,
                    diagnostic_handler,
-                   codemap,
-                   cstore)
+                   codemap)
 }
 
 pub fn build_session_(sopts: config::Options,
                       dep_graph: &DepGraph,
                       local_crate_source_file: Option<PathBuf>,
                       span_diagnostic: errors::Handler,
-                      codemap: Rc<codemap::CodeMap>,
-                      cstore: Rc<CrateStore>)
+                      codemap: Rc<codemap::CodeMap>)
                       -> Session {
     let host = match Target::search(config::host_triple()) {
         Ok(t) => t,
@@ -722,7 +715,6 @@ pub fn build_session_(sopts: config::Options,
         target: target_cfg,
         host,
         opts: sopts,
-        cstore,
         parse_sess: p_s,
         // For a library crate, this is always none
         entry_fn: RefCell::new(None),
diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs
index 28abd1577dade..1487698353799 100644
--- a/src/librustc/traits/util.rs
+++ b/src/librustc/traits/util.rs
@@ -537,9 +537,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
                 }
             }
             None => {
-                self.global_tcx()
-                    .sess
-                    .cstore
+                self.cstore()
                     .impl_defaultness(node_item_def_id)
                     .is_default()
             }
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index f475baf19949f..720b7fede40b0 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -21,6 +21,7 @@ use hir::map as hir_map;
 use hir::map::DefPathHash;
 use lint::{self, Lint};
 use ich::{self, StableHashingContext, NodeIdHashingMode};
+use middle::cstore::CrateStore;
 use middle::free_region::FreeRegionMap;
 use middle::lang_items;
 use middle::resolve_lifetime;
@@ -806,8 +807,11 @@ pub struct GlobalCtxt<'tcx> {
     global_arenas: &'tcx GlobalArenas<'tcx>,
     global_interners: CtxtInterners<'tcx>,
 
+    cstore: &'tcx CrateStore,
+
     pub sess: &'tcx Session,
 
+
     pub trans_trait_caches: traits::trans::TransTraitCaches<'tcx>,
 
     pub dep_graph: DepGraph,
@@ -913,7 +917,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         if cnum == LOCAL_CRATE {
             self.crate_name
         } else {
-            self.sess.cstore.crate_name(cnum)
+            self.cstore.crate_name(cnum)
         }
     }
 
@@ -921,7 +925,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         if cnum == LOCAL_CRATE {
             self.crate_name.clone()
         } else {
-            self.sess.cstore.original_crate_name(cnum)
+            self.cstore.original_crate_name(cnum)
         }
     }
 
@@ -929,10 +933,14 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         if cnum == LOCAL_CRATE {
             self.sess.local_crate_disambiguator()
         } else {
-            self.sess.cstore.crate_disambiguator(cnum)
+            self.cstore.crate_disambiguator(cnum)
         }
     }
 
+    pub fn cstore(&self) -> &CrateStore {
+        &*self.cstore
+    }
+
     pub fn alloc_generics(self, generics: ty::Generics) -> &'gcx ty::Generics {
         self.global_arenas.generics.alloc(generics)
     }
@@ -1008,6 +1016,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
     /// value (types, substs, etc.) can only be used while `ty::tls` has a valid
     /// reference to the context, to allow formatting values that need it.
     pub fn create_and_enter<F, R>(s: &'tcx Session,
+                                  cstore: &'tcx CrateStore,
                                   local_providers: ty::maps::Providers<'tcx>,
                                   extern_providers: ty::maps::Providers<'tcx>,
                                   mir_passes: Rc<Passes>,
@@ -1026,16 +1035,15 @@ 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 = cstore.crates().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
+            let upstream_def_path_tables: Vec<(CrateNum, Rc<_>)> = cstore
                 .crates()
                 .iter()
-                .map(|&cnum| (cnum, s.cstore.def_path_table(cnum)))
+                .map(|&cnum| (cnum, cstore.def_path_table(cnum)))
                 .collect();
 
             let def_path_tables = || {
@@ -1065,6 +1073,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
 
         tls::enter_global(GlobalCtxt {
             sess: s,
+            cstore,
             trans_trait_caches: traits::trans::TransTraitCaches::new(dep_graph.clone()),
             global_arenas: arenas,
             global_interners: interners,
diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs
index eadf80871fc95..4f0d30b996639 100644
--- a/src/librustc/ty/item_path.rs
+++ b/src/librustc/ty/item_path.rs
@@ -128,7 +128,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
     pub fn try_push_visible_item_path<T>(self, buffer: &mut T, external_def_id: DefId) -> bool
         where T: ItemPathBuffer
     {
-        let visible_parent_map = self.sess.cstore.visible_parent_map(self.sess);
+        let visible_parent_map = self.cstore().visible_parent_map(self.sess);
 
         let (mut cur_def, mut cur_path) = (external_def_id, Vec::<ast::Name>::new());
         loop {
@@ -150,7 +150,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
                 }
             }
 
-            cur_path.push(self.sess.cstore.def_key(cur_def)
+            cur_path.push(self.cstore().def_key(cur_def)
                               .disambiguated_data.data.get_opt_name().unwrap_or_else(||
                 Symbol::intern("<unnamed>")));
             match visible_parent_map.get(&cur_def) {
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 1851e1b8d34bb..d73edc9ee7d7b 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -2180,7 +2180,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         if id.is_local() {
             self.hir.def_key(id)
         } else {
-            self.sess.cstore.def_key(id)
+            self.cstore().def_key(id)
         }
     }
 
@@ -2193,7 +2193,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         if id.is_local() {
             self.hir.def_path(id)
         } else {
-            self.sess.cstore.def_path(id)
+            self.cstore().def_path(id)
         }
     }
 
@@ -2202,7 +2202,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         if def_id.is_local() {
             self.hir.definitions().def_path_hash(def_id.index)
         } else {
-            self.sess.cstore.def_path_hash(def_id)
+            self.cstore().def_path_hash(def_id)
         }
     }
 
@@ -2210,9 +2210,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         if let Some(id) = self.hir.as_local_node_id(id) {
             self.hir.name(id)
         } else if id.index == CRATE_DEF_INDEX {
-            self.sess.cstore.original_crate_name(id.krate)
+            self.cstore().original_crate_name(id.krate)
         } else {
-            let def_key = self.sess.cstore.def_key(id);
+            let def_key = self.cstore().def_key(id);
             // The name of a StructCtor is that of its struct parent.
             if let hir_map::DefPathData::StructCtor = def_key.disambiguated_data.data {
                 self.item_name(DefId {
@@ -2315,7 +2315,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
             let node_id = self.hir.as_local_node_id(impl_did).unwrap();
             Ok(self.hir.span(node_id))
         } else {
-            Err(self.sess.cstore.crate_name(impl_did.krate))
+            Err(self.cstore().crate_name(impl_did.krate))
         }
     }
 
diff --git a/src/librustc/ty/trait_def.rs b/src/librustc/ty/trait_def.rs
index 9990472c6b4ca..39bb8c58f4866 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>,
         // crates, so we don't bother querying the cstore.
         Vec::new()
     } else {
-        tcx.sess.cstore.implementations_of_trait(Some(trait_id))
+        tcx.cstore().implementations_of_trait(Some(trait_id))
     };
 
     let mut blanket_impls = Vec::new();
diff --git a/src/librustc_const_eval/eval.rs b/src/librustc_const_eval/eval.rs
index c7def0b834cfd..a0c57b823603b 100644
--- a/src/librustc_const_eval/eval.rs
+++ b/src/librustc_const_eval/eval.rs
@@ -354,7 +354,7 @@ fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>,
             }
           } else {
             if tcx.is_const_fn(def_id) {
-                tcx.sess.cstore.item_body(tcx, def_id)
+                tcx.cstore().item_body(tcx, def_id)
             } else {
                 signal!(e, TypeckError)
             }
@@ -774,7 +774,7 @@ fn const_eval<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         tcx.mir_const_qualif(def_id);
         tcx.hir.body(tcx.hir.body_owned_by(id))
     } else {
-        tcx.sess.cstore.item_body(tcx, def_id)
+        tcx.cstore().item_body(tcx, def_id)
     };
     ConstContext::new(tcx, key.param_env.and(substs), tables).eval(&body.value)
 }
diff --git a/src/librustc_const_eval/pattern.rs b/src/librustc_const_eval/pattern.rs
index ba79f775ef73d..04f0162f4b755 100644
--- a/src/librustc_const_eval/pattern.rs
+++ b/src/librustc_const_eval/pattern.rs
@@ -609,7 +609,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
                         let body = if let Some(id) = self.tcx.hir.as_local_node_id(def_id) {
                             self.tcx.hir.body(self.tcx.hir.body_owned_by(id))
                         } else {
-                            self.tcx.sess.cstore.item_body(self.tcx, def_id)
+                            self.tcx.cstore().item_body(self.tcx, def_id)
                         };
                         let pat = self.lower_const_expr(&body.value, pat_id, span);
                         self.tables = old_tables;
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index 000d89241a427..811f061f7b7c6 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -21,6 +21,7 @@ use rustc::session::config::{self, Input, OutputFilenames, OutputType};
 use rustc::session::search_paths::PathKind;
 use rustc::lint;
 use rustc::middle::{self, stability, reachable};
+use rustc::middle::cstore::CrateStore;
 use rustc::middle::privacy::AccessLevels;
 use rustc::mir::transform::{MIR_CONST, MIR_VALIDATED, MIR_OPTIMIZED, Passes};
 use rustc::ty::{self, TyCtxt, Resolutions, GlobalArenas};
@@ -200,6 +201,7 @@ pub fn compile_input(sess: &Session,
         };
 
         phase_3_run_analysis_passes(sess,
+                                    cstore,
                                     hir_map,
                                     analysis,
                                     resolutions,
@@ -272,7 +274,7 @@ pub fn compile_input(sess: &Session,
                                 phase5_result);
         phase5_result?;
 
-        phase_6_link_output(sess, &trans, &outputs);
+        phase_6_link_output(sess, cstore, &trans, &outputs);
 
         // Now that we won't touch anything in the incremental compilation directory
         // any more, we can finalize it (which involves renaming it)
@@ -385,7 +387,7 @@ pub struct CompileState<'a, 'tcx: 'a> {
     pub session: &'tcx Session,
     pub krate: Option<ast::Crate>,
     pub registry: Option<Registry<'a>>,
-    pub cstore: Option<&'a CStore>,
+    pub cstore: Option<&'tcx CStore>,
     pub crate_name: Option<&'a str>,
     pub output_filenames: Option<&'a OutputFilenames>,
     pub out_dir: Option<&'a Path>,
@@ -433,7 +435,7 @@ impl<'a, 'tcx> CompileState<'a, 'tcx> {
                          out_dir: &'a Option<PathBuf>,
                          out_file: &'a Option<PathBuf>,
                          krate: ast::Crate,
-                         cstore: &'a CStore)
+                         cstore: &'tcx CStore)
                          -> Self {
         CompileState {
             // Initialize the registry before moving `krate`
@@ -449,7 +451,7 @@ impl<'a, 'tcx> CompileState<'a, 'tcx> {
                           session: &'tcx Session,
                           out_dir: &'a Option<PathBuf>,
                           out_file: &'a Option<PathBuf>,
-                          cstore: &'a CStore,
+                          cstore: &'tcx CStore,
                           expanded_crate: &'a ast::Crate,
                           crate_name: &'a str)
                           -> Self {
@@ -468,7 +470,7 @@ impl<'a, 'tcx> CompileState<'a, 'tcx> {
                                 out_file: &'a Option<PathBuf>,
                                 arena: &'tcx DroplessArena,
                                 arenas: &'tcx GlobalArenas<'tcx>,
-                                cstore: &'a CStore,
+                                cstore: &'tcx CStore,
                                 hir_map: &'a hir_map::Map<'tcx>,
                                 analysis: &'a ty::CrateAnalysis,
                                 resolutions: &'a Resolutions,
@@ -697,6 +699,7 @@ pub fn phase_2_configure_and_expand<F>(sess: &Session,
     crate_loader.preprocess(&krate);
     let resolver_arenas = Resolver::arenas();
     let mut resolver = Resolver::new(sess,
+                                     cstore,
                                      &krate,
                                      crate_name,
                                      make_glob_map,
@@ -845,7 +848,7 @@ pub fn phase_2_configure_and_expand<F>(sess: &Session,
 
     // Lower ast -> hir.
     let hir_forest = time(time_passes, "lowering ast -> hir", || {
-        let hir_crate = lower_crate(sess, &krate, &mut resolver);
+        let hir_crate = lower_crate(sess, cstore, &krate, &mut resolver);
 
         if sess.opts.debugging_opts.hir_stats {
             hir_stats::print_hir_stats(&hir_crate);
@@ -887,6 +890,7 @@ pub fn phase_2_configure_and_expand<F>(sess: &Session,
 /// miscellaneous analysis passes on the crate. Return various
 /// structures carrying the results of the analysis.
 pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
+                                               cstore: &'tcx CrateStore,
                                                hir_map: hir_map::Map<'tcx>,
                                                mut analysis: ty::CrateAnalysis,
                                                resolutions: Resolutions,
@@ -916,13 +920,13 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
 
     let lang_items = time(time_passes, "language item collection", || {
         sess.track_errors(|| {
-            middle::lang_items::collect_language_items(&sess, &hir_map)
+            middle::lang_items::collect_language_items(&sess, cstore, &hir_map)
         })
     })?;
 
     let named_region_map = time(time_passes,
                                 "lifetime resolution",
-                                || middle::resolve_lifetime::krate(sess, &hir_map))?;
+                                || middle::resolve_lifetime::krate(sess, cstore, &hir_map))?;
 
     time(time_passes,
          "looking for entry point",
@@ -1021,6 +1025,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
     passes.push_pass(MIR_OPTIMIZED, mir::transform::dump_mir::Marker("PreTrans"));
 
     TyCtxt::create_and_enter(sess,
+                             cstore,
                              local_providers,
                              extern_providers,
                              Rc::new(passes),
@@ -1163,10 +1168,15 @@ pub fn phase_5_run_llvm_passes(sess: &Session,
 /// This should produce either a finished executable or library.
 #[cfg(feature="llvm")]
 pub fn phase_6_link_output(sess: &Session,
+                           cstore: &CrateStore,
                            trans: &trans::CrateTranslation,
                            outputs: &OutputFilenames) {
     time(sess.time_passes(), "linking", || {
-        ::rustc_trans::back::link::link_binary(sess, trans, outputs, &trans.crate_name.as_str())
+        ::rustc_trans::back::link::link_binary(sess,
+                                               cstore,
+                                               trans,
+                                               outputs,
+                                               &trans.crate_name.as_str())
     });
 }
 
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index 1915a1c86484a..d3355f2ade450 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -72,6 +72,7 @@ use rustc::session::config::nightly_options;
 use rustc::session::{early_error, early_warn};
 use rustc::lint::Lint;
 use rustc::lint;
+use rustc::middle::cstore::CrateStore;
 use rustc_metadata::locator;
 use rustc_metadata::cstore::CStore;
 use rustc::util::common::{time, ErrorReported};
@@ -299,7 +300,7 @@ pub fn run_compiler<'a>(args: &[String],
     let loader = file_loader.unwrap_or(box RealFileLoader);
     let codemap = Rc::new(CodeMap::with_file_loader(loader, sopts.file_path_mapping()));
     let mut sess = session::build_session_with_codemap(
-        sopts, &dep_graph, input_file_path, descriptions, cstore.clone(), codemap, emitter_dest,
+        sopts, &dep_graph, input_file_path, descriptions, codemap, emitter_dest,
     );
     rustc_trans::init(&sess);
     rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
@@ -308,7 +309,12 @@ pub fn run_compiler<'a>(args: &[String],
     target_features::add_configuration(&mut cfg, &sess);
     sess.parse_sess.config = cfg;
 
-    do_or_return!(callbacks.late_callback(&matches, &sess, &input, &odir, &ofile), Some(sess));
+    do_or_return!(callbacks.late_callback(&matches,
+                                          &sess,
+                                          &*cstore,
+                                          &input,
+                                          &odir,
+                                          &ofile), Some(sess));
 
     let plugins = sess.opts.debugging_opts.extra_plugins.clone();
     let control = callbacks.build_controller(&sess, &matches);
@@ -400,6 +406,7 @@ pub trait CompilerCalls<'a> {
     fn late_callback(&mut self,
                      _: &getopts::Matches,
                      _: &Session,
+                     _: &CrateStore,
                      _: &Input,
                      _: &Option<PathBuf>,
                      _: &Option<PathBuf>)
@@ -574,12 +581,10 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
                     return None;
                 }
                 let dep_graph = DepGraph::new(sopts.build_dep_graph());
-                let cstore = Rc::new(CStore::new(&dep_graph, box ::MetadataLoader));
                 let mut sess = build_session(sopts.clone(),
                     &dep_graph,
                     None,
-                    descriptions.clone(),
-                    cstore.clone());
+                    descriptions.clone());
                 rustc_trans::init(&sess);
                 rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
                 let mut cfg = config::build_configuration(&sess, cfg.clone());
@@ -601,12 +606,13 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
     fn late_callback(&mut self,
                      matches: &getopts::Matches,
                      sess: &Session,
+                     cstore: &CrateStore,
                      input: &Input,
                      odir: &Option<PathBuf>,
                      ofile: &Option<PathBuf>)
                      -> Compilation {
         RustcDefaultCalls::print_crate_info(sess, Some(input), odir, ofile)
-            .and_then(|| RustcDefaultCalls::list_metadata(sess, matches, input))
+            .and_then(|| RustcDefaultCalls::list_metadata(sess, cstore, matches, input))
     }
 
     fn build_controller(&mut self,
@@ -627,6 +633,7 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
                 };
                 control.after_hir_lowering.callback = box move |state| {
                     pretty::print_after_hir_lowering(state.session,
+                                                     state.cstore.unwrap(),
                                                      state.hir_map.unwrap(),
                                                      state.analysis.unwrap(),
                                                      state.resolutions.unwrap(),
@@ -711,7 +718,11 @@ fn save_analysis(sess: &Session) -> bool {
 }
 
 impl RustcDefaultCalls {
-    pub fn list_metadata(sess: &Session, matches: &getopts::Matches, input: &Input) -> Compilation {
+    pub fn list_metadata(sess: &Session,
+                         cstore: &CrateStore,
+                         matches: &getopts::Matches,
+                         input: &Input)
+                         -> Compilation {
         let r = matches.opt_strs("Z");
         if r.contains(&("ls".to_string())) {
             match input {
@@ -720,7 +731,7 @@ impl RustcDefaultCalls {
                     let mut v = Vec::new();
                     locator::list_file_metadata(&sess.target.target,
                                                 path,
-                                                sess.cstore.metadata_loader(),
+                                                cstore.metadata_loader(),
                                                 &mut v)
                             .unwrap();
                     println!("{}", String::from_utf8(v).unwrap());
diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs
index 6a58b7fb75360..82dda2d2aa162 100644
--- a/src/librustc_driver/pretty.rs
+++ b/src/librustc_driver/pretty.rs
@@ -21,6 +21,7 @@ use rustc::ty::{self, TyCtxt, GlobalArenas, Resolutions};
 use rustc::cfg;
 use rustc::cfg::graphviz::LabelledCFG;
 use rustc::dep_graph::DepGraph;
+use rustc::middle::cstore::CrateStore;
 use rustc::session::Session;
 use rustc::session::config::Input;
 use rustc_borrowck as borrowck;
@@ -198,6 +199,7 @@ impl PpSourceMode {
     }
     fn call_with_pp_support_hir<'tcx, A, F>(&self,
                                                sess: &'tcx Session,
+                                               cstore: &'tcx CrateStore,
                                                hir_map: &hir_map::Map<'tcx>,
                                                analysis: &ty::CrateAnalysis,
                                                resolutions: &Resolutions,
@@ -226,6 +228,7 @@ impl PpSourceMode {
             }
             PpmTyped => {
                 abort_on_err(driver::phase_3_run_analysis_passes(sess,
+                                                                 cstore,
                                                                  hir_map.clone(),
                                                                  analysis.clone(),
                                                                  resolutions.clone(),
@@ -875,6 +878,7 @@ pub fn print_after_parsing(sess: &Session,
 }
 
 pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session,
+                                                cstore: &'tcx CrateStore,
                                                 hir_map: &hir_map::Map<'tcx>,
                                                 analysis: &ty::CrateAnalysis,
                                                 resolutions: &Resolutions,
@@ -891,6 +895,7 @@ pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session,
 
     if ppm.needs_analysis() {
         print_with_analysis(sess,
+                            cstore,
                             hir_map,
                             analysis,
                             resolutions,
@@ -929,6 +934,7 @@ pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session,
             (PpmHir(s), None) => {
                 let out: &mut Write = &mut out;
                 s.call_with_pp_support_hir(sess,
+                                           cstore,
                                            hir_map,
                                            analysis,
                                            resolutions,
@@ -952,6 +958,7 @@ pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session,
             (PpmHir(s), Some(uii)) => {
                 let out: &mut Write = &mut out;
                 s.call_with_pp_support_hir(sess,
+                                           cstore,
                                            hir_map,
                                            analysis,
                                            resolutions,
@@ -993,6 +1000,7 @@ pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session,
 // with a different callback than the standard driver, so that isn't easy.
 // Instead, we call that function ourselves.
 fn print_with_analysis<'tcx, 'a: 'tcx>(sess: &'a Session,
+                                       cstore: &'a CrateStore,
                                        hir_map: &hir_map::Map<'tcx>,
                                        analysis: &ty::CrateAnalysis,
                                        resolutions: &Resolutions,
@@ -1013,6 +1021,7 @@ fn print_with_analysis<'tcx, 'a: 'tcx>(sess: &'a Session,
     let mut out = Vec::new();
 
     abort_on_err(driver::phase_3_run_analysis_passes(sess,
+                                                     cstore,
                                                      hir_map.clone(),
                                                      analysis.clone(),
                                                      resolutions.clone(),
diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs
index 552130e8a4703..e996cd2276fa5 100644
--- a/src/librustc_driver/test.rs
+++ b/src/librustc_driver/test.rs
@@ -111,8 +111,7 @@ fn test_env<F>(source_string: &str,
                                        &dep_graph,
                                        None,
                                        diagnostic_handler,
-                                       Rc::new(CodeMap::new(FilePathMapping::empty())),
-                                       cstore.clone());
+                                       Rc::new(CodeMap::new(FilePathMapping::empty())));
     rustc_trans::init(&sess);
     rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
     let input = config::Input::Str {
@@ -140,10 +139,11 @@ fn test_env<F>(source_string: &str,
     let hir_map = hir_map::map_crate(&mut hir_forest, defs);
 
     // run just enough stuff to build a tcx:
-    let lang_items = lang_items::collect_language_items(&sess, &hir_map);
-    let named_region_map = resolve_lifetime::krate(&sess, &hir_map);
+    let lang_items = lang_items::collect_language_items(&sess, &*cstore, &hir_map);
+    let named_region_map = resolve_lifetime::krate(&sess, &*cstore, &hir_map);
     let index = stability::Index::new(&sess);
     TyCtxt::create_and_enter(&sess,
+                             &*cstore,
                              ty::maps::Providers::default(),
                              ty::maps::Providers::default(),
                              Rc::new(Passes::new()),
diff --git a/src/librustc_incremental/persist/fs.rs b/src/librustc_incremental/persist/fs.rs
index 28d33d9528692..7adcbdcd17a75 100644
--- a/src/librustc_incremental/persist/fs.rs
+++ b/src/librustc_incremental/persist/fs.rs
@@ -632,7 +632,7 @@ pub fn find_metadata_hashes_for(tcx: TyCtxt, cnum: CrateNum) -> Option<PathBuf>
         }
     };
 
-    let target_svh = tcx.sess.cstore.crate_hash(cnum);
+    let target_svh = tcx.cstore().crate_hash(cnum);
     let target_svh = base_n::encode(target_svh.as_u64(), INT_ENCODE_BASE);
 
     let sub_dir = find_metadata_hashes_iter(&target_svh, dir_entries.filter_map(|e| {
diff --git a/src/librustc_incremental/persist/hash.rs b/src/librustc_incremental/persist/hash.rs
index 9d762a74bfe67..439bf11f2724d 100644
--- a/src/librustc_incremental/persist/hash.rs
+++ b/src/librustc_incremental/persist/hash.rs
@@ -133,7 +133,7 @@ impl<'a, 'tcx> HashContext<'a, 'tcx> {
     fn load_data(&mut self, cnum: CrateNum) {
         debug!("load_data(cnum={})", cnum);
 
-        let svh = self.tcx.sess.cstore.crate_hash(cnum);
+        let svh = self.tcx.cstore().crate_hash(cnum);
         let old = self.crate_hashes.insert(cnum, svh);
         debug!("load_data: svh={}", svh);
         assert!(old.is_none(), "loaded data for crate {:?} twice", cnum);
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index 52b645638b86f..6593753eb3135 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -1061,8 +1061,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PluginAsLibrary {
             _ => return,
         };
 
-        let prfn = match cx.sess().cstore.extern_mod_stmt_cnum(it.id) {
-            Some(cnum) => cx.sess().cstore.plugin_registrar_fn(cnum),
+        let prfn = match cx.tcx.cstore().extern_mod_stmt_cnum(it.id) {
+            Some(cnum) => cx.tcx.cstore().plugin_registrar_fn(cnum),
             None => {
                 // Probably means we aren't linking the crate for some reason.
                 //
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index 537e12086141c..2ef91bf007c30 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -55,7 +55,7 @@ macro_rules! provide {
 
                 $tcx.dep_graph.read(dep_node);
 
-                let $cdata = $tcx.sess.cstore.crate_data_as_rc_any($def_id.krate);
+                let $cdata = $tcx.cstore().crate_data_as_rc_any($def_id.krate);
                 let $cdata = $cdata.downcast_ref::<cstore::CrateMetadata>()
                     .expect("CrateStore crated ata is not a CrateMetadata");
                 $compute
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index d36aebe38eb0b..ceae5c598be56 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -1283,12 +1283,13 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
     }
 
     fn encode_native_libraries(&mut self, _: ()) -> LazySeq<NativeLibrary> {
-        let used_libraries = self.tcx.sess.cstore.used_libraries();
+        let used_libraries = self.tcx.cstore().used_libraries();
         self.lazy_seq(used_libraries)
     }
 
     fn encode_crate_deps(&mut self, _: ()) -> LazySeq<CrateDep> {
-        let cstore = &*self.tcx.sess.cstore;
+        let tcx = self.tcx;
+        let cstore = tcx.cstore();
         let crates = cstore.crates();
 
         let mut deps = crates
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index 872a29e7bc0c5..ff11f74cbc422 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -630,7 +630,7 @@ impl<'a, 'tcx> TypePrivacyVisitor<'a, 'tcx> {
                 };
                 ty::Visibility::from_hir(vis, node_id, self.tcx)
             }
-            None => self.tcx.sess.cstore.visibility(did),
+            None => self.tcx.cstore().visibility(did),
         }
     }
 
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 47fa5357abf0d..686b0769adc06 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -253,7 +253,7 @@ impl<'a> Resolver<'a> {
                 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).unwrap();
+                let crate_id = self.cstore.extern_mod_stmt_cnum(item.id).unwrap();
                 let module =
                     self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX });
                 self.populate_module_if_necessary(module);
@@ -449,7 +449,7 @@ impl<'a> Resolver<'a> {
         let ident = child.ident;
         let def = child.def;
         let def_id = def.def_id();
-        let vis = self.session.cstore.visibility(def_id);
+        let vis = self.cstore.visibility(def_id);
         let span = child.span;
         let expansion = Mark::root(); // FIXME(jseyfried) intercrate hygiene
         match def {
@@ -471,7 +471,7 @@ impl<'a> Resolver<'a> {
                 self.define(parent, ident, ValueNS, (def, vis, DUMMY_SP, expansion));
 
                 if let Some(struct_def_id) =
-                        self.session.cstore.def_key(def_id).parent
+                        self.cstore.def_key(def_id).parent
                             .map(|index| DefId { krate: def_id.krate, index: index }) {
                     self.struct_constructors.insert(struct_def_id, (def, vis));
                 }
@@ -485,12 +485,12 @@ impl<'a> Resolver<'a> {
                                              span);
                 self.define(parent, ident, TypeNS, (module, vis, DUMMY_SP, expansion));
 
-                for child in self.session.cstore.item_children(def_id, self.session) {
+                for child in self.cstore.item_children(def_id, self.session) {
                     let ns = if let Def::AssociatedTy(..) = child.def { TypeNS } else { ValueNS };
                     self.define(module, child.ident, ns,
                                 (child.def, ty::Visibility::Public, DUMMY_SP, expansion));
 
-                    if self.session.cstore.associated_item_cloned(child.def.def_id())
+                    if self.cstore.associated_item_cloned(child.def.def_id())
                            .method_has_self_argument {
                         self.has_self.insert(child.def.def_id());
                     }
@@ -501,7 +501,7 @@ impl<'a> Resolver<'a> {
                 self.define(parent, ident, TypeNS, (def, vis, DUMMY_SP, expansion));
 
                 // Record field names for error reporting.
-                let field_names = self.session.cstore.struct_field_names(def_id);
+                let field_names = self.cstore.struct_field_names(def_id);
                 self.insert_field_names(def_id, field_names);
             }
             Def::Macro(..) => {
@@ -516,15 +516,15 @@ impl<'a> Resolver<'a> {
             return self.module_map[&def_id]
         }
 
-        let macros_only = self.session.cstore.dep_kind(def_id.krate).macros_only();
+        let macros_only = self.cstore.dep_kind(def_id.krate).macros_only();
         if let Some(&module) = self.extern_module_map.get(&(def_id, macros_only)) {
             return module;
         }
 
         let (name, parent) = if def_id.index == CRATE_DEF_INDEX {
-            (self.session.cstore.crate_name(def_id.krate), None)
+            (self.cstore.crate_name(def_id.krate), None)
         } else {
-            let def_key = self.session.cstore.def_key(def_id);
+            let def_key = self.cstore.def_key(def_id);
             (def_key.disambiguated_data.data.get_opt_name().unwrap(),
              Some(self.get_module(DefId { index: def_key.parent.unwrap(), ..def_id })))
         };
@@ -558,7 +558,7 @@ impl<'a> Resolver<'a> {
             return ext.clone();
         }
 
-        let macro_def = match self.session.cstore.load_macro(def_id, &self.session) {
+        let macro_def = match self.cstore.load_macro(def_id, &self.session) {
             LoadedMacro::MacroDef(macro_def) => macro_def,
             LoadedMacro::ProcMacro(ext) => return ext,
         };
@@ -574,7 +574,7 @@ impl<'a> Resolver<'a> {
     /// is built, building it if it is not.
     pub fn populate_module_if_necessary(&mut self, module: Module<'a>) {
         if module.populated.get() { return }
-        for child in self.session.cstore.item_children(module.def_id().unwrap(), self.session) {
+        for child in self.cstore.item_children(module.def_id().unwrap(), self.session) {
             self.build_reduced_graph_for_external_crate_def(module, child);
         }
         module.populated.set(true)
@@ -605,7 +605,7 @@ impl<'a> Resolver<'a> {
             span_err!(self.session, item.span, E0468,
                       "an `extern crate` loading macros must be at the crate root");
         } else if !self.use_extern_macros && !used &&
-                  self.session.cstore.dep_kind(module.def_id().unwrap().krate).macros_only() {
+                  self.cstore.dep_kind(module.def_id().unwrap().krate).macros_only() {
             let msg = "proc macro crates and `#[no_link]` crates have no effect without \
                        `#[macro_use]`";
             self.session.span_warn(item.span, msg);
@@ -648,7 +648,7 @@ impl<'a> Resolver<'a> {
             }
         }
         for (name, span) in legacy_imports.reexports {
-            self.session.cstore.export_macros(module.def_id().unwrap().krate);
+            self.cstore.export_macros(module.def_id().unwrap().krate);
             let ident = Ident::with_empty_ctxt(name);
             let result = self.resolve_ident_in_module(module, ident, MacroNS, false, false, span);
             if let Ok(binding) = result {
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 2183c9124e7f4..ee97002f6be56 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -31,7 +31,7 @@ use self::RibKind::*;
 
 use rustc::hir::map::{Definitions, DefCollector};
 use rustc::hir::{self, PrimTy, TyBool, TyChar, TyFloat, TyInt, TyUint, TyStr};
-use rustc::middle::cstore::CrateLoader;
+use rustc::middle::cstore::{CrateStore, CrateLoader};
 use rustc::session::Session;
 use rustc::lint;
 use rustc::hir::def::*;
@@ -1176,6 +1176,7 @@ impl PrimitiveTypeTable {
 /// The main resolver class.
 pub struct Resolver<'a> {
     session: &'a Session,
+    cstore: &'a CrateStore,
 
     pub definitions: Definitions,
 
@@ -1343,7 +1344,7 @@ impl<'a, 'b: 'a> ty::DefIdTree for &'a Resolver<'b> {
     fn parent(self, id: DefId) -> Option<DefId> {
         match id.krate {
             LOCAL_CRATE => self.definitions.def_key(id.index).parent,
-            _ => self.session.cstore.def_key(id).parent,
+            _ => self.cstore.def_key(id).parent,
         }.map(|index| DefId { index: index, ..id })
     }
 }
@@ -1383,6 +1384,7 @@ impl<'a> hir::lowering::Resolver for Resolver<'a> {
 
 impl<'a> Resolver<'a> {
     pub fn new(session: &'a Session,
+               cstore: &'a CrateStore,
                krate: &Crate,
                crate_name: &str,
                make_glob_map: MakeGlobMap,
@@ -1414,6 +1416,8 @@ impl<'a> Resolver<'a> {
         Resolver {
             session,
 
+            cstore,
+
             definitions,
 
             // The outermost module has def ID 0; this is not reflected in the
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 9531c8baa0bc1..f269e37cfafa1 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -778,7 +778,7 @@ impl<'a> Resolver<'a> {
             _ => return,
         };
 
-        let crate_name = self.session.cstore.crate_name(krate);
+        let crate_name = self.cstore.crate_name(krate);
 
         self.session.struct_span_err(use_span, warn_msg)
             .help(&format!("instead, import the procedural macro like any other item: \
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index 71bcee56ecc51..6e379d17399d8 100644
--- a/src/librustc_resolve/resolve_imports.rs
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -844,7 +844,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
                 let def = binding.def();
                 if def != Def::Err {
                     if !def.def_id().is_local() {
-                        self.session.cstore.export_macros(def.def_id().krate);
+                        self.cstore.export_macros(def.def_id().krate);
                     }
                     if let Def::Macro(..) = def {
                         if let Some(&span) = exported_macro_names.get(&ident.modern()) {
diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs
index 9ee38dd86c1b5..27caa49a52c6c 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<ExternalCrateData> {
         let mut result = Vec::new();
 
-        for n in self.tcx.sess.cstore.crates() {
+        for n in self.tcx.cstore().crates() {
             let span = match *self.tcx.extern_crate(n.as_def_id()) {
                 Some(ref c) => c.span,
                 None => {
@@ -119,7 +119,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
             };
             let lo_loc = self.span_utils.sess.codemap().lookup_char_pos(span.lo());
             result.push(ExternalCrateData {
-                name: self.tcx.sess.cstore.crate_name(n).to_string(),
+                name: self.tcx.cstore().crate_name(n).to_string(),
                 num: n.as_u32(),
                 file_name: SpanUtils::make_path_string(&lo_loc.file.name),
             });
diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs
index 4e211d83cff3e..0cb7f255dbbb2 100644
--- a/src/librustc_trans/back/link.rs
+++ b/src/librustc_trans/back/link.rs
@@ -20,7 +20,7 @@ use rustc::session::filesearch;
 use rustc::session::search_paths::PathKind;
 use rustc::session::Session;
 use rustc::middle::cstore::{LinkMeta, NativeLibrary, LibSource, LinkagePreference,
-                            NativeLibraryKind};
+                            NativeLibraryKind, CrateStore};
 use rustc::middle::dependency_format::Linkage;
 use CrateTranslation;
 use rustc::util::common::time;
@@ -163,6 +163,7 @@ pub fn remove(sess: &Session, path: &Path) {
 /// Perform the linkage portion of the compilation phase. This will generate all
 /// of the requested outputs for this compilation session.
 pub fn link_binary(sess: &Session,
+                   cstore: &CrateStore,
                    trans: &CrateTranslation,
                    outputs: &OutputFilenames,
                    crate_name: &str) -> Vec<PathBuf> {
@@ -179,7 +180,12 @@ pub fn link_binary(sess: &Session,
            bug!("invalid output type `{:?}` for target os `{}`",
                 crate_type, sess.opts.target_triple);
         }
-        let mut out_files = link_binary_output(sess, trans, crate_type, outputs, crate_name);
+        let mut out_files = link_binary_output(sess,
+                                               cstore,
+                                               trans,
+                                               crate_type,
+                                               outputs,
+                                               crate_name);
         out_filenames.append(&mut out_files);
     }
 
@@ -216,8 +222,9 @@ fn filename_for_metadata(sess: &Session, crate_name: &str, outputs: &OutputFilen
 }
 
 pub fn each_linked_rlib(sess: &Session,
+                        cstore: &CrateStore,
                         f: &mut FnMut(CrateNum, &Path)) -> Result<(), String> {
-    let crates = sess.cstore.used_crates(LinkagePreference::RequireStatic).into_iter();
+    let crates = cstore.used_crates(LinkagePreference::RequireStatic).into_iter();
     let fmts = sess.dependency_formats.borrow();
     let fmts = fmts.get(&config::CrateTypeExecutable)
                    .or_else(|| fmts.get(&config::CrateTypeStaticlib))
@@ -234,7 +241,7 @@ pub fn each_linked_rlib(sess: &Session,
             Some(_) => {}
             None => return Err(format!("could not find formats for rlibs"))
         }
-        let name = sess.cstore.crate_name(cnum).clone();
+        let name = cstore.crate_name(cnum).clone();
         let path = match path {
             LibSource::Some(p) => p,
             LibSource::MetadataOnly => {
@@ -260,12 +267,12 @@ pub fn each_linked_rlib(sess: &Session,
 /// It's unusual for a crate to not participate in LTO. Typically only
 /// compiler-specific and unstable crates have a reason to not participate in
 /// LTO.
-pub fn ignored_for_lto(sess: &Session, cnum: CrateNum) -> bool {
+pub fn ignored_for_lto(cstore: &CrateStore, cnum: CrateNum) -> bool {
     // `#![no_builtins]` crates don't participate in LTO because the state
     // of builtins gets messed up (our crate isn't tagged with no builtins).
     // Similarly `#![compiler_builtins]` doesn't participate because we want
     // those builtins!
-    sess.cstore.is_no_builtins(cnum) || sess.cstore.is_compiler_builtins(cnum)
+    cstore.is_no_builtins(cnum) || cstore.is_compiler_builtins(cnum)
 }
 
 fn out_filename(sess: &Session,
@@ -295,6 +302,7 @@ fn check_file_is_writeable(file: &Path, sess: &Session) {
 }
 
 fn link_binary_output(sess: &Session,
+                      cstore: &CrateStore,
                       trans: &CrateTranslation,
                       crate_type: config::CrateType,
                       outputs: &OutputFilenames,
@@ -323,6 +331,7 @@ fn link_binary_output(sess: &Session,
         match crate_type {
             config::CrateTypeRlib => {
                 link_rlib(sess,
+                          cstore,
                           trans,
                           RlibFlavor::Normal,
                           &objects,
@@ -332,6 +341,7 @@ fn link_binary_output(sess: &Session,
             }
             config::CrateTypeStaticlib => {
                 link_staticlib(sess,
+                               cstore,
                                trans,
                                outputs,
                                &objects,
@@ -339,8 +349,8 @@ fn link_binary_output(sess: &Session,
                                tmpdir.path());
             }
             _ => {
-                link_natively(sess, crate_type, &objects, &out_filename, trans,
-                              outputs, tmpdir.path());
+                link_natively(sess, cstore, crate_type, &objects, &out_filename,
+                              trans, outputs, tmpdir.path());
             }
         }
         out_filenames.push(out_filename);
@@ -402,6 +412,7 @@ enum RlibFlavor {
 // all of the object files from native libraries. This is done by unzipping
 // native libraries and inserting all of the contents into this archive.
 fn link_rlib<'a>(sess: &'a Session,
+                 cstore: &CrateStore,
                  trans: &CrateTranslation,
                  flavor: RlibFlavor,
                  objects: &[PathBuf],
@@ -431,7 +442,7 @@ fn link_rlib<'a>(sess: &'a Session,
     // feature then we'll need to figure out how to record what objects were
     // loaded from the libraries found here and then encode that into the
     // metadata of the rlib we're generating somehow.
-    for lib in sess.cstore.used_libraries() {
+    for lib in cstore.used_libraries() {
         match lib.kind {
             NativeLibraryKind::NativeStatic => {}
             NativeLibraryKind::NativeStaticNobundle |
@@ -597,12 +608,14 @@ fn write_rlib_bytecode_object_v1(writer: &mut Write,
 // link in the metadata object file (and also don't prepare the archive with a
 // metadata file).
 fn link_staticlib(sess: &Session,
+                  cstore: &CrateStore,
                   trans: &CrateTranslation,
                   outputs: &OutputFilenames,
                   objects: &[PathBuf],
                   out_filename: &Path,
                   tempdir: &Path) {
     let mut ab = link_rlib(sess,
+                           cstore,
                            trans,
                            RlibFlavor::StaticlibBase,
                            objects,
@@ -611,9 +624,9 @@ fn link_staticlib(sess: &Session,
                            tempdir);
     let mut all_native_libs = vec![];
 
-    let res = each_linked_rlib(sess, &mut |cnum, path| {
-        let name = sess.cstore.crate_name(cnum);
-        let native_libs = sess.cstore.native_libraries(cnum);
+    let res = each_linked_rlib(sess, cstore, &mut |cnum, path| {
+        let name = cstore.crate_name(cnum);
+        let native_libs = cstore.native_libraries(cnum);
 
         // Here when we include the rlib into our staticlib we need to make a
         // decision whether to include the extra object files along the way.
@@ -634,10 +647,10 @@ fn link_staticlib(sess: &Session,
         });
         ab.add_rlib(path,
                     &name.as_str(),
-                    sess.lto() && !ignored_for_lto(sess, cnum),
+                    sess.lto() && !ignored_for_lto(cstore, cnum),
                     skip_object_files).unwrap();
 
-        all_native_libs.extend(sess.cstore.native_libraries(cnum));
+        all_native_libs.extend(cstore.native_libraries(cnum));
     });
     if let Err(e) = res {
         sess.fatal(&e);
@@ -670,6 +683,7 @@ fn link_staticlib(sess: &Session,
 // This will invoke the system linker/cc to create the resulting file. This
 // links to all upstream files as well.
 fn link_natively(sess: &Session,
+                 cstore: &CrateStore,
                  crate_type: config::CrateType,
                  objects: &[PathBuf],
                  out_filename: &Path,
@@ -713,7 +727,7 @@ fn link_natively(sess: &Session,
 
     {
         let mut linker = trans.linker_info.to_linker(cmd, &sess);
-        link_args(&mut *linker, sess, crate_type, tmpdir,
+        link_args(&mut *linker, sess, cstore, crate_type, tmpdir,
                   objects, out_filename, outputs, trans);
         cmd = linker.finalize();
     }
@@ -839,6 +853,7 @@ fn link_natively(sess: &Session,
 
 fn link_args(cmd: &mut Linker,
              sess: &Session,
+             cstore: &CrateStore,
              crate_type: config::CrateType,
              tmpdir: &Path,
              objects: &[PathBuf],
@@ -892,7 +907,7 @@ fn link_args(cmd: &mut Linker,
         cmd.gc_sections(keep_metadata);
     }
 
-    let used_link_args = sess.cstore.used_link_args();
+    let used_link_args = cstore.used_link_args();
 
     if crate_type == config::CrateTypeExecutable &&
        t.options.position_independent_executables {
@@ -962,9 +977,9 @@ fn link_args(cmd: &mut Linker,
     // link line. And finally upstream native libraries can't depend on anything
     // in this DAG so far because they're only dylibs and dylibs can only depend
     // on other dylibs (e.g. other native deps).
-    add_local_native_libraries(cmd, sess);
-    add_upstream_rust_crates(cmd, sess, crate_type, tmpdir);
-    add_upstream_native_libraries(cmd, sess, crate_type);
+    add_local_native_libraries(cmd, sess, cstore);
+    add_upstream_rust_crates(cmd, sess, cstore, crate_type, tmpdir);
+    add_upstream_native_libraries(cmd, sess, cstore, crate_type);
 
     // Tell the linker what we're doing.
     if crate_type != config::CrateTypeExecutable {
@@ -989,7 +1004,7 @@ fn link_args(cmd: &mut Linker,
             path
         };
         let mut rpath_config = RPathConfig {
-            used_crates: sess.cstore.used_crates(LinkagePreference::RequireDynamic),
+            used_crates: cstore.used_crates(LinkagePreference::RequireDynamic),
             out_filename: out_filename.to_path_buf(),
             has_rpath: sess.target.target.options.has_rpath,
             is_like_osx: sess.target.target.options.is_like_osx,
@@ -1019,7 +1034,7 @@ fn link_args(cmd: &mut Linker,
 // Also note that the native libraries linked here are only the ones located
 // in the current crate. Upstream crates with native library dependencies
 // may have their native library pulled in above.
-fn add_local_native_libraries(cmd: &mut Linker, sess: &Session) {
+fn add_local_native_libraries(cmd: &mut Linker, sess: &Session, cstore: &CrateStore) {
     sess.target_filesearch(PathKind::All).for_each_lib_search_path(|path, k| {
         match k {
             PathKind::Framework => { cmd.framework_path(path); }
@@ -1027,7 +1042,7 @@ fn add_local_native_libraries(cmd: &mut Linker, sess: &Session) {
         }
     });
 
-    let relevant_libs = sess.cstore.used_libraries().into_iter().filter(|l| {
+    let relevant_libs = cstore.used_libraries().into_iter().filter(|l| {
         relevant_lib(sess, l)
     });
 
@@ -1050,6 +1065,7 @@ fn add_local_native_libraries(cmd: &mut Linker, sess: &Session) {
 // the intermediate rlib version)
 fn add_upstream_rust_crates(cmd: &mut Linker,
                             sess: &Session,
+                            cstore: &CrateStore,
                             crate_type: config::CrateType,
                             tmpdir: &Path) {
     // All of the heavy lifting has previously been accomplished by the
@@ -1065,7 +1081,7 @@ fn add_upstream_rust_crates(cmd: &mut Linker,
 
     // Invoke get_used_crates to ensure that we get a topological sorting of
     // crates.
-    let deps = sess.cstore.used_crates(LinkagePreference::RequireDynamic);
+    let deps = cstore.used_crates(LinkagePreference::RequireDynamic);
 
     let mut compiler_builtins = None;
 
@@ -1073,24 +1089,24 @@ fn add_upstream_rust_crates(cmd: &mut Linker,
         // We may not pass all crates through to the linker. Some crates may
         // appear statically in an existing dylib, meaning we'll pick up all the
         // symbols from the dylib.
-        let src = sess.cstore.used_crate_source(cnum);
+        let src = cstore.used_crate_source(cnum);
         match data[cnum.as_usize() - 1] {
-            _ if sess.cstore.is_profiler_runtime(cnum) => {
-                add_static_crate(cmd, sess, tmpdir, crate_type, cnum);
+            _ if cstore.is_profiler_runtime(cnum) => {
+                add_static_crate(cmd, sess, cstore, tmpdir, crate_type, cnum);
             }
-            _ if sess.cstore.is_sanitizer_runtime(cnum) => {
-                link_sanitizer_runtime(cmd, sess, tmpdir, cnum);
+            _ if cstore.is_sanitizer_runtime(cnum) => {
+                link_sanitizer_runtime(cmd, sess, cstore, tmpdir, cnum);
             }
             // compiler-builtins are always placed last to ensure that they're
             // linked correctly.
-            _ if sess.cstore.is_compiler_builtins(cnum) => {
+            _ if cstore.is_compiler_builtins(cnum) => {
                 assert!(compiler_builtins.is_none());
                 compiler_builtins = Some(cnum);
             }
             Linkage::NotLinked |
             Linkage::IncludedFromDylib => {}
             Linkage::Static => {
-                add_static_crate(cmd, sess, tmpdir, crate_type, cnum);
+                add_static_crate(cmd, sess, cstore, tmpdir, crate_type, cnum);
             }
             Linkage::Dynamic => {
                 add_dynamic_crate(cmd, sess, &src.dylib.unwrap().0)
@@ -1104,7 +1120,7 @@ fn add_upstream_rust_crates(cmd: &mut Linker,
     // was already "included" in a dylib (e.g. `libstd` when `-C prefer-dynamic`
     // is used)
     if let Some(cnum) = compiler_builtins {
-        add_static_crate(cmd, sess, tmpdir, crate_type, cnum);
+        add_static_crate(cmd, sess, cstore, tmpdir, crate_type, cnum);
     }
 
     // Converts a library file-stem into a cc -l argument
@@ -1122,9 +1138,10 @@ fn add_upstream_rust_crates(cmd: &mut Linker,
     // linking it.
     fn link_sanitizer_runtime(cmd: &mut Linker,
                               sess: &Session,
+                              cstore: &CrateStore,
                               tmpdir: &Path,
                               cnum: CrateNum) {
-        let src = sess.cstore.used_crate_source(cnum);
+        let src = cstore.used_crate_source(cnum);
         let cratepath = &src.rlib.unwrap().0;
 
         if sess.target.target.options.is_like_osx {
@@ -1190,21 +1207,22 @@ fn add_upstream_rust_crates(cmd: &mut Linker,
     // we're at the end of the dependency chain.
     fn add_static_crate(cmd: &mut Linker,
                         sess: &Session,
+                        cstore: &CrateStore,
                         tmpdir: &Path,
                         crate_type: config::CrateType,
                         cnum: CrateNum) {
-        let src = sess.cstore.used_crate_source(cnum);
+        let src = cstore.used_crate_source(cnum);
         let cratepath = &src.rlib.unwrap().0;
 
         // See the comment above in `link_staticlib` and `link_rlib` for why if
         // there's a static library that's not relevant we skip all object
         // files.
-        let native_libs = sess.cstore.native_libraries(cnum);
+        let native_libs = cstore.native_libraries(cnum);
         let skip_native = native_libs.iter().any(|lib| {
             lib.kind == NativeLibraryKind::NativeStatic && !relevant_lib(sess, lib)
         });
 
-        if (!sess.lto() || ignored_for_lto(sess, cnum)) &&
+        if (!sess.lto() || ignored_for_lto(cstore, cnum)) &&
            crate_type != config::CrateTypeDylib &&
            !skip_native {
             cmd.link_rlib(&fix_windows_verbatim_for_gcc(cratepath));
@@ -1246,7 +1264,7 @@ fn add_upstream_rust_crates(cmd: &mut Linker,
                 // LTO module. Note that `#![no_builtins]` is excluded from LTO,
                 // though, so we let that object file slide.
                 let skip_because_lto = sess.lto() && is_rust_object &&
-                                        !sess.cstore.is_no_builtins(cnum);
+                                        !cstore.is_no_builtins(cnum);
 
                 if skip_because_cfg_say_so || skip_because_lto {
                     archive.remove_file(&f);
@@ -1268,7 +1286,7 @@ fn add_upstream_rust_crates(cmd: &mut Linker,
             // compiler-builtins crate (e.g. compiler-rt) because it'll get
             // repeatedly linked anyway.
             if crate_type == config::CrateTypeDylib &&
-               !sess.cstore.is_compiler_builtins(cnum) {
+               !cstore.is_compiler_builtins(cnum) {
                 cmd.link_whole_rlib(&fix_windows_verbatim_for_gcc(&dst));
             } else {
                 cmd.link_rlib(&fix_windows_verbatim_for_gcc(&dst));
@@ -1312,7 +1330,10 @@ fn add_upstream_rust_crates(cmd: &mut Linker,
 // generic function calls a native function, then the generic function must
 // be instantiated in the target crate, meaning that the native symbol must
 // also be resolved in the target crate.
-fn add_upstream_native_libraries(cmd: &mut Linker, sess: &Session, crate_type: config::CrateType) {
+fn add_upstream_native_libraries(cmd: &mut Linker,
+                                 sess: &Session,
+                                 cstore: &CrateStore,
+                                 crate_type: config::CrateType) {
     // Be sure to use a topological sorting of crates because there may be
     // interdependencies between native libraries. When passing -nodefaultlibs,
     // for example, almost all native libraries depend on libc, so we have to
@@ -1325,9 +1346,9 @@ fn add_upstream_native_libraries(cmd: &mut Linker, sess: &Session, crate_type: c
     let formats = sess.dependency_formats.borrow();
     let data = formats.get(&crate_type).unwrap();
 
-    let crates = sess.cstore.used_crates(LinkagePreference::RequireStatic);
+    let crates = cstore.used_crates(LinkagePreference::RequireStatic);
     for (cnum, _) in crates {
-        for lib in sess.cstore.native_libraries(cnum) {
+        for lib in cstore.native_libraries(cnum) {
             if !relevant_lib(sess, &lib) {
                 continue
             }
diff --git a/src/librustc_trans/back/symbol_export.rs b/src/librustc_trans/back/symbol_export.rs
index 971483e91b6f3..c049ebfd7a34e 100644
--- a/src/librustc_trans/back/symbol_export.rs
+++ b/src/librustc_trans/back/symbol_export.rs
@@ -110,13 +110,13 @@ impl ExportedSymbols {
         let mut exports = FxHashMap();
         exports.insert(LOCAL_CRATE, local_crate);
 
-        for cnum in tcx.sess.cstore.crates() {
+        for cnum in tcx.cstore().crates() {
             debug_assert!(cnum != LOCAL_CRATE);
 
             // If this crate is a plugin and/or a custom derive crate, then
             // we're not even going to link those in so we skip those crates.
-            if tcx.sess.cstore.plugin_registrar_fn(cnum).is_some() ||
-               tcx.sess.cstore.derive_registrar_fn(cnum).is_some() {
+            if tcx.cstore().plugin_registrar_fn(cnum).is_some() ||
+               tcx.cstore().derive_registrar_fn(cnum).is_some() {
                 continue;
             }
 
@@ -129,11 +129,10 @@ impl ExportedSymbols {
             // level instead.
             let special_runtime_crate =
                 tcx.is_panic_runtime(cnum.as_def_id()) ||
-                tcx.sess.cstore.is_compiler_builtins(cnum);
+                tcx.cstore().is_compiler_builtins(cnum);
 
             let crate_exports = tcx
-                .sess
-                .cstore
+                .cstore()
                 .exported_symbols(cnum)
                 .iter()
                 .map(|&def_id| {
diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs
index 3f9b28d3d610c..214b2b7e2e565 100644
--- a/src/librustc_trans/back/write.rs
+++ b/src/librustc_trans/back/write.rs
@@ -13,7 +13,7 @@ use back::link::{self, get_linker, remove};
 use back::linker::LinkerInfo;
 use back::symbol_export::ExportedSymbols;
 use rustc_incremental::{save_trans_partition, in_incr_comp_dir};
-use rustc::middle::cstore::{LinkMeta, EncodedMetadata};
+use rustc::middle::cstore::{CrateStore, LinkMeta, EncodedMetadata};
 use rustc::session::config::{self, OutputFilenames, OutputType, OutputTypes, Passes, SomePasses,
                              AllPasses, Sanitizer};
 use rustc::session::Session;
@@ -666,6 +666,7 @@ fn need_crate_bitcode_for_rlib(sess: &Session) -> bool {
 }
 
 pub fn start_async_translation(sess: &Session,
+                               cstore: &CrateStore,
                                crate_output: &OutputFilenames,
                                time_graph: Option<TimeGraph>,
                                crate_name: Symbol,
@@ -774,6 +775,7 @@ pub fn start_async_translation(sess: &Session,
     let (coordinator_send, coordinator_receive) = channel();
 
     let coordinator_thread = start_executing_work(sess,
+                                                  cstore,
                                                   shared_emitter,
                                                   trans_worker_send,
                                                   coordinator_send.clone(),
@@ -1101,6 +1103,7 @@ enum MainThreadWorkerState {
 }
 
 fn start_executing_work(sess: &Session,
+                        cstore: &CrateStore,
                         shared_emitter: SharedEmitter,
                         trans_worker_send: Sender<Message>,
                         coordinator_send: Sender<Message>,
@@ -1125,8 +1128,8 @@ fn start_executing_work(sess: &Session,
     }).expect("failed to spawn helper thread");
 
     let mut each_linked_rlib_for_lto = Vec::new();
-    drop(link::each_linked_rlib(sess, &mut |cnum, path| {
-        if link::ignored_for_lto(sess, cnum) {
+    drop(link::each_linked_rlib(sess, cstore, &mut |cnum, path| {
+        if link::ignored_for_lto(cstore, cnum) {
             return
         }
         each_linked_rlib_for_lto.push((cnum, path.to_path_buf()));
diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs
index a6c6b0efcfa8c..c4918336a9326 100644
--- a/src/librustc_trans/base.rs
+++ b/src/librustc_trans/base.rs
@@ -774,7 +774,7 @@ fn write_metadata<'a, 'gcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>,
                 EncodedMetadataHashes::new());
     }
 
-    let cstore = &tcx.sess.cstore;
+    let cstore = tcx.cstore();
     let (metadata, hashes) = cstore.encode_metadata(tcx,
                                                     &link_meta,
                                                     exported_symbols);
@@ -904,7 +904,7 @@ pub fn find_exported_symbols(tcx: TyCtxt, reachable: &NodeSet) -> NodeSet {
         match tcx.hir.get(id) {
             hir_map::NodeForeignItem(..) => {
                 let def_id = tcx.hir.local_def_id(id);
-                tcx.sess.cstore.is_statically_included_foreign_item(def_id)
+                tcx.cstore().is_statically_included_foreign_item(def_id)
             }
 
             // Only consider nodes that actually have exported symbols.
@@ -978,6 +978,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         let linker_info = LinkerInfo::new(&shared_ccx, &empty_exported_symbols);
         let ongoing_translation = write::start_async_translation(
             tcx.sess,
+            tcx.cstore(),
             output_filenames,
             time_graph.clone(),
             tcx.crate_name(LOCAL_CRATE),
@@ -1030,6 +1031,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
     let ongoing_translation = write::start_async_translation(
         tcx.sess,
+        tcx.cstore(),
         output_filenames,
         time_graph.clone(),
         tcx.crate_name(LOCAL_CRATE),
diff --git a/src/librustc_trans/callee.rs b/src/librustc_trans/callee.rs
index 76f94565bae51..5104cc792ab4e 100644
--- a/src/librustc_trans/callee.rs
+++ b/src/librustc_trans/callee.rs
@@ -125,7 +125,7 @@ pub fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
         }
 
         if ccx.use_dll_storage_attrs() &&
-            ccx.sess().cstore.is_dllimport_foreign_item(instance_def_id)
+            ccx.tcx().cstore().is_dllimport_foreign_item(instance_def_id)
         {
             unsafe {
                 llvm::LLVMSetDLLStorageClass(llfn, llvm::DLLStorageClass::DllImport);
diff --git a/src/librustc_trans/consts.rs b/src/librustc_trans/consts.rs
index 310cd6fe9559d..c018cd8b48711 100644
--- a/src/librustc_trans/consts.rs
+++ b/src/librustc_trans/consts.rs
@@ -211,7 +211,7 @@ pub fn get_static(ccx: &CrateContext, def_id: DefId) -> ValueRef {
         g
     };
 
-    if ccx.use_dll_storage_attrs() && ccx.sess().cstore.is_dllimport_foreign_item(def_id) {
+    if ccx.use_dll_storage_attrs() && ccx.tcx().cstore().is_dllimport_foreign_item(def_id) {
         // For foreign (native) libs we know the exact storage type to use.
         unsafe {
             llvm::LLVMSetDLLStorageClass(g, llvm::DLLStorageClass::DllImport);
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index f2d7842e473f6..5342c5ca84635 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -552,14 +552,14 @@ pub fn all_traits<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> AllTraits<'a>
                     if !external_mods.insert(def_id) {
                         return;
                     }
-                    for child in tcx.sess.cstore.item_children(def_id, tcx.sess) {
+                    for child in tcx.cstore().item_children(def_id, tcx.sess) {
                         handle_external_def(tcx, traits, external_mods, child.def)
                     }
                 }
                 _ => {}
             }
         }
-        for cnum in tcx.sess.cstore.crates() {
+        for cnum in tcx.cstore().crates() {
             let def_id = DefId {
                 krate: cnum,
                 index: CRATE_DEF_INDEX,
diff --git a/src/librustc_typeck/check_unused.rs b/src/librustc_typeck/check_unused.rs
index 3da154e0689ad..e5e5b11e044d4 100644
--- a/src/librustc_typeck/check_unused.rs
+++ b/src/librustc_typeck/check_unused.rs
@@ -74,7 +74,7 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
     tcx.hir.krate().visit_all_item_likes(&mut visitor);
 
     for &(id, span) in &tcx.maybe_unused_extern_crates {
-        let cnum = tcx.sess.cstore.extern_mod_stmt_cnum(id).unwrap().as_def_id();
+        let cnum = tcx.cstore().extern_mod_stmt_cnum(id).unwrap().as_def_id();
         if !tcx.is_compiler_builtins(cnum)
             && !tcx.is_panic_runtime(cnum)
             && !tcx.has_global_allocator(cnum) {
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 5d39d1d27f4c3..957169e6c781e 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -120,7 +120,7 @@ pub fn load_attrs(cx: &DocContext, did: DefId) -> clean::Attributes {
 /// These names are used later on by HTML rendering to generate things like
 /// source links back to the original item.
 pub fn record_extern_fqn(cx: &DocContext, did: DefId, kind: clean::TypeKind) {
-    let crate_name = cx.tcx.sess.cstore.crate_name(did.krate).to_string();
+    let crate_name = cx.tcx.cstore().crate_name(did.krate).to_string();
     let relative = cx.tcx.def_path(did).data.into_iter().filter_map(|elem| {
         // extern blocks have an empty name
         let s = elem.data.to_string();
@@ -236,7 +236,7 @@ pub fn build_impls(cx: &DocContext, did: DefId) -> Vec<clean::Item> {
 
     cx.populated_all_crate_impls.set(true);
 
-    for did in tcx.sess.cstore.implementations_of_trait(None) {
+    for did in tcx.cstore().implementations_of_trait(None) {
         build_impl(cx, did, &mut impls);
     }
 
@@ -443,9 +443,9 @@ fn build_module(cx: &DocContext, did: DefId) -> clean::Module {
         // two namespaces, so the target may be listed twice. Make sure we only
         // visit each node at most once.
         let mut visited = FxHashSet();
-        for item in cx.tcx.sess.cstore.item_children(did, cx.tcx.sess) {
+        for item in cx.tcx.cstore().item_children(did, cx.tcx.sess) {
             let def_id = item.def.def_id();
-            if cx.tcx.sess.cstore.visibility(def_id) == ty::Visibility::Public {
+            if cx.tcx.cstore().visibility(def_id) == ty::Visibility::Public {
                 if !visited.insert(def_id) { continue }
                 if let Some(i) = try_inline(cx, item.def, item.ident.name) {
                     items.extend(i)
@@ -471,7 +471,7 @@ impl hir::print::PpAnn for InlinedConst {
 }
 
 fn print_inlined_const(cx: &DocContext, did: DefId) -> String {
-    let body = cx.tcx.sess.cstore.item_body(cx.tcx, did);
+    let body = cx.tcx.cstore().item_body(cx.tcx, did);
     let inlined = InlinedConst {
         nested_bodies: cx.tcx.item_body_nested_bodies(did)
     };
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index aab44ddce0e6a..2869dd452d1be 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -131,7 +131,7 @@ impl<'a, 'tcx> Clean<Crate> for visit_ast::RustdocVisitor<'a, 'tcx> {
         }
 
         let mut externs = Vec::new();
-        for cnum in cx.sess().cstore.crates() {
+        for cnum in cx.tcx.cstore().crates() {
             externs.push((cnum, cnum.clean(cx)));
             // Analyze doc-reachability for extern items
             LibEmbargoVisitor::new(cx).visit_lib(cnum);
@@ -244,7 +244,7 @@ impl Clean<ExternalCrate> for CrateNum {
                 }
             }).collect()
         } else {
-            cx.tcx.sess.cstore.item_children(root, cx.tcx.sess).iter().map(|item| item.def)
+            cx.tcx.cstore().item_children(root, cx.tcx.sess).iter().map(|item| item.def)
               .filter_map(as_primitive).collect()
         };
 
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 58de0e1caecdb..93f7230ab406d 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -148,7 +148,7 @@ pub fn run_core(search_paths: SearchPaths,
     let _ignore = dep_graph.in_ignore();
     let cstore = Rc::new(CStore::new(&dep_graph, box rustc_trans::LlvmMetadataLoader));
     let mut sess = session::build_session_(
-        sessopts, &dep_graph, cpath, diagnostic_handler, codemap, cstore.clone()
+        sessopts, &dep_graph, cpath, diagnostic_handler, codemap
     );
     rustc_trans::init(&sess);
     rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
@@ -181,6 +181,7 @@ pub fn run_core(search_paths: SearchPaths,
     let hir_map = hir_map::map_crate(&mut hir_forest, defs);
 
     abort_on_err(driver::phase_3_run_analysis_passes(&sess,
+                                                     &*cstore,
                                                      hir_map,
                                                      analysis,
                                                      resolutions,
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index 5d74cbdf56a19..38d59dbb944c6 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -87,7 +87,7 @@ pub fn run(input: &str,
     let _ignore = dep_graph.in_ignore();
     let cstore = Rc::new(CStore::new(&dep_graph, box rustc_trans::LlvmMetadataLoader));
     let mut sess = session::build_session_(
-        sessopts, &dep_graph, Some(input_path.clone()), handler, codemap.clone(), cstore.clone(),
+        sessopts, &dep_graph, Some(input_path.clone()), handler, codemap.clone()
     );
     rustc_trans::init(&sess);
     rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
@@ -240,7 +240,7 @@ fn run_test(test: &str, cratename: &str, filename: &str, cfgs: Vec<String>, libs
     let dep_graph = DepGraph::new(false);
     let cstore = Rc::new(CStore::new(&dep_graph, box rustc_trans::LlvmMetadataLoader));
     let mut sess = session::build_session_(
-        sessopts, &dep_graph, None, diagnostic_handler, codemap, cstore.clone(),
+        sessopts, &dep_graph, None, diagnostic_handler, codemap
     );
     rustc_trans::init(&sess);
     rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index 1f33cd7765164..27de8cc5d4f42 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -207,8 +207,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
                         continue // These are `krate.exported_macros`, handled in `self.visit()`.
                     }
 
-                    let imported_from = self.cx.sess().cstore.original_crate_name(def_id.krate);
-                    let def = match self.cx.sess().cstore.load_macro(def_id, self.cx.sess()) {
+                    let imported_from = self.cx.tcx.cstore().original_crate_name(def_id.krate);
+                    let def = match self.cx.tcx.cstore().load_macro(def_id, self.cx.sess()) {
                         LoadedMacro::MacroDef(macro_def) => macro_def,
                         // FIXME(jseyfried): document proc macro reexports
                         LoadedMacro::ProcMacro(..) => continue,
@@ -371,7 +371,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
             _ if self.inlining && item.vis != hir::Public => {}
             hir::ItemGlobalAsm(..) => {}
             hir::ItemExternCrate(ref p) => {
-                let cstore = &self.cx.sess().cstore;
+                let cstore = &self.cx.tcx.cstore();
                 om.extern_crates.push(ExternCrate {
                     cnum: cstore.extern_mod_stmt_cnum(item.id)
                                 .unwrap_or(LOCAL_CRATE),
diff --git a/src/librustdoc/visit_lib.rs b/src/librustdoc/visit_lib.rs
index 7b5b27c5565cb..a84cd6d0181e6 100644
--- a/src/librustdoc/visit_lib.rs
+++ b/src/librustdoc/visit_lib.rs
@@ -38,7 +38,7 @@ impl<'a, 'b, 'tcx> LibEmbargoVisitor<'a, 'b, 'tcx> {
     pub fn new(cx: &'a ::core::DocContext<'b, 'tcx>) -> LibEmbargoVisitor<'a, 'b, 'tcx> {
         LibEmbargoVisitor {
             cx,
-            cstore: &*cx.sess().cstore,
+            cstore: cx.tcx.cstore(),
             access_levels: cx.access_levels.borrow_mut(),
             prev_level: Some(AccessLevel::Public),
             visited_mods: FxHashSet()
diff --git a/src/test/run-make/issue-19371/foo.rs b/src/test/run-make/issue-19371/foo.rs
index e96588c6e5aea..4040c8495473e 100644
--- a/src/test/run-make/issue-19371/foo.rs
+++ b/src/test/run-make/issue-19371/foo.rs
@@ -60,7 +60,7 @@ fn basic_sess(sysroot: PathBuf) -> (Session, Rc<CStore>) {
     let descriptions = Registry::new(&rustc::DIAGNOSTICS);
     let dep_graph = DepGraph::new(opts.build_dep_graph());
     let cstore = Rc::new(CStore::new(&dep_graph, Box::new(rustc_trans::LlvmMetadataLoader)));
-    let sess = build_session(opts, &dep_graph, None, descriptions, cstore.clone());
+    let sess = build_session(opts, &dep_graph, None, descriptions);
     rustc_trans::init(&sess);
     rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
     (sess, cstore)
diff --git a/src/test/run-pass-fulldeps/compiler-calls.rs b/src/test/run-pass-fulldeps/compiler-calls.rs
index 4a397621ceb53..b5c1ee099037c 100644
--- a/src/test/run-pass-fulldeps/compiler-calls.rs
+++ b/src/test/run-pass-fulldeps/compiler-calls.rs
@@ -21,6 +21,7 @@ extern crate rustc_driver;
 extern crate syntax;
 extern crate rustc_errors as errors;
 
+use rustc::middle::cstore::CrateStore;
 use rustc::session::Session;
 use rustc::session::config::{self, Input};
 use rustc_driver::{driver, CompilerCalls, Compilation};
@@ -47,6 +48,7 @@ impl<'a> CompilerCalls<'a> for TestCalls {
     fn late_callback(&mut self,
                      _: &getopts::Matches,
                      _: &Session,
+                     _: &CrateStore,
                      _: &Input,
                      _: &Option<PathBuf>,
                      _: &Option<PathBuf>)