about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-11-29 14:51:59 +0000
committerbors <bors@rust-lang.org>2019-11-29 14:51:59 +0000
commitd99e0c6d02b159f305474f58c8c38027bb06e051 (patch)
tree669f3ce8eae2b58f129fdb237764ce9ff3389291
parentc4375c9dfdd7f31de909f6e9384bac1bf37b44da (diff)
parente84c926d4758ba8600a3841d442e888fd2c25f6b (diff)
downloadrust-d99e0c6d02b159f305474f58c8c38027bb06e051.tar.gz
rust-d99e0c6d02b159f305474f58c8c38027bb06e051.zip
Auto merge of #66697 - petrochenkov:nocstore, r=eddyb
rustc_metadata: Privatize more things and a couple of other refactorings

This PR continues https://github.com/rust-lang/rust/pull/66496 and hits the point of diminishing returns.
All fields of `CrateRoot` and `CrateMetadata` are privatized.
For read-only fields this certainly makes sense, but for a few fields updateable from outside of `rmeta.rs` (mostly `creader.rs`) it was done mostly for consistency, I can make them `pub(crate)` again if requested.

`cstore.rs` (which became small after #66496) was merged into `creader.rs`.

A few things noticed while making the privacy changes were addressed in the remaining refactoring commits.

Fixes https://github.com/rust-lang/rust/issues/66550
r? @eddyb @Mark-Simulacrum
-rw-r--r--src/librustc/middle/cstore.rs12
-rw-r--r--src/librustc/session/mod.rs4
-rw-r--r--src/librustc/ty/context.rs16
-rw-r--r--src/librustc_interface/passes.rs5
-rw-r--r--src/librustc_metadata/creader.rs302
-rw-r--r--src/librustc_metadata/cstore.rs99
-rw-r--r--src/librustc_metadata/dependency_format.rs6
-rw-r--r--src/librustc_metadata/lib.rs3
-rw-r--r--src/librustc_metadata/locator.rs31
-rw-r--r--src/librustc_metadata/rmeta/decoder.rs105
-rw-r--r--src/librustc_metadata/rmeta/decoder/cstore_impl.rs37
-rw-r--r--src/librustc_metadata/rmeta/encoder.rs3
-rw-r--r--src/librustc_metadata/rmeta/mod.rs24
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs2
-rw-r--r--src/librustc_resolve/lib.rs3
-rw-r--r--src/librustdoc/clean/inline.rs2
-rw-r--r--src/libsyntax/expand/allocator.rs6
-rw-r--r--src/test/ui/allocator/two-allocators3.stderr2
18 files changed, 338 insertions, 324 deletions
diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs
index e5c80c35894..44c6f6b07f5 100644
--- a/src/librustc/middle/cstore.rs
+++ b/src/librustc/middle/cstore.rs
@@ -146,6 +146,13 @@ impl ExternCrate {
     pub fn is_direct(&self) -> bool {
         self.dependency_of == LOCAL_CRATE
     }
+
+    pub fn rank(&self) -> impl PartialOrd {
+        // Prefer:
+        // - direct extern crate to indirect
+        // - shorter paths to longer
+        (self.is_direct(), !self.path_len)
+    }
 }
 
 #[derive(Copy, Clone, Debug, HashStable)]
@@ -204,7 +211,7 @@ pub type MetadataLoaderDyn = dyn MetadataLoader + Sync;
 /// (it'd break incremental compilation) and should only be called pre-HIR (e.g.
 /// during resolve)
 pub trait CrateStore {
-    fn crate_data_as_any(&self, cnum: CrateNum) -> &dyn Any;
+    fn as_any(&self) -> &dyn Any;
 
     // resolve
     fn def_key(&self, def: DefId) -> DefKey;
@@ -217,9 +224,7 @@ pub trait CrateStore {
     fn crate_is_private_dep_untracked(&self, cnum: CrateNum) -> bool;
     fn crate_disambiguator_untracked(&self, cnum: CrateNum) -> CrateDisambiguator;
     fn crate_hash_untracked(&self, cnum: CrateNum) -> Svh;
-    fn crate_host_hash_untracked(&self, cnum: CrateNum) -> Option<Svh>;
     fn item_generics_cloned_untracked(&self, def: DefId, sess: &Session) -> ty::Generics;
-    fn postorder_cnums_untracked(&self) -> Vec<CrateNum>;
 
     // This is basically a 1-based range of ints, which is a little
     // silly - I may fix that.
@@ -228,7 +233,6 @@ pub trait CrateStore {
     // utility functions
     fn encode_metadata(&self, tcx: TyCtxt<'_>) -> EncodedMetadata;
     fn metadata_encoding_version(&self) -> &[u8];
-    fn injected_panic_runtime(&self) -> Option<CrateNum>;
     fn allocator_kind(&self) -> Option<AllocatorKind>;
 }
 
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index af6522df61e..0b9d04ca6a3 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -133,9 +133,6 @@ pub struct Session {
     /// false positives about a job server in our environment.
     pub jobserver: Client,
 
-    /// Metadata about the allocators for the current crate being compiled.
-    pub has_global_allocator: Once<bool>,
-
     /// Cap lint level specified by a driver specifically.
     pub driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,
 
@@ -1180,7 +1177,6 @@ fn build_session_(
         print_fuel_crate,
         print_fuel,
         jobserver: jobserver::client(),
-        has_global_allocator: Once::new(),
         driver_lint_caps,
         trait_methods_not_found: Lock::new(Default::default()),
         confused_type_with_std_module: Lock::new(Default::default()),
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 95456581169..5a7078cdb26 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -1307,10 +1307,6 @@ impl<'tcx> TyCtxt<'tcx> {
         self.all_crate_nums(LOCAL_CRATE)
     }
 
-    pub fn injected_panic_runtime(self) -> Option<CrateNum> {
-        self.cstore.injected_panic_runtime()
-    }
-
     pub fn allocator_kind(self) -> Option<AllocatorKind> {
         self.cstore.allocator_kind()
     }
@@ -1391,8 +1387,8 @@ impl<'tcx> TyCtxt<'tcx> {
 
     // Note that this is *untracked* and should only be used within the query
     // system if the result is otherwise tracked through queries
-    pub fn crate_data_as_any(self, cnum: CrateNum) -> &'tcx dyn Any {
-        self.cstore.crate_data_as_any(cnum)
+    pub fn cstore_as_any(self) -> &'tcx dyn Any {
+        self.cstore.as_any()
     }
 
     #[inline(always)]
@@ -2999,14 +2995,6 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) {
         assert_eq!(cnum, LOCAL_CRATE);
         tcx.arena.alloc_slice(&tcx.cstore.crates_untracked())
     };
-    providers.crate_host_hash = |tcx, cnum| {
-        assert_ne!(cnum, LOCAL_CRATE);
-        tcx.cstore.crate_host_hash_untracked(cnum)
-    };
-    providers.postorder_cnums = |tcx, cnum| {
-        assert_eq!(cnum, LOCAL_CRATE);
-        tcx.arena.alloc_slice(&tcx.cstore.postorder_cnums_untracked())
-    };
     providers.output_filenames = |tcx, cnum| {
         assert_eq!(cnum, LOCAL_CRATE);
         tcx.output_filenames.clone()
diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs
index a745d63426b..5f00bebced3 100644
--- a/src/librustc_interface/passes.rs
+++ b/src/librustc_interface/passes.rs
@@ -25,7 +25,6 @@ use rustc_data_structures::{box_region_allow_access, declare_box_region_type, pa
 use rustc_data_structures::sync::{Lrc, ParallelIterator, par_iter};
 use rustc_errors::PResult;
 use rustc_incremental;
-use rustc_metadata::cstore;
 use rustc_mir as mir;
 use rustc_parse::{parse_crate_from_file, parse_crate_from_source_str};
 use rustc_passes::{self, ast_validation, hir_stats, layout_test};
@@ -728,7 +727,7 @@ pub fn default_provide(providers: &mut ty::query::Providers<'_>) {
     rustc_passes::provide(providers);
     rustc_traits::provide(providers);
     middle::region::provide(providers);
-    cstore::provide(providers);
+    rustc_metadata::provide(providers);
     lint::provide(providers);
     rustc_lint::provide(providers);
     rustc_codegen_utils::provide(providers);
@@ -736,7 +735,7 @@ pub fn default_provide(providers: &mut ty::query::Providers<'_>) {
 }
 
 pub fn default_provide_extern(providers: &mut ty::query::Providers<'_>) {
-    cstore::provide_extern(providers);
+    rustc_metadata::provide_extern(providers);
     rustc_codegen_ssa::provide_extern(providers);
 }
 
diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs
index 7b54b98cbc1..dbf2dcf1c0a 100644
--- a/src/librustc_metadata/creader.rs
+++ b/src/librustc_metadata/creader.rs
@@ -1,38 +1,47 @@
 //! Validates all used crates and extern libraries and loads their metadata
 
-use crate::cstore::CStore;
 use crate::locator::{CrateLocator, CratePaths};
 use crate::rmeta::{CrateMetadata, CrateNumMap, CrateRoot, CrateDep, MetadataBlob};
 
 use rustc::hir::def_id::CrateNum;
 use rustc_data_structures::svh::Svh;
+use rustc_data_structures::sync::Lrc;
+use rustc_index::vec::IndexVec;
 use rustc::middle::cstore::DepKind;
 use rustc::session::{Session, CrateDisambiguator};
 use rustc::session::config::{Sanitizer, self};
 use rustc_target::spec::{PanicStrategy, TargetTriple};
 use rustc::session::search_paths::PathKind;
 use rustc::middle::cstore::{CrateSource, ExternCrate, ExternCrateSource, MetadataLoaderDyn};
-use rustc::util::nodemap::FxHashSet;
 use rustc::hir::map::Definitions;
 use rustc::hir::def_id::LOCAL_CRATE;
+use rustc::ty::TyCtxt;
 
 use std::path::Path;
 use std::{cmp, fs};
 
 use syntax::ast;
 use syntax::attr;
+use syntax::edition::Edition;
 use syntax::expand::allocator::{global_allocator_spans, AllocatorKind};
 use syntax::symbol::{Symbol, sym};
 use syntax::span_fatal;
+use syntax_expand::base::SyntaxExtension;
 use syntax_pos::{Span, DUMMY_SP};
 use log::{debug, info, log_enabled};
 use proc_macro::bridge::client::ProcMacro;
 
 use rustc_error_codes::*;
 
-crate struct Library {
-    pub source: CrateSource,
-    pub metadata: MetadataBlob,
+#[derive(Clone)]
+pub struct CStore {
+    metas: IndexVec<CrateNum, Option<Lrc<CrateMetadata>>>,
+    injected_panic_runtime: Option<CrateNum>,
+    /// This crate needs an allocator and either provides it itself, or finds it in a dependency.
+    /// If the above is true, then this field denotes the kind of the found allocator.
+    allocator_kind: Option<AllocatorKind>,
+    /// This crate has a `#[global_allocator]` item.
+    has_global_allocator: bool,
 }
 
 pub struct CrateLoader<'a> {
@@ -44,18 +53,14 @@ pub struct CrateLoader<'a> {
     cstore: CStore,
 }
 
-fn dump_crates(cstore: &CStore) {
-    info!("resolved crates:");
-    cstore.iter_crate_data(|cnum, data| {
-        info!("  name: {}", data.root.name);
-        info!("  cnum: {}", cnum);
-        info!("  hash: {}", data.root.hash);
-        info!("  reqd: {:?}", *data.dep_kind.lock());
-        let CrateSource { dylib, rlib, rmeta } = data.source.clone();
-        dylib.map(|dl| info!("  dylib: {}", dl.0.display()));
-        rlib.map(|rl|  info!("   rlib: {}", rl.0.display()));
-        rmeta.map(|rl| info!("   rmeta: {}", rl.0.display()));
-    });
+pub enum LoadedMacro {
+    MacroDef(ast::Item, Edition),
+    ProcMacro(SyntaxExtension),
+}
+
+crate struct Library {
+    pub source: CrateSource,
+    pub metadata: MetadataBlob,
 }
 
 enum LoadResult {
@@ -75,6 +80,90 @@ impl<'a> LoadError<'a> {
     }
 }
 
+fn dump_crates(cstore: &CStore) {
+    info!("resolved crates:");
+    cstore.iter_crate_data(|cnum, data| {
+        info!("  name: {}", data.name());
+        info!("  cnum: {}", cnum);
+        info!("  hash: {}", data.hash());
+        info!("  reqd: {:?}", data.dep_kind());
+        let CrateSource { dylib, rlib, rmeta } = data.source();
+        dylib.as_ref().map(|dl| info!("  dylib: {}", dl.0.display()));
+        rlib.as_ref().map(|rl|  info!("   rlib: {}", rl.0.display()));
+        rmeta.as_ref().map(|rl| info!("   rmeta: {}", rl.0.display()));
+    });
+}
+
+impl CStore {
+    crate fn from_tcx(tcx: TyCtxt<'_>) -> &CStore {
+        tcx.cstore_as_any().downcast_ref::<CStore>().expect("`tcx.cstore` is not a `CStore`")
+    }
+
+    fn alloc_new_crate_num(&mut self) -> CrateNum {
+        self.metas.push(None);
+        CrateNum::new(self.metas.len() - 1)
+    }
+
+    crate fn get_crate_data(&self, cnum: CrateNum) -> &CrateMetadata {
+        self.metas[cnum].as_ref()
+            .unwrap_or_else(|| panic!("Failed to get crate data for {:?}", cnum))
+    }
+
+    fn set_crate_data(&mut self, cnum: CrateNum, data: CrateMetadata) {
+        assert!(self.metas[cnum].is_none(), "Overwriting crate metadata entry");
+        self.metas[cnum] = Some(Lrc::new(data));
+    }
+
+    crate fn iter_crate_data(&self, mut f: impl FnMut(CrateNum, &CrateMetadata)) {
+        for (cnum, data) in self.metas.iter_enumerated() {
+            if let Some(data) = data {
+                f(cnum, data);
+            }
+        }
+    }
+
+    fn push_dependencies_in_postorder(&self, deps: &mut Vec<CrateNum>, cnum: CrateNum) {
+        if !deps.contains(&cnum) {
+            let data = self.get_crate_data(cnum);
+            for &dep in data.dependencies().iter() {
+                if dep != cnum {
+                    self.push_dependencies_in_postorder(deps, dep);
+                }
+            }
+
+            deps.push(cnum);
+        }
+    }
+
+    crate fn crate_dependencies_in_postorder(&self, cnum: CrateNum) -> Vec<CrateNum> {
+        let mut deps = Vec::new();
+        if cnum == LOCAL_CRATE {
+            self.iter_crate_data(|cnum, _| self.push_dependencies_in_postorder(&mut deps, cnum));
+        } else {
+            self.push_dependencies_in_postorder(&mut deps, cnum);
+        }
+        deps
+    }
+
+    fn crate_dependencies_in_reverse_postorder(&self, cnum: CrateNum) -> Vec<CrateNum> {
+        let mut deps = self.crate_dependencies_in_postorder(cnum);
+        deps.reverse();
+        deps
+    }
+
+    crate fn injected_panic_runtime(&self) -> Option<CrateNum> {
+        self.injected_panic_runtime
+    }
+
+    crate fn allocator_kind(&self) -> Option<AllocatorKind> {
+        self.allocator_kind
+    }
+
+    crate fn has_global_allocator(&self) -> bool {
+        self.has_global_allocator
+    }
+}
+
 impl<'a> CrateLoader<'a> {
     pub fn new(
         sess: &'a Session,
@@ -85,7 +174,16 @@ impl<'a> CrateLoader<'a> {
             sess,
             metadata_loader,
             local_crate_name: Symbol::intern(local_crate_name),
-            cstore: Default::default(),
+            cstore: CStore {
+                // We add an empty entry for LOCAL_CRATE (which maps to zero) in
+                // order to make array indices in `metas` match with the
+                // corresponding `CrateNum`. This first entry will always remain
+                // `None`.
+                metas: IndexVec::from_elem_n(None, 1),
+                injected_panic_runtime: None,
+                allocator_kind: None,
+                has_global_allocator: false,
+            }
         }
     }
 
@@ -97,14 +195,13 @@ impl<'a> CrateLoader<'a> {
         self.cstore
     }
 
-    fn existing_match(&self, name: Symbol, hash: Option<&Svh>, kind: PathKind)
-                      -> Option<CrateNum> {
+    fn existing_match(&self, name: Symbol, hash: Option<Svh>, kind: PathKind) -> Option<CrateNum> {
         let mut ret = None;
         self.cstore.iter_crate_data(|cnum, data| {
-            if data.root.name != name { return }
+            if data.name() != name { return }
 
             match hash {
-                Some(hash) if *hash == data.root.hash => { ret = Some(cnum); return }
+                Some(hash) if hash == data.hash() => { ret = Some(cnum); return }
                 Some(..) => return,
                 None => {}
             }
@@ -118,7 +215,7 @@ impl<'a> CrateLoader<'a> {
             // We're also sure to compare *paths*, not actual byte slices. The
             // `source` stores paths which are normalized which may be different
             // from the strings on the command line.
-            let source = &self.cstore.get_crate_data(cnum).source;
+            let source = self.cstore.get_crate_data(cnum).source();
             if let Some(entry) = self.sess.opts.externs.get(&name.as_str()) {
                 // Only use `--extern crate_name=path` here, not `--extern crate_name`.
                 let found = entry.locations.iter().filter_map(|l| l.as_ref()).any(|l| {
@@ -152,26 +249,26 @@ impl<'a> CrateLoader<'a> {
                                   span: Span,
                                   root: &CrateRoot<'_>) {
         // Check for (potential) conflicts with the local crate
-        if self.local_crate_name == root.name &&
-           self.sess.local_crate_disambiguator() == root.disambiguator {
+        if self.local_crate_name == root.name() &&
+           self.sess.local_crate_disambiguator() == root.disambiguator() {
             span_fatal!(self.sess, span, E0519,
                         "the current crate is indistinguishable from one of its \
                          dependencies: it has the same crate-name `{}` and was \
                          compiled with the same `-C metadata` arguments. This \
                          will result in symbol conflicts between the two.",
-                        root.name)
+                        root.name())
         }
 
         // Check for conflicts with any crate loaded so far
         self.cstore.iter_crate_data(|_, other| {
-            if other.root.name == root.name && // same crate-name
-               other.root.disambiguator == root.disambiguator &&  // same crate-disambiguator
-               other.root.hash != root.hash { // but different SVH
+            if other.name() == root.name() && // same crate-name
+               other.disambiguator() == root.disambiguator() &&  // same crate-disambiguator
+               other.hash() != root.hash() { // but different SVH
                 span_fatal!(self.sess, span, E0523,
                         "found two different crates with name `{}` that are \
                          not distinguished by differing `-C metadata`. This \
                          will result in symbol conflicts between the two.",
-                        root.name)
+                        root.name())
             }
         });
     }
@@ -189,14 +286,14 @@ impl<'a> CrateLoader<'a> {
 
         let Library { source, metadata } = lib;
         let crate_root = metadata.get_root();
-        let host_hash = host_lib.as_ref().map(|lib| lib.metadata.get_root().hash);
+        let host_hash = host_lib.as_ref().map(|lib| lib.metadata.get_root().hash());
         self.verify_no_symbol_conflicts(span, &crate_root);
 
         let private_dep = self.sess.opts.externs.get(&name.as_str())
             .map(|e| e.is_private_dep)
             .unwrap_or(false);
 
-        info!("register crate `{}` (private_dep = {})", crate_root.name, private_dep);
+        info!("register crate `{}` (private_dep = {})", crate_root.name(), private_dep);
 
         // Claim this crate number and cache it
         let cnum = self.cstore.alloc_new_crate_num();
@@ -207,7 +304,7 @@ impl<'a> CrateLoader<'a> {
         let root = if let Some(root) = root {
             root
         } else {
-            crate_paths = CratePaths::new(crate_root.name, source.clone());
+            crate_paths = CratePaths::new(crate_root.name(), source.clone());
             &crate_paths
         };
 
@@ -221,7 +318,7 @@ impl<'a> CrateLoader<'a> {
                 None => (&source, &crate_root),
             };
             let dlsym_dylib = dlsym_source.dylib.as_ref().expect("no dylib for a proc-macro crate");
-            Some(self.dlsym_proc_macros(&dlsym_dylib.0, dlsym_root.disambiguator, span))
+            Some(self.dlsym_proc_macros(&dlsym_dylib.0, dlsym_root.disambiguator(), span))
         } else {
             None
         };
@@ -316,10 +413,10 @@ impl<'a> CrateLoader<'a> {
         let (root, hash, host_hash, extra_filename, path_kind) = match dep {
             Some((root, dep)) => (
                 Some(root),
-                Some(&dep.hash),
-                dep.host_hash.as_ref(),
+                Some(dep.hash),
+                dep.host_hash,
                 Some(&dep.extra_filename[..]),
-                PathKind::Dependency
+                PathKind::Dependency,
             ),
             None => (None, None, None, None, PathKind::Crate),
         };
@@ -350,12 +447,10 @@ impl<'a> CrateLoader<'a> {
         match result {
             (LoadResult::Previous(cnum), None) => {
                 let data = self.cstore.get_crate_data(cnum);
-                if data.root.is_proc_macro_crate() {
+                if data.is_proc_macro_crate() {
                     dep_kind = DepKind::UnexportedMacrosOnly;
                 }
-                data.dep_kind.with_lock(|data_dep_kind| {
-                    *data_dep_kind = cmp::max(*data_dep_kind, dep_kind);
-                });
+                data.update_dep_kind(|data_dep_kind| cmp::max(data_dep_kind, dep_kind));
                 Ok(cnum)
             }
             (LoadResult::Loaded(library), host_library) => {
@@ -380,7 +475,7 @@ impl<'a> CrateLoader<'a> {
         if locator.triple == self.sess.opts.target_triple {
             let mut result = LoadResult::Loaded(library);
             self.cstore.iter_crate_data(|cnum, data| {
-                if data.root.name == root.name && root.hash == data.root.hash {
+                if data.name() == root.name() && root.hash() == data.hash() {
                     assert!(locator.hash.is_none());
                     info!("load success, going to previous cnum: {}", cnum);
                     result = LoadResult::Previous(cnum);
@@ -392,44 +487,14 @@ impl<'a> CrateLoader<'a> {
         }
     }
 
-    fn update_extern_crate(&self,
-                           cnum: CrateNum,
-                           mut extern_crate: ExternCrate,
-                           visited: &mut FxHashSet<(CrateNum, bool)>)
-    {
-        if !visited.insert((cnum, extern_crate.is_direct())) { return }
-
+    fn update_extern_crate(&self, cnum: CrateNum, extern_crate: ExternCrate) {
         let cmeta = self.cstore.get_crate_data(cnum);
-        let mut old_extern_crate = cmeta.extern_crate.borrow_mut();
-
-        // Prefer:
-        // - something over nothing (tuple.0);
-        // - direct extern crate to indirect (tuple.1);
-        // - shorter paths to longer (tuple.2).
-        let new_rank = (
-            true,
-            extern_crate.is_direct(),
-            cmp::Reverse(extern_crate.path_len),
-        );
-        let old_rank = match *old_extern_crate {
-            None => (false, false, cmp::Reverse(usize::max_value())),
-            Some(ref c) => (
-                true,
-                c.is_direct(),
-                cmp::Reverse(c.path_len),
-            ),
-        };
-        if old_rank >= new_rank {
-            return; // no change needed
-        }
-
-        *old_extern_crate = Some(extern_crate);
-        drop(old_extern_crate);
-
-        // Propagate the extern crate info to dependencies.
-        extern_crate.dependency_of = cnum;
-        for &dep_cnum in cmeta.dependencies.borrow().iter() {
-            self.update_extern_crate(dep_cnum, extern_crate, visited);
+        if cmeta.update_extern_crate(extern_crate) {
+            // Propagate the extern crate info to dependencies if it was updated.
+            let extern_crate = ExternCrate { dependency_of: cnum, ..extern_crate };
+            for &dep_cnum in cmeta.dependencies().iter() {
+                self.update_extern_crate(dep_cnum, extern_crate);
+            }
         }
     }
 
@@ -503,7 +568,6 @@ impl<'a> CrateLoader<'a> {
         });
         if !any_non_rlib {
             info!("panic runtime injection skipped, only generating rlib");
-            self.cstore.injected_panic_runtime = None;
             return
         }
 
@@ -520,14 +584,13 @@ impl<'a> CrateLoader<'a> {
                                                           sym::needs_panic_runtime);
 
         self.cstore.iter_crate_data(|cnum, data| {
-            needs_panic_runtime = needs_panic_runtime ||
-                                  data.root.needs_panic_runtime;
-            if data.root.panic_runtime {
+            needs_panic_runtime = needs_panic_runtime || data.needs_panic_runtime();
+            if data.is_panic_runtime() {
                 // Inject a dependency from all #![needs_panic_runtime] to this
                 // #![panic_runtime] crate.
                 self.inject_dependency_if(cnum, "a panic runtime",
-                                          &|data| data.root.needs_panic_runtime);
-                runtime_found = runtime_found || *data.dep_kind.lock() == DepKind::Explicit;
+                                          &|data| data.needs_panic_runtime());
+                runtime_found = runtime_found || data.dep_kind() == DepKind::Explicit;
             }
         });
 
@@ -535,7 +598,6 @@ impl<'a> CrateLoader<'a> {
         // we just don't need one at all, then we're done here and there's
         // nothing else to do.
         if !needs_panic_runtime || runtime_found {
-            self.cstore.injected_panic_runtime = None;
             return
         }
 
@@ -562,11 +624,11 @@ impl<'a> CrateLoader<'a> {
 
         // Sanity check the loaded crate to ensure it is indeed a panic runtime
         // and the panic strategy is indeed what we thought it was.
-        if !data.root.panic_runtime {
+        if !data.is_panic_runtime() {
             self.sess.err(&format!("the crate `{}` is not a panic runtime",
                                    name));
         }
-        if data.root.panic_strategy != desired_strategy {
+        if data.panic_strategy() != desired_strategy {
             self.sess.err(&format!("the crate `{}` does not have the panic \
                                     strategy `{}`",
                                    name, desired_strategy.desc()));
@@ -574,7 +636,7 @@ impl<'a> CrateLoader<'a> {
 
         self.cstore.injected_panic_runtime = Some(cnum);
         self.inject_dependency_if(cnum, "a panic runtime",
-                                  &|data| data.root.needs_panic_runtime);
+                                  &|data| data.needs_panic_runtime());
     }
 
     fn inject_sanitizer_runtime(&mut self) {
@@ -648,7 +710,7 @@ impl<'a> CrateLoader<'a> {
 
             let mut uses_std = false;
             self.cstore.iter_crate_data(|_, data| {
-                if data.root.name == sym::std {
+                if data.name() == sym::std {
                     uses_std = true;
                 }
             });
@@ -666,7 +728,7 @@ impl<'a> CrateLoader<'a> {
                 let data = self.cstore.get_crate_data(cnum);
 
                 // Sanity check the loaded crate to ensure it is indeed a sanitizer runtime
-                if !data.root.sanitizer_runtime {
+                if !data.is_sanitizer_runtime() {
                     self.sess.err(&format!("the crate `{}` is not a sanitizer runtime",
                                            name));
                 }
@@ -687,7 +749,7 @@ impl<'a> CrateLoader<'a> {
             let data = self.cstore.get_crate_data(cnum);
 
             // Sanity check the loaded crate to ensure it is indeed a profiler runtime
-            if !data.root.profiler_runtime {
+            if !data.is_profiler_runtime() {
                 self.sess.err(&format!("the crate `profiler_builtins` is not \
                                         a profiler runtime"));
             }
@@ -695,7 +757,7 @@ impl<'a> CrateLoader<'a> {
     }
 
     fn inject_allocator_crate(&mut self, krate: &ast::Crate) {
-        let has_global_allocator = match &*global_allocator_spans(krate) {
+        self.cstore.has_global_allocator = match &*global_allocator_spans(krate) {
             [span1, span2, ..] => {
                 self.sess.struct_span_err(*span2, "cannot define multiple global allocators")
                     .span_label(*span2, "cannot define a new global allocator")
@@ -705,7 +767,6 @@ impl<'a> CrateLoader<'a> {
             }
             spans => !spans.is_empty()
         };
-        self.sess.has_global_allocator.set(has_global_allocator);
 
         // Check to see if we actually need an allocator. This desire comes
         // about through the `#![needs_allocator]` attribute and is typically
@@ -713,10 +774,9 @@ impl<'a> CrateLoader<'a> {
         let mut needs_allocator = attr::contains_name(&krate.attrs,
                                                       sym::needs_allocator);
         self.cstore.iter_crate_data(|_, data| {
-            needs_allocator = needs_allocator || data.root.needs_allocator;
+            needs_allocator = needs_allocator || data.needs_allocator();
         });
         if !needs_allocator {
-            self.cstore.allocator_kind = None;
             return
         }
 
@@ -732,7 +792,6 @@ impl<'a> CrateLoader<'a> {
                 }
             });
         if all_rlib {
-            self.cstore.allocator_kind = None;
             return
         }
 
@@ -743,29 +802,24 @@ impl<'a> CrateLoader<'a> {
         // First up we check for global allocators. Look at the crate graph here
         // and see what's a global allocator, including if we ourselves are a
         // global allocator.
-        let mut global_allocator = if has_global_allocator {
-            Some(None)
+        let mut global_allocator = if self.cstore.has_global_allocator {
+            Some(Symbol::intern("this crate"))
         } else {
             None
         };
         self.cstore.iter_crate_data(|_, data| {
-            if !data.root.has_global_allocator {
+            if !data.has_global_allocator() {
                 return
             }
             match global_allocator {
-                Some(Some(other_crate)) => {
+                Some(other_crate) => {
                     self.sess.err(&format!("the `#[global_allocator]` in {} \
-                                            conflicts with this global \
+                                            conflicts with global \
                                             allocator in: {}",
                                            other_crate,
-                                           data.root.name));
+                                           data.name()));
                 }
-                Some(None) => {
-                    self.sess.err(&format!("the `#[global_allocator]` in this \
-                                            crate conflicts with global \
-                                            allocator in: {}", data.root.name));
-                }
-                None => global_allocator = Some(Some(data.root.name)),
+                None => global_allocator = Some(data.name()),
             }
         });
         if global_allocator.is_some() {
@@ -779,7 +833,7 @@ impl<'a> CrateLoader<'a> {
         // attribute.
         let mut has_default = attr::contains_name(&krate.attrs, sym::default_lib_allocator);
         self.cstore.iter_crate_data(|_, data| {
-            if data.root.has_default_lib_allocator {
+            if data.has_default_lib_allocator() {
                 has_default = true;
             }
         });
@@ -790,7 +844,7 @@ impl<'a> CrateLoader<'a> {
                            add `#[global_allocator]` to a static item \
                            that implements the GlobalAlloc trait.");
         }
-        self.cstore.allocator_kind = Some(AllocatorKind::DefaultLib);
+        self.cstore.allocator_kind = Some(AllocatorKind::Default);
     }
 
     fn inject_dependency_if(&self,
@@ -807,15 +861,15 @@ impl<'a> CrateLoader<'a> {
         // Before we inject any dependencies, make sure we don't inject a
         // circular dependency by validating that this crate doesn't
         // transitively depend on any crates satisfying `needs_dep`.
-        for dep in self.cstore.crate_dependencies_in_rpo(krate) {
+        for dep in self.cstore.crate_dependencies_in_reverse_postorder(krate) {
             let data = self.cstore.get_crate_data(dep);
             if needs_dep(&data) {
                 self.sess.err(&format!("the crate `{}` cannot depend \
                                         on a crate that needs {}, but \
                                         it depends on `{}`",
-                                       self.cstore.get_crate_data(krate).root.name,
+                                       self.cstore.get_crate_data(krate).name(),
                                        what,
-                                       data.root.name));
+                                       data.name()));
             }
         }
 
@@ -829,7 +883,7 @@ impl<'a> CrateLoader<'a> {
             }
 
             info!("injecting a dep from {} to {}", cnum, krate);
-            data.dependencies.borrow_mut().push(krate);
+            data.add_dependency(krate);
         });
     }
 
@@ -879,7 +933,6 @@ impl<'a> CrateLoader<'a> {
                         path_len,
                         dependency_of: LOCAL_CRATE,
                     },
-                    &mut FxHashSet::default(),
                 );
                 cnum
             }
@@ -899,27 +952,12 @@ impl<'a> CrateLoader<'a> {
                 path_len: usize::max_value(),
                 dependency_of: LOCAL_CRATE,
             },
-            &mut FxHashSet::default(),
         );
 
         cnum
     }
 
     pub fn maybe_process_path_extern(&mut self, name: Symbol, span: Span) -> Option<CrateNum> {
-        let cnum = self.maybe_resolve_crate(name, span, DepKind::Explicit, None).ok()?;
-
-        self.update_extern_crate(
-            cnum,
-            ExternCrate {
-                src: ExternCrateSource::Path,
-                span,
-                // to have the least priority in `update_extern_crate`
-                path_len: usize::max_value(),
-                dependency_of: LOCAL_CRATE,
-            },
-            &mut FxHashSet::default(),
-        );
-
-        Some(cnum)
+        self.maybe_resolve_crate(name, span, DepKind::Explicit, None).ok()
     }
 }
diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs
deleted file mode 100644
index 48cf0b982f2..00000000000
--- a/src/librustc_metadata/cstore.rs
+++ /dev/null
@@ -1,99 +0,0 @@
-// The crate store - a central repo for information collected about external
-// crates and libraries
-
-use crate::rmeta::CrateMetadata;
-
-use rustc_data_structures::sync::Lrc;
-use rustc_index::vec::IndexVec;
-use rustc::hir::def_id::CrateNum;
-use syntax::ast;
-use syntax::edition::Edition;
-use syntax::expand::allocator::AllocatorKind;
-use syntax_expand::base::SyntaxExtension;
-
-pub use crate::rmeta::{provide, provide_extern};
-
-#[derive(Clone)]
-pub struct CStore {
-    metas: IndexVec<CrateNum, Option<Lrc<CrateMetadata>>>,
-    crate injected_panic_runtime: Option<CrateNum>,
-    crate allocator_kind: Option<AllocatorKind>,
-}
-
-pub enum LoadedMacro {
-    MacroDef(ast::Item, Edition),
-    ProcMacro(SyntaxExtension),
-}
-
-impl Default for CStore {
-    fn default() -> Self {
-        CStore {
-            // We add an empty entry for LOCAL_CRATE (which maps to zero) in
-            // order to make array indices in `metas` match with the
-            // corresponding `CrateNum`. This first entry will always remain
-            // `None`.
-            metas: IndexVec::from_elem_n(None, 1),
-            injected_panic_runtime: None,
-            allocator_kind: None,
-        }
-    }
-}
-
-impl CStore {
-    crate fn alloc_new_crate_num(&mut self) -> CrateNum {
-        self.metas.push(None);
-        CrateNum::new(self.metas.len() - 1)
-    }
-
-    crate fn get_crate_data(&self, cnum: CrateNum) -> &CrateMetadata {
-        self.metas[cnum].as_ref()
-            .unwrap_or_else(|| panic!("Failed to get crate data for {:?}", cnum))
-    }
-
-    crate fn set_crate_data(&mut self, cnum: CrateNum, data: CrateMetadata) {
-        assert!(self.metas[cnum].is_none(), "Overwriting crate metadata entry");
-        self.metas[cnum] = Some(Lrc::new(data));
-    }
-
-    crate fn iter_crate_data<I>(&self, mut i: I)
-        where I: FnMut(CrateNum, &CrateMetadata)
-    {
-        for (k, v) in self.metas.iter_enumerated() {
-            if let &Some(ref v) = v {
-                i(k, v);
-            }
-        }
-    }
-
-    crate fn crate_dependencies_in_rpo(&self, krate: CrateNum) -> Vec<CrateNum> {
-        let mut ordering = Vec::new();
-        self.push_dependencies_in_postorder(&mut ordering, krate);
-        ordering.reverse();
-        ordering
-    }
-
-    crate fn push_dependencies_in_postorder(&self, ordering: &mut Vec<CrateNum>, krate: CrateNum) {
-        if ordering.contains(&krate) {
-            return;
-        }
-
-        let data = self.get_crate_data(krate);
-        for &dep in data.dependencies.borrow().iter() {
-            if dep != krate {
-                self.push_dependencies_in_postorder(ordering, dep);
-            }
-        }
-
-        ordering.push(krate);
-    }
-
-    crate fn do_postorder_cnums_untracked(&self) -> Vec<CrateNum> {
-        let mut ordering = Vec::new();
-        for (num, v) in self.metas.iter_enumerated() {
-            if let &Some(_) = v {
-                self.push_dependencies_in_postorder(&mut ordering, num);
-            }
-        }
-        return ordering
-    }
-}
diff --git a/src/librustc_metadata/dependency_format.rs b/src/librustc_metadata/dependency_format.rs
index dbf7fede146..d6d722c47b3 100644
--- a/src/librustc_metadata/dependency_format.rs
+++ b/src/librustc_metadata/dependency_format.rs
@@ -51,6 +51,8 @@
 //! Additionally, the algorithm is geared towards finding *any* solution rather
 //! than finding a number of solutions (there are normally quite a few).
 
+use crate::creader::CStore;
+
 use rustc::hir::def_id::CrateNum;
 use rustc::middle::cstore::LinkagePreference::{self, RequireStatic, RequireDynamic};
 use rustc::middle::cstore::{self, DepKind};
@@ -184,7 +186,7 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: config::CrateType) -> DependencyList {
     //
     // Things like allocators and panic runtimes may not have been activated
     // quite yet, so do so here.
-    activate_injected_dep(tcx.injected_panic_runtime(), &mut ret,
+    activate_injected_dep(CStore::from_tcx(tcx).injected_panic_runtime(), &mut ret,
                           &|cnum| tcx.is_panic_runtime(cnum));
 
     // When dylib B links to dylib A, then when using B we must also link to A.
@@ -263,7 +265,7 @@ fn attempt_static(tcx: TyCtxt<'_>) -> Option<DependencyList> {
     // Our allocator/panic runtime may not have been linked above if it wasn't
     // explicitly linked, which is the case for any injected dependency. Handle
     // that here and activate them.
-    activate_injected_dep(tcx.injected_panic_runtime(), &mut ret,
+    activate_injected_dep(CStore::from_tcx(tcx).injected_panic_runtime(), &mut ret,
                           &|cnum| tcx.is_panic_runtime(cnum));
 
     Some(ret)
diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs
index 35ac7686647..8c0b7345e1e 100644
--- a/src/librustc_metadata/lib.rs
+++ b/src/librustc_metadata/lib.rs
@@ -24,6 +24,8 @@ extern crate rustc;
 #[macro_use]
 extern crate rustc_data_structures;
 
+pub use rmeta::{provide, provide_extern};
+
 mod dependency_format;
 mod foreign_modules;
 mod link_args;
@@ -31,7 +33,6 @@ mod native_libs;
 mod rmeta;
 
 pub mod creader;
-pub mod cstore;
 pub mod dynamic_lib;
 pub mod locator;
 
diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs
index 64230fd9e60..c6fb80eca05 100644
--- a/src/librustc_metadata/locator.rs
+++ b/src/librustc_metadata/locator.rs
@@ -262,8 +262,8 @@ crate struct CrateLocator<'a> {
     // Immutable per-search configuration.
     crate_name: Symbol,
     exact_paths: Vec<PathBuf>,
-    pub hash: Option<&'a Svh>,
-    pub host_hash: Option<&'a Svh>,
+    pub hash: Option<Svh>,
+    pub host_hash: Option<Svh>,
     extra_filename: Option<&'a str>,
     pub target: &'a Target,
     pub triple: TargetTriple,
@@ -313,8 +313,8 @@ impl<'a> CrateLocator<'a> {
         sess: &'a Session,
         metadata_loader: &'a dyn MetadataLoader,
         crate_name: Symbol,
-        hash: Option<&'a Svh>,
-        host_hash: Option<&'a Svh>,
+        hash: Option<Svh>,
+        host_hash: Option<Svh>,
         extra_filename: Option<&'a str>,
         is_host: bool,
         path_kind: PathKind,
@@ -597,7 +597,7 @@ impl<'a> CrateLocator<'a> {
                                                "multiple matching crates for `{}`",
                                                self.crate_name);
                 let candidates = libraries.iter().filter_map(|(_, lib)| {
-                    let crate_name = &lib.metadata.get_root().name.as_str();
+                    let crate_name = &lib.metadata.get_root().name().as_str();
                     match &(&lib.source.dylib, &lib.source.rlib) {
                         &(&Some((ref pd, _)), &Some((ref pr, _))) => {
                             Some(format!("\ncrate `{}`: {}\n{:>padding$}",
@@ -774,35 +774,36 @@ impl<'a> CrateLocator<'a> {
         }
 
         if self.exact_paths.is_empty() {
-            if self.crate_name != root.name {
+            if self.crate_name != root.name() {
                 info!("Rejecting via crate name");
                 return None;
             }
         }
 
-        if root.triple != self.triple {
+        if root.triple() != &self.triple {
             info!("Rejecting via crate triple: expected {} got {}",
                   self.triple,
-                  root.triple);
+                  root.triple());
             self.rejected_via_triple.push(CrateMismatch {
                 path: libpath.to_path_buf(),
-                got: root.triple.to_string(),
+                got: root.triple().to_string(),
             });
             return None;
         }
 
-        if let Some(myhash) = self.hash {
-            if *myhash != root.hash {
-                info!("Rejecting via hash: expected {} got {}", *myhash, root.hash);
+        let hash = root.hash();
+        if let Some(expected_hash) = self.hash {
+            if hash != expected_hash {
+                info!("Rejecting via hash: expected {} got {}", expected_hash, hash);
                 self.rejected_via_hash.push(CrateMismatch {
                     path: libpath.to_path_buf(),
-                    got: myhash.to_string(),
+                    got: hash.to_string(),
                 });
                 return None;
             }
         }
 
-        Some(root.hash)
+        Some(hash)
     }
 
 
@@ -1021,7 +1022,7 @@ pub fn find_plugin_registrar(
 
     match library.source.dylib {
         Some(dylib) => {
-            Some((dylib.0, library.metadata.get_root().disambiguator))
+            Some((dylib.0, library.metadata.get_root().disambiguator()))
         }
         None => {
             span_err!(sess, span, E0457,
diff --git a/src/librustc_metadata/rmeta/decoder.rs b/src/librustc_metadata/rmeta/decoder.rs
index e6ccbf5c38b..820783bab6d 100644
--- a/src/librustc_metadata/rmeta/decoder.rs
+++ b/src/librustc_metadata/rmeta/decoder.rs
@@ -4,7 +4,7 @@ use crate::rmeta::*;
 use crate::rmeta::table::{FixedSizeEncoding, Table};
 
 use rustc_index::vec::{Idx, IndexVec};
-use rustc_data_structures::sync::{Lrc, Lock, Once, AtomicCell};
+use rustc_data_structures::sync::{Lrc, Lock, LockGuard, Once, AtomicCell};
 use rustc::hir::map::{DefKey, DefPath, DefPathData, DefPathHash};
 use rustc::hir::map::definitions::DefPathTable;
 use rustc::hir;
@@ -66,7 +66,7 @@ crate struct CrateMetadata {
     /// lifetime is only used behind `Lazy`, and therefore acts like an
     /// universal (`for<'tcx>`), that is paired up with whichever `TyCtxt`
     /// is being used to decode those values.
-    crate root: CrateRoot<'static>,
+    root: CrateRoot<'static>,
     /// For each definition in this crate, we encode a key. When the
     /// crate is loaded, we read all the keys and put them in this
     /// hashmap, which gives the reverse mapping. This allows us to
@@ -97,11 +97,11 @@ crate struct CrateMetadata {
     /// IDs as they are seen from the current compilation session.
     cnum_map: CrateNumMap,
     /// Same ID set as `cnum_map` plus maybe some injected crates like panic runtime.
-    crate dependencies: Lock<Vec<CrateNum>>,
+    dependencies: Lock<Vec<CrateNum>>,
     /// How to link (or not link) this crate to the currently compiled crate.
-    crate dep_kind: Lock<DepKind>,
+    dep_kind: Lock<DepKind>,
     /// Filesystem location of this crate.
-    crate source: CrateSource,
+    source: CrateSource,
     /// Whether or not this crate should be consider a private dependency
     /// for purposes of the 'exported_private_dependencies' lint
     private_dep: bool,
@@ -112,7 +112,7 @@ crate struct CrateMetadata {
 
     /// Information about the `extern crate` item or path that caused this crate to be loaded.
     /// If this is `None`, then the crate was injected (e.g., by the allocator).
-    crate extern_crate: Lock<Option<ExternCrate>>,
+    extern_crate: Lock<Option<ExternCrate>>,
 }
 
 /// Holds information about a syntax_pos::SourceFile imported from another crate.
@@ -558,6 +558,22 @@ impl CrateRoot<'_> {
         self.proc_macro_data.is_some()
     }
 
+    crate fn name(&self) -> Symbol {
+        self.name
+    }
+
+    crate fn disambiguator(&self) -> CrateDisambiguator {
+        self.disambiguator
+    }
+
+    crate fn hash(&self) -> Svh {
+        self.hash
+    }
+
+    crate fn triple(&self) -> &TargetTriple {
+        &self.triple
+    }
+
     crate fn decode_crate_deps(
         &self,
         metadata: &'a MetadataBlob,
@@ -1517,6 +1533,83 @@ impl<'a, 'tcx> CrateMetadata {
 
         dep_node_index
     }
+
+    crate fn dependencies(&self) -> LockGuard<'_, Vec<CrateNum>> {
+        self.dependencies.borrow()
+    }
+
+    crate fn add_dependency(&self, cnum: CrateNum) {
+        self.dependencies.borrow_mut().push(cnum);
+    }
+
+    crate fn update_extern_crate(&self, new_extern_crate: ExternCrate) -> bool {
+        let mut extern_crate = self.extern_crate.borrow_mut();
+        let update = Some(new_extern_crate.rank()) > extern_crate.as_ref().map(ExternCrate::rank);
+        if update {
+            *extern_crate = Some(new_extern_crate);
+        }
+        update
+    }
+
+    crate fn source(&self) -> &CrateSource {
+        &self.source
+    }
+
+    crate fn dep_kind(&self) -> DepKind {
+        *self.dep_kind.lock()
+    }
+
+    crate fn update_dep_kind(&self, f: impl FnOnce(DepKind) -> DepKind) {
+        self.dep_kind.with_lock(|dep_kind| *dep_kind = f(*dep_kind))
+    }
+
+    crate fn panic_strategy(&self) -> PanicStrategy {
+        self.root.panic_strategy
+    }
+
+    crate fn needs_panic_runtime(&self) -> bool {
+        self.root.needs_panic_runtime
+    }
+
+    crate fn is_panic_runtime(&self) -> bool {
+        self.root.panic_runtime
+    }
+
+    crate fn is_sanitizer_runtime(&self) -> bool {
+        self.root.sanitizer_runtime
+    }
+
+    crate fn is_profiler_runtime(&self) -> bool {
+        self.root.profiler_runtime
+    }
+
+    crate fn needs_allocator(&self) -> bool {
+        self.root.needs_allocator
+    }
+
+    crate fn has_global_allocator(&self) -> bool {
+        self.root.has_global_allocator
+    }
+
+    crate fn has_default_lib_allocator(&self) -> bool {
+        self.root.has_default_lib_allocator
+    }
+
+    crate fn is_proc_macro_crate(&self) -> bool {
+        self.root.is_proc_macro_crate()
+    }
+
+    crate fn name(&self) -> Symbol {
+        self.root.name
+    }
+
+    crate fn disambiguator(&self) -> CrateDisambiguator {
+        self.root.disambiguator
+    }
+
+    crate fn hash(&self) -> Svh {
+        self.root.hash
+    }
 }
 
 // Cannot be implemented on 'ProcMacro', as libproc_macro
diff --git a/src/librustc_metadata/rmeta/decoder/cstore_impl.rs b/src/librustc_metadata/rmeta/decoder/cstore_impl.rs
index abb0ceb4ff4..8214153f153 100644
--- a/src/librustc_metadata/rmeta/decoder/cstore_impl.rs
+++ b/src/librustc_metadata/rmeta/decoder/cstore_impl.rs
@@ -1,4 +1,4 @@
-use crate::cstore::{self, LoadedMacro};
+use crate::creader::{CStore, LoadedMacro};
 use crate::link_args;
 use crate::native_libs;
 use crate::foreign_modules;
@@ -51,9 +51,7 @@ macro_rules! provide {
                 let ($def_id, $other) = def_id_arg.into_args();
                 assert!(!$def_id.is_local());
 
-                let $cdata = $tcx.crate_data_as_any($def_id.krate);
-                let $cdata = $cdata.downcast_ref::<rmeta::CrateMetadata>()
-                    .expect("CrateStore created data is not a CrateMetadata");
+                let $cdata = CStore::from_tcx($tcx).get_crate_data($def_id.krate);
 
                 if $tcx.dep_graph.is_fully_enabled() {
                     let crate_dep_node_index = $cdata.get_crate_dep_node_index($tcx);
@@ -192,6 +190,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
     }
     crate_disambiguator => { cdata.root.disambiguator }
     crate_hash => { cdata.root.hash }
+    crate_host_hash => { cdata.host_hash }
     original_crate_name => { cdata.root.name }
 
     extra_filename => { cdata.root.extra_filename.clone() }
@@ -377,12 +376,20 @@ pub fn provide(providers: &mut Providers<'_>) {
             assert_eq!(cnum, LOCAL_CRATE);
             Lrc::new(crate::dependency_format::calculate(tcx))
         },
+        has_global_allocator: |tcx, cnum| {
+            assert_eq!(cnum, LOCAL_CRATE);
+            CStore::from_tcx(tcx).has_global_allocator()
+        },
+        postorder_cnums: |tcx, cnum| {
+            assert_eq!(cnum, LOCAL_CRATE);
+            tcx.arena.alloc_slice(&CStore::from_tcx(tcx).crate_dependencies_in_postorder(cnum))
+        },
 
         ..*providers
     };
 }
 
-impl cstore::CStore {
+impl CStore {
     pub fn export_macros_untracked(&self, cnum: CrateNum) {
         let data = self.get_crate_data(cnum);
         let mut dep_kind = data.dep_kind.lock();
@@ -458,9 +465,9 @@ impl cstore::CStore {
     }
 }
 
-impl CrateStore for cstore::CStore {
-    fn crate_data_as_any(&self, cnum: CrateNum) -> &dyn Any {
-        self.get_crate_data(cnum)
+impl CrateStore for CStore {
+    fn as_any(&self) -> &dyn Any {
+        self
     }
 
     fn item_generics_cloned_untracked(&self, def: DefId, sess: &Session) -> ty::Generics {
@@ -486,10 +493,6 @@ impl CrateStore for cstore::CStore {
         self.get_crate_data(cnum).root.hash
     }
 
-    fn crate_host_hash_untracked(&self, cnum: CrateNum) -> Option<Svh> {
-        self.get_crate_data(cnum).host_hash
-    }
-
     /// Returns the `DefKey` for a given `DefId`. This indicates the
     /// parent `DefId` as well as some idea of what kind of data the
     /// `DefId` refers to.
@@ -516,10 +519,6 @@ impl CrateStore for cstore::CStore {
         result
     }
 
-    fn postorder_cnums_untracked(&self) -> Vec<CrateNum> {
-        self.do_postorder_cnums_untracked()
-    }
-
     fn encode_metadata(&self, tcx: TyCtxt<'_>) -> EncodedMetadata {
         encoder::encode_metadata(tcx)
     }
@@ -529,11 +528,7 @@ impl CrateStore for cstore::CStore {
         rmeta::METADATA_HEADER
     }
 
-    fn injected_panic_runtime(&self) -> Option<CrateNum> {
-        self.injected_panic_runtime
-    }
-
     fn allocator_kind(&self) -> Option<AllocatorKind> {
-        self.allocator_kind
+        self.allocator_kind()
     }
 }
diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs
index 8074bde6123..3a318ddc1e1 100644
--- a/src/librustc_metadata/rmeta/encoder.rs
+++ b/src/librustc_metadata/rmeta/encoder.rs
@@ -496,7 +496,6 @@ impl<'tcx> EncodeContext<'tcx> {
 
         let attrs = tcx.hir().krate_attrs();
         let has_default_lib_allocator = attr::contains_name(&attrs, sym::default_lib_allocator);
-        let has_global_allocator = *tcx.sess.has_global_allocator.get();
 
         let root = self.lazy(CrateRoot {
             name: tcx.crate_name(LOCAL_CRATE),
@@ -506,7 +505,7 @@ impl<'tcx> EncodeContext<'tcx> {
             disambiguator: tcx.sess.local_crate_disambiguator(),
             panic_strategy: tcx.sess.panic_strategy(),
             edition: tcx.sess.edition(),
-            has_global_allocator: has_global_allocator,
+            has_global_allocator: tcx.has_global_allocator(LOCAL_CRATE),
             has_panic_handler: tcx.has_panic_handler(LOCAL_CRATE),
             has_default_lib_allocator: has_default_lib_allocator,
             plugin_registrar_fn: tcx.plugin_registrar_fn(LOCAL_CRATE).map(|id| id.index),
diff --git a/src/librustc_metadata/rmeta/mod.rs b/src/librustc_metadata/rmeta/mod.rs
index 1bca2836a3a..4ea562fced3 100644
--- a/src/librustc_metadata/rmeta/mod.rs
+++ b/src/librustc_metadata/rmeta/mod.rs
@@ -173,16 +173,16 @@ macro_rules! Lazy {
 
 #[derive(RustcEncodable, RustcDecodable)]
 crate struct CrateRoot<'tcx> {
-    pub name: Symbol,
-    pub triple: TargetTriple,
+    name: Symbol,
+    triple: TargetTriple,
     extra_filename: String,
-    pub hash: Svh,
-    pub disambiguator: CrateDisambiguator,
-    pub panic_strategy: PanicStrategy,
+    hash: Svh,
+    disambiguator: CrateDisambiguator,
+    panic_strategy: PanicStrategy,
     edition: Edition,
-    pub has_global_allocator: bool,
+    has_global_allocator: bool,
     has_panic_handler: bool,
-    pub has_default_lib_allocator: bool,
+    has_default_lib_allocator: bool,
     plugin_registrar_fn: Option<DefIndex>,
     proc_macro_decls_static: Option<DefIndex>,
     proc_macro_stability: Option<attr::Stability>,
@@ -207,12 +207,12 @@ crate struct CrateRoot<'tcx> {
     proc_macro_data: Option<Lazy<[DefIndex]>>,
 
     compiler_builtins: bool,
-    pub needs_allocator: bool,
-    pub needs_panic_runtime: bool,
+    needs_allocator: bool,
+    needs_panic_runtime: bool,
     no_builtins: bool,
-    pub panic_runtime: bool,
-    pub profiler_runtime: bool,
-    pub sanitizer_runtime: bool,
+    panic_runtime: bool,
+    profiler_runtime: bool,
+    sanitizer_runtime: bool,
     symbol_mangling_version: SymbolManglingVersion,
 }
 
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 6694ddc53d4..eb7265cb9cc 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -19,7 +19,7 @@ use rustc::hir::def::{self, *};
 use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, DefId};
 use rustc::ty;
 use rustc::middle::cstore::CrateStore;
-use rustc_metadata::cstore::LoadedMacro;
+use rustc_metadata::creader::LoadedMacro;
 
 use std::cell::Cell;
 use std::ptr;
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index ab2aeb2fa82..be36e02f5b5 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -32,8 +32,7 @@ use rustc::ty::{self, DefIdTree, ResolverOutputs};
 use rustc::util::nodemap::{NodeMap, NodeSet, FxHashMap, FxHashSet, DefIdMap};
 use rustc::span_bug;
 
-use rustc_metadata::creader::CrateLoader;
-use rustc_metadata::cstore::CStore;
+use rustc_metadata::creader::{CrateLoader, CStore};
 
 use syntax::{struct_span_err, unwrap_or};
 use syntax::ast::{self, Name, NodeId, Ident, FloatTy, IntTy, UintTy};
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index b3b3750320a..4b5fc7c2a1e 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -10,7 +10,7 @@ use syntax_pos::Span;
 use rustc::hir;
 use rustc::hir::def::{Res, DefKind, CtorKind};
 use rustc::hir::def_id::DefId;
-use rustc_metadata::cstore::LoadedMacro;
+use rustc_metadata::creader::LoadedMacro;
 use rustc::ty;
 use rustc::util::nodemap::FxHashSet;
 
diff --git a/src/libsyntax/expand/allocator.rs b/src/libsyntax/expand/allocator.rs
index 20487b9af03..cc3eeed04a6 100644
--- a/src/libsyntax/expand/allocator.rs
+++ b/src/libsyntax/expand/allocator.rs
@@ -5,16 +5,14 @@ use syntax_pos::Span;
 #[derive(Clone, Copy)]
 pub enum AllocatorKind {
     Global,
-    DefaultLib,
-    DefaultExe,
+    Default,
 }
 
 impl AllocatorKind {
     pub fn fn_name(&self, base: &str) -> String {
         match *self {
             AllocatorKind::Global => format!("__rg_{}", base),
-            AllocatorKind::DefaultLib => format!("__rdl_{}", base),
-            AllocatorKind::DefaultExe => format!("__rde_{}", base),
+            AllocatorKind::Default => format!("__rdl_{}", base),
         }
     }
 }
diff --git a/src/test/ui/allocator/two-allocators3.stderr b/src/test/ui/allocator/two-allocators3.stderr
index ecffb192e2a..a3079113d01 100644
--- a/src/test/ui/allocator/two-allocators3.stderr
+++ b/src/test/ui/allocator/two-allocators3.stderr
@@ -1,4 +1,4 @@
-error: the `#[global_allocator]` in system_allocator conflicts with this global allocator in: system_allocator2
+error: the `#[global_allocator]` in system_allocator conflicts with global allocator in: system_allocator2
 
 error: aborting due to previous error