about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/hir/lowering.rs12
-rw-r--r--src/librustc/middle/cstore.rs8
-rw-r--r--src/librustc/ty/context.rs31
-rw-r--r--src/librustc/ty/mod.rs6
-rw-r--r--src/librustc_codegen_llvm/lib.rs4
-rw-r--r--src/librustc_codegen_utils/codegen_backend.rs4
-rw-r--r--src/librustc_driver/lib.rs8
-rw-r--r--src/librustc_interface/interface.rs8
-rw-r--r--src/librustc_interface/passes.rs137
-rw-r--r--src/librustc_interface/queries.rs27
-rw-r--r--src/librustc_metadata/creader.rs217
-rw-r--r--src/librustc_metadata/cstore.rs47
-rw-r--r--src/librustc_metadata/cstore_impl.rs17
-rw-r--r--src/librustc_metadata/locator.rs86
-rw-r--r--src/librustc_plugin/load.rs21
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs19
-rw-r--r--src/librustc_resolve/lib.rs86
-rw-r--r--src/librustc_resolve/resolve_imports.rs2
-rw-r--r--src/librustdoc/clean/inline.rs4
-rw-r--r--src/librustdoc/core.rs7
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs4
-rw-r--r--src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs6
22 files changed, 346 insertions, 415 deletions
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 7971c33426b..002e6874466 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -83,8 +83,6 @@ pub struct LoweringContext<'a> {
     /// Used to assign IDs to HIR nodes that do not directly correspond to AST nodes.
     sess: &'a Session,
 
-    cstore: &'a dyn CrateStore,
-
     resolver: &'a mut dyn Resolver,
 
     /// HACK(Centril): there is a cyclic dependency between the parser and lowering
@@ -160,6 +158,8 @@ pub struct LoweringContext<'a> {
 }
 
 pub trait Resolver {
+    fn cstore(&self) -> &dyn CrateStore;
+
     /// Obtains resolution for a `NodeId` with a single resolution.
     fn get_partial_res(&mut self, id: NodeId) -> Option<PartialRes>;
 
@@ -240,7 +240,6 @@ impl<'a> ImplTraitContext<'a> {
 
 pub fn lower_crate(
     sess: &Session,
-    cstore: &dyn CrateStore,
     dep_graph: &DepGraph,
     krate: &Crate,
     resolver: &mut dyn Resolver,
@@ -256,7 +255,6 @@ pub fn lower_crate(
     LoweringContext {
         crate_root: sess.parse_sess.injected_crate_name.try_get().copied(),
         sess,
-        cstore,
         resolver,
         nt_to_tokenstream,
         items: BTreeMap::new(),
@@ -980,7 +978,7 @@ impl<'a> LoweringContext<'a> {
         if id.is_local() {
             self.resolver.definitions().def_key(id.index)
         } else {
-            self.cstore.def_key(id)
+            self.resolver.cstore().def_key(id)
         }
     }
 
@@ -1727,8 +1725,8 @@ impl<'a> LoweringContext<'a> {
                             return n;
                         }
                         assert!(!def_id.is_local());
-                        let item_generics =
-                            self.cstore.item_generics_cloned_untracked(def_id, self.sess);
+                        let item_generics = self.resolver.cstore()
+                            .item_generics_cloned_untracked(def_id, self.sess);
                         let n = item_generics.own_counts().lifetimes;
                         self.type_def_lifetime_params.insert(def_id, n);
                         n
diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs
index ec1e32988a6..d5558db2397 100644
--- a/src/librustc/middle/cstore.rs
+++ b/src/librustc/middle/cstore.rs
@@ -16,7 +16,7 @@ use syntax::ast;
 use syntax::symbol::Symbol;
 use syntax_pos::Span;
 use rustc_target::spec::Target;
-use rustc_data_structures::sync::{self, MetadataRef, Lrc};
+use rustc_data_structures::sync::{self, MetadataRef};
 use rustc_macros::HashStable;
 
 pub use self::NativeLibraryKind::*;
@@ -191,6 +191,8 @@ pub trait MetadataLoader {
                           -> Result<MetadataRef, String>;
 }
 
+pub type MetadataLoaderDyn = dyn MetadataLoader + Sync;
+
 /// A store of Rust crates, through which their metadata can be accessed.
 ///
 /// Note that this trait should probably not be expanding today. All new
@@ -201,13 +203,13 @@ pub trait MetadataLoader {
 /// (it'd break incremental compilation) and should only be called pre-HIR (e.g.
 /// during resolve)
 pub trait CrateStore {
-    fn crate_data_as_rc_any(&self, krate: CrateNum) -> Lrc<dyn Any>;
+    fn crate_data_as_any(&self, cnum: CrateNum) -> &dyn Any;
 
     // resolve
     fn def_key(&self, def: DefId) -> DefKey;
     fn def_path(&self, def: DefId) -> hir_map::DefPath;
     fn def_path_hash(&self, def: DefId) -> hir_map::DefPathHash;
-    fn def_path_table(&self, cnum: CrateNum) -> Lrc<DefPathTable>;
+    fn def_path_table(&self, cnum: CrateNum) -> &DefPathTable;
 
     // "queries" used in resolve that aren't tracked for incremental compilation
     fn crate_name_untracked(&self, cnum: CrateNum) -> Symbol;
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index d5a93e02905..f99298281fe 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -1027,7 +1027,7 @@ pub struct GlobalCtxt<'tcx> {
 
     interners: CtxtInterners<'tcx>,
 
-    cstore: &'tcx CrateStoreDyn,
+    cstore: Box<CrateStoreDyn>,
 
     pub sess: &'tcx Session,
 
@@ -1195,11 +1195,10 @@ impl<'tcx> TyCtxt<'tcx> {
     pub fn create_global_ctxt(
         s: &'tcx Session,
         lint_store: Lrc<lint::LintStore>,
-        cstore: &'tcx CrateStoreDyn,
         local_providers: ty::query::Providers<'tcx>,
         extern_providers: ty::query::Providers<'tcx>,
         arenas: &'tcx AllArenas,
-        resolutions: ty::Resolutions,
+        resolutions: ty::ResolverOutputs,
         hir: hir_map::Map<'tcx>,
         on_disk_query_result_cache: query::OnDiskCache<'tcx>,
         crate_name: &str,
@@ -1213,34 +1212,28 @@ impl<'tcx> TyCtxt<'tcx> {
         let common_lifetimes = CommonLifetimes::new(&interners);
         let common_consts = CommonConsts::new(&interners, &common_types);
         let dep_graph = hir.dep_graph.clone();
-        let max_cnum = cstore.crates_untracked().iter().map(|c| c.as_usize()).max().unwrap_or(0);
+        let cstore = resolutions.cstore;
+        let crates = cstore.crates_untracked();
+        let max_cnum = 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, Lrc<_>)> = cstore
-                .crates_untracked()
+            let def_path_tables = crates
                 .iter()
                 .map(|&cnum| (cnum, cstore.def_path_table(cnum)))
-                .collect();
-
-            let def_path_tables = || {
-                upstream_def_path_tables
-                    .iter()
-                    .map(|&(cnum, ref rc)| (cnum, &**rc))
-                    .chain(iter::once((LOCAL_CRATE, hir.definitions().def_path_table())))
-            };
+                .chain(iter::once((LOCAL_CRATE, hir.definitions().def_path_table())));
 
             // Precompute the capacity of the hashmap so we don't have to
             // re-allocate when populating it.
-            let capacity = def_path_tables().map(|(_, t)| t.size()).sum::<usize>();
+            let capacity = def_path_tables.clone().map(|(_, t)| t.size()).sum::<usize>();
 
             let mut map: FxHashMap<_, _> = FxHashMap::with_capacity_and_hasher(
                 capacity,
                 ::std::default::Default::default()
             );
 
-            for (cnum, def_path_table) in def_path_tables() {
+            for (cnum, def_path_table) in def_path_tables {
                 def_path_table.add_def_path_hashes_to(cnum, &mut map);
             }
 
@@ -1417,8 +1410,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_rc_any(self, cnum: CrateNum) -> Lrc<dyn Any> {
-        self.cstore.crate_data_as_rc_any(cnum)
+    pub fn crate_data_as_any(self, cnum: CrateNum) -> &'tcx dyn Any {
+        self.cstore.crate_data_as_any(cnum)
     }
 
     #[inline(always)]
@@ -1428,7 +1421,7 @@ impl<'tcx> TyCtxt<'tcx> {
         StableHashingContext::new(self.sess,
                                   krate,
                                   self.hir().definitions(),
-                                  self.cstore)
+                                  &*self.cstore)
     }
 
     // This method makes sure that we have a DepNode and a Fingerprint for
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index feede00fea1..90450494a14 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -15,6 +15,7 @@ use rustc_macros::HashStable;
 use crate::ich::Fingerprint;
 use crate::ich::StableHashingContext;
 use crate::infer::canonical::Canonical;
+use crate::middle::cstore::CrateStoreDyn;
 use crate::middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem};
 use crate::middle::resolve_lifetime::ObjectLifetimeDefault;
 use crate::mir::Body;
@@ -119,8 +120,9 @@ mod sty;
 
 // Data types
 
-#[derive(Clone)]
-pub struct Resolutions {
+pub struct ResolverOutputs {
+    pub definitions: hir_map::Definitions,
+    pub cstore: Box<CrateStoreDyn>,
     pub extern_crate_map: NodeMap<CrateNum>,
     pub trait_map: TraitMap,
     pub maybe_unused_trait_imports: NodeSet,
diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs
index 8c1797cfb7d..e09b600afd4 100644
--- a/src/librustc_codegen_llvm/lib.rs
+++ b/src/librustc_codegen_llvm/lib.rs
@@ -56,7 +56,7 @@ use std::sync::Arc;
 use std::ffi::CStr;
 
 use rustc::dep_graph::DepGraph;
-use rustc::middle::cstore::{EncodedMetadata, MetadataLoader};
+use rustc::middle::cstore::{EncodedMetadata, MetadataLoaderDyn};
 use rustc::session::Session;
 use rustc::session::config::{OutputFilenames, OutputType, PrintRequest, OptLevel};
 use rustc::ty::{self, TyCtxt};
@@ -260,7 +260,7 @@ impl CodegenBackend for LlvmCodegenBackend {
         target_features(sess)
     }
 
-    fn metadata_loader(&self) -> Box<dyn MetadataLoader + Sync> {
+    fn metadata_loader(&self) -> Box<MetadataLoaderDyn> {
         box metadata::LlvmMetadataLoader
     }
 
diff --git a/src/librustc_codegen_utils/codegen_backend.rs b/src/librustc_codegen_utils/codegen_backend.rs
index 1077c1f4263..0e2c3731eae 100644
--- a/src/librustc_codegen_utils/codegen_backend.rs
+++ b/src/librustc_codegen_utils/codegen_backend.rs
@@ -14,7 +14,7 @@ use rustc::util::common::ErrorReported;
 use rustc::session::config::{OutputFilenames, PrintRequest};
 use rustc::ty::TyCtxt;
 use rustc::ty::query::Providers;
-use rustc::middle::cstore::{EncodedMetadata, MetadataLoader};
+use rustc::middle::cstore::{EncodedMetadata, MetadataLoaderDyn};
 use rustc::dep_graph::DepGraph;
 
 pub use rustc_data_structures::sync::MetadataRef;
@@ -26,7 +26,7 @@ pub trait CodegenBackend {
     fn print_passes(&self) {}
     fn print_version(&self) {}
 
-    fn metadata_loader(&self) -> Box<dyn MetadataLoader + Sync>;
+    fn metadata_loader(&self) -> Box<MetadataLoaderDyn>;
     fn provide(&self, _providers: &mut Providers<'_>);
     fn provide_extern(&self, _providers: &mut Providers<'_>);
     fn codegen_crate<'tcx>(
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index 5d9dec14c6c..15adf7e4add 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -36,11 +36,11 @@ use rustc::session::config::nightly_options;
 use rustc::session::{early_error, early_warn};
 use rustc::lint::Lint;
 use rustc::lint;
+use rustc::middle::cstore::MetadataLoader;
 use rustc::hir::def_id::LOCAL_CRATE;
 use rustc::ty::TyCtxt;
 use rustc::util::common::{set_time_depth, time, print_time_passes_entry, ErrorReported};
 use rustc_metadata::locator;
-use rustc_metadata::cstore::CStore;
 use rustc_codegen_utils::codegen_backend::CodegenBackend;
 use rustc_interface::interface;
 use rustc_interface::util::get_codegen_sysroot;
@@ -277,7 +277,7 @@ pub fn run_compiler(
             compiler.output_file(),
         ).and_then(|| RustcDefaultCalls::list_metadata(
             sess,
-            compiler.cstore(),
+            &*compiler.codegen_backend().metadata_loader(),
             &matches,
             compiler.input()
         ));
@@ -614,7 +614,7 @@ fn show_content_with_pager(content: &String) {
 
 impl RustcDefaultCalls {
     pub fn list_metadata(sess: &Session,
-                         cstore: &CStore,
+                         metadata_loader: &dyn MetadataLoader,
                          matches: &getopts::Matches,
                          input: &Input)
                          -> Compilation {
@@ -626,7 +626,7 @@ impl RustcDefaultCalls {
                     let mut v = Vec::new();
                     locator::list_file_metadata(&sess.target.target,
                                                 path,
-                                                cstore,
+                                                metadata_loader,
                                                 &mut v)
                             .unwrap();
                     println!("{}", String::from_utf8(v).unwrap());
diff --git a/src/librustc_interface/interface.rs b/src/librustc_interface/interface.rs
index 24ea0fc8bf6..e014e4ed0fd 100644
--- a/src/librustc_interface/interface.rs
+++ b/src/librustc_interface/interface.rs
@@ -11,7 +11,6 @@ use rustc_codegen_utils::codegen_backend::CodegenBackend;
 use rustc_data_structures::OnDrop;
 use rustc_data_structures::sync::Lrc;
 use rustc_data_structures::fx::{FxHashSet, FxHashMap};
-use rustc_metadata::cstore::CStore;
 use std::path::PathBuf;
 use std::result;
 use std::sync::{Arc, Mutex};
@@ -37,7 +36,6 @@ pub struct Compiler {
     pub(crate) output_dir: Option<PathBuf>,
     pub(crate) output_file: Option<PathBuf>,
     pub(crate) queries: Queries,
-    pub(crate) cstore: Lrc<CStore>,
     pub(crate) crate_name: Option<String>,
     pub(crate) register_lints: Option<Box<dyn Fn(&Session, &mut lint::LintStore) + Send + Sync>>,
 }
@@ -49,9 +47,6 @@ impl Compiler {
     pub fn codegen_backend(&self) -> &Lrc<Box<dyn CodegenBackend>> {
         &self.codegen_backend
     }
-    pub fn cstore(&self) -> &Lrc<CStore> {
-        &self.cstore
-    }
     pub fn source_map(&self) -> &Lrc<SourceMap> {
         &self.source_map
     }
@@ -160,13 +155,10 @@ where
         config.lint_caps,
     );
 
-    let cstore = Lrc::new(CStore::new(codegen_backend.metadata_loader()));
-
     let compiler = Compiler {
         sess,
         codegen_backend,
         source_map,
-        cstore,
         input: config.input,
         input_path: config.input_path,
         output_dir: config.output_dir,
diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs
index 2044b73db8a..58936172c5b 100644
--- a/src/librustc_interface/passes.rs
+++ b/src/librustc_interface/passes.rs
@@ -9,8 +9,8 @@ use rustc::hir::lowering::lower_crate;
 use rustc::hir::def_id::{CrateNum, LOCAL_CRATE};
 use rustc::lint;
 use rustc::middle::{self, reachable, resolve_lifetime, stability};
-use rustc::middle::cstore::CrateStore;
-use rustc::ty::{self, AllArenas, Resolutions, TyCtxt, GlobalCtxt};
+use rustc::middle::cstore::{CrateStore, MetadataLoader, MetadataLoaderDyn};
+use rustc::ty::{self, AllArenas, ResolverOutputs, TyCtxt, GlobalCtxt};
 use rustc::ty::steal::Steal;
 use rustc::traits;
 use rustc::util::common::{time, ErrorReported};
@@ -23,8 +23,7 @@ use rustc_codegen_utils::link::filename_for_metadata;
 use rustc_data_structures::{box_region_allow_access, declare_box_region_type, parallel};
 use rustc_data_structures::sync::{Lrc, ParallelIterator, par_iter};
 use rustc_incremental;
-use rustc_metadata::creader::CrateLoader;
-use rustc_metadata::cstore::{self, CStore};
+use rustc_metadata::cstore;
 use rustc_mir as mir;
 use rustc_passes::{self, ast_validation, hir_stats, layout_test};
 use rustc_plugin as plugin;
@@ -46,12 +45,10 @@ use syntax_ext;
 use rustc_serialize::json;
 use tempfile::Builder as TempFileBuilder;
 
+use std::{env, fs, iter, mem};
 use std::any::Any;
-use std::env;
 use std::ffi::OsString;
-use std::fs;
 use std::io::{self, Write};
-use std::iter;
 use std::path::PathBuf;
 use std::cell::RefCell;
 use std::rc::Rc;
@@ -105,7 +102,7 @@ fn count_nodes(krate: &ast::Crate) -> usize {
 declare_box_region_type!(
     pub BoxedResolver,
     for(),
-    (&mut Resolver<'_>) -> (Result<ast::Crate>, ExpansionResult)
+    (&mut Resolver<'_>) -> (Result<ast::Crate>, ResolverOutputs)
 );
 
 /// Runs the "early phases" of the compiler: initial `cfg` processing,
@@ -118,7 +115,7 @@ declare_box_region_type!(
 pub fn configure_and_expand(
     sess: Lrc<Session>,
     lint_store: Lrc<lint::LintStore>,
-    cstore: Lrc<CStore>,
+    metadata_loader: Box<MetadataLoaderDyn>,
     krate: ast::Crate,
     crate_name: &str,
     plugin_info: PluginInfo,
@@ -131,16 +128,14 @@ pub fn configure_and_expand(
     let crate_name = crate_name.to_string();
     let (result, resolver) = BoxedResolver::new(static move || {
         let sess = &*sess;
-        let crate_loader = CrateLoader::new(sess, &*cstore, &crate_name);
         let resolver_arenas = Resolver::arenas();
         let res = configure_and_expand_inner(
             sess,
             &lint_store,
-            &*cstore,
             krate,
             &crate_name,
             &resolver_arenas,
-            &crate_loader,
+            &*metadata_loader,
             plugin_info,
         );
         let mut resolver = match res {
@@ -154,68 +149,16 @@ pub fn configure_and_expand(
             }
         };
         box_region_allow_access!(for(), (&mut Resolver<'_>), (&mut resolver));
-        ExpansionResult::from_owned_resolver(resolver)
+        resolver.into_outputs()
     });
     result.map(|k| (k, resolver))
 }
 
-pub struct ExpansionResult {
-    pub defs: Steal<hir::map::Definitions>,
-    pub resolutions: Steal<Resolutions>,
-}
-
-impl ExpansionResult {
-    fn from_owned_resolver(
-        resolver: Resolver<'_>,
-    ) -> Self {
-        ExpansionResult {
-            defs: Steal::new(resolver.definitions),
-            resolutions: Steal::new(Resolutions {
-                extern_crate_map: resolver.extern_crate_map,
-                export_map: resolver.export_map,
-                trait_map: resolver.trait_map,
-                glob_map: resolver.glob_map,
-                maybe_unused_trait_imports: resolver.maybe_unused_trait_imports,
-                maybe_unused_extern_crates: resolver.maybe_unused_extern_crates,
-                extern_prelude: resolver.extern_prelude.iter().map(|(ident, entry)| {
-                    (ident.name, entry.introduced_by_item)
-                }).collect(),
-            }),
-        }
-    }
-
-    pub fn from_resolver_ref(
-        resolver: &Resolver<'_>,
-    ) -> Self {
-        ExpansionResult {
-            defs: Steal::new(resolver.definitions.clone()),
-            resolutions: Steal::new(Resolutions {
-                extern_crate_map: resolver.extern_crate_map.clone(),
-                export_map: resolver.export_map.clone(),
-                trait_map: resolver.trait_map.clone(),
-                glob_map: resolver.glob_map.clone(),
-                maybe_unused_trait_imports: resolver.maybe_unused_trait_imports.clone(),
-                maybe_unused_extern_crates: resolver.maybe_unused_extern_crates.clone(),
-                extern_prelude: resolver.extern_prelude.iter().map(|(ident, entry)| {
-                    (ident.name, entry.introduced_by_item)
-                }).collect(),
-            }),
-        }
-    }
-}
-
 impl BoxedResolver {
-    pub fn to_expansion_result(
-        resolver: Rc<RefCell<BoxedResolver>>,
-    ) -> ExpansionResult {
+    pub fn to_resolver_outputs(resolver: Rc<RefCell<BoxedResolver>>) -> ResolverOutputs {
         match Rc::try_unwrap(resolver) {
             Ok(resolver) => resolver.into_inner().complete(),
-            Err(resolver) => {
-                let resolver = &*resolver;
-                resolver.borrow_mut().access(|resolver| {
-                    ExpansionResult::from_resolver_ref(resolver)
-                })
-            }
+            Err(resolver) => resolver.borrow_mut().access(|resolver| resolver.clone_outputs()),
         }
     }
 }
@@ -226,7 +169,7 @@ pub struct PluginInfo {
 
 pub fn register_plugins<'a>(
     sess: &'a Session,
-    cstore: &'a CStore,
+    metadata_loader: &'a dyn MetadataLoader,
     register_lints: impl Fn(&Session, &mut lint::LintStore),
     mut krate: ast::Crate,
     crate_name: &str,
@@ -274,9 +217,8 @@ pub fn register_plugins<'a>(
     let registrars = time(sess, "plugin loading", || {
         plugin::load::load_plugins(
             sess,
-            &cstore,
+            metadata_loader,
             &krate,
-            crate_name,
             Some(sess.opts.debugging_opts.extra_plugins.clone()),
         )
     });
@@ -313,11 +255,10 @@ pub fn register_plugins<'a>(
 fn configure_and_expand_inner<'a>(
     sess: &'a Session,
     lint_store: &'a lint::LintStore,
-    cstore: &'a CStore,
     mut krate: ast::Crate,
     crate_name: &str,
     resolver_arenas: &'a ResolverArenas<'a>,
-    crate_loader: &'a CrateLoader<'a>,
+    metadata_loader: &'a MetadataLoaderDyn,
     plugin_info: PluginInfo,
 ) -> Result<(ast::Crate, Resolver<'a>)> {
     time(sess, "pre-AST-expansion lint checks", || {
@@ -331,10 +272,9 @@ fn configure_and_expand_inner<'a>(
 
     let mut resolver = Resolver::new(
         sess,
-        cstore,
         &krate,
         crate_name,
-        crate_loader,
+        metadata_loader,
         &resolver_arenas,
     );
     syntax_ext::register_builtin_macros(&mut resolver, sess.edition());
@@ -534,7 +474,6 @@ fn configure_and_expand_inner<'a>(
 pub fn lower_to_hir(
     sess: &Session,
     lint_store: &lint::LintStore,
-    cstore: &CStore,
     resolver: &mut Resolver<'_>,
     dep_graph: &DepGraph,
     krate: &ast::Crate,
@@ -542,7 +481,7 @@ pub fn lower_to_hir(
     // Lower AST to HIR.
     let hir_forest = time(sess, "lowering AST -> HIR", || {
         let nt_to_tokenstream = syntax::parse::nt_to_tokenstream;
-        let hir_crate = lower_crate(sess, cstore, &dep_graph, &krate, resolver, nt_to_tokenstream);
+        let hir_crate = lower_crate(sess, &dep_graph, &krate, resolver, nt_to_tokenstream);
 
         if sess.opts.debugging_opts.hir_stats {
             hir_stats::print_hir_stats(&hir_crate);
@@ -648,8 +587,12 @@ fn escape_dep_filename(filename: &FileName) -> String {
     filename.to_string().replace(" ", "\\ ")
 }
 
-fn write_out_deps(compiler: &Compiler, outputs: &OutputFilenames, out_filenames: &[PathBuf]) {
-    let sess = &compiler.sess;
+fn write_out_deps(
+    sess: &Session,
+    boxed_resolver: &Steal<Rc<RefCell<BoxedResolver>>>,
+    outputs: &OutputFilenames,
+    out_filenames: &[PathBuf],
+) {
     // Write out dependency rules to the dep-info file if requested
     if !sess.opts.output_types.contains_key(&OutputType::DepInfo) {
         return;
@@ -668,18 +611,20 @@ fn write_out_deps(compiler: &Compiler, outputs: &OutputFilenames, out_filenames:
             .collect();
 
         if sess.binary_dep_depinfo() {
-            for cnum in compiler.cstore.crates_untracked() {
-                let source = compiler.cstore.crate_source_untracked(cnum);
-                if let Some((path, _)) = source.dylib {
-                    files.push(escape_dep_filename(&FileName::Real(path)));
+            boxed_resolver.borrow().borrow_mut().access(|resolver| {
+                for cnum in resolver.cstore().crates_untracked() {
+                    let source = resolver.cstore().crate_source_untracked(cnum);
+                    if let Some((path, _)) = source.dylib {
+                        files.push(escape_dep_filename(&FileName::Real(path)));
+                    }
+                    if let Some((path, _)) = source.rlib {
+                        files.push(escape_dep_filename(&FileName::Real(path)));
+                    }
+                    if let Some((path, _)) = source.rmeta {
+                        files.push(escape_dep_filename(&FileName::Real(path)));
+                    }
                 }
-                if let Some((path, _)) = source.rlib {
-                    files.push(escape_dep_filename(&FileName::Real(path)));
-                }
-                if let Some((path, _)) = source.rmeta {
-                    files.push(escape_dep_filename(&FileName::Real(path)));
-                }
-            }
+            });
         }
 
         let mut file = fs::File::create(&deps_filename)?;
@@ -717,6 +662,7 @@ pub fn prepare_outputs(
     sess: &Session,
     compiler: &Compiler,
     krate: &ast::Crate,
+    boxed_resolver: &Steal<Rc<RefCell<BoxedResolver>>>,
     crate_name: &str
 ) -> Result<OutputFilenames> {
     // FIXME: rustdoc passes &[] instead of &krate.attrs here
@@ -758,7 +704,7 @@ pub fn prepare_outputs(
         }
     }
 
-    write_out_deps(compiler, &outputs, &output_paths);
+    write_out_deps(sess, boxed_resolver, &outputs, &output_paths);
 
     let only_dep_info = sess.opts.output_types.contains_key(&OutputType::DepInfo)
         && sess.opts.output_types.len() == 1;
@@ -823,26 +769,24 @@ pub fn create_global_ctxt(
     compiler: &Compiler,
     lint_store: Lrc<lint::LintStore>,
     mut hir_forest: hir::map::Forest,
-    defs: hir::map::Definitions,
-    resolutions: Resolutions,
+    mut resolver_outputs: ResolverOutputs,
     outputs: OutputFilenames,
     crate_name: &str,
 ) -> BoxedGlobalCtxt {
     let sess = compiler.session().clone();
-    let cstore = compiler.cstore.clone();
     let codegen_backend = compiler.codegen_backend().clone();
     let crate_name = crate_name.to_string();
+    let defs = mem::take(&mut resolver_outputs.definitions);
 
     let ((), result) = BoxedGlobalCtxt::new(static move || {
         let sess = &*sess;
-        let cstore = &*cstore;
 
         let global_ctxt: Option<GlobalCtxt<'_>>;
         let arenas = AllArenas::new();
 
         // Construct the HIR map.
         let hir_map = time(sess, "indexing HIR", || {
-            hir::map::map_crate(sess, cstore, &mut hir_forest, &defs)
+            hir::map::map_crate(sess, &*resolver_outputs.cstore, &mut hir_forest, &defs)
         });
 
         let query_result_on_disk_cache = time(sess, "load query result cache", || {
@@ -860,11 +804,10 @@ pub fn create_global_ctxt(
         let gcx = TyCtxt::create_global_ctxt(
             sess,
             lint_store,
-            cstore,
             local_providers,
             extern_providers,
             &arenas,
-            resolutions,
+            resolver_outputs,
             hir_map,
             query_result_on_disk_cache,
             &crate_name,
diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs
index 84648ca8326..ea51e63725e 100644
--- a/src/librustc_interface/queries.rs
+++ b/src/librustc_interface/queries.rs
@@ -1,5 +1,5 @@
 use crate::interface::{Compiler, Result};
-use crate::passes::{self, BoxedResolver, ExpansionResult, BoxedGlobalCtxt, PluginInfo};
+use crate::passes::{self, BoxedResolver, BoxedGlobalCtxt, PluginInfo};
 
 use rustc_incremental::DepGraphFuture;
 use rustc_data_structures::sync::Lrc;
@@ -11,6 +11,7 @@ use rustc::session::Session;
 use rustc::lint::LintStore;
 use rustc::hir::def_id::LOCAL_CRATE;
 use rustc::ty::steal::Steal;
+use rustc::ty::ResolverOutputs;
 use rustc::dep_graph::DepGraph;
 use std::cell::{Ref, RefMut, RefCell};
 use std::rc::Rc;
@@ -81,7 +82,7 @@ pub(crate) struct Queries {
     register_plugins: Query<(ast::Crate, PluginInfo, Lrc<LintStore>)>,
     expansion: Query<(ast::Crate, Steal<Rc<RefCell<BoxedResolver>>>, Lrc<LintStore>)>,
     dep_graph: Query<DepGraph>,
-    lower_to_hir: Query<(Steal<hir::map::Forest>, ExpansionResult)>,
+    lower_to_hir: Query<(Steal<hir::map::Forest>, Steal<ResolverOutputs>)>,
     prepare_outputs: Query<OutputFilenames>,
     global_ctxt: Query<BoxedGlobalCtxt>,
     ongoing_codegen: Query<Box<dyn Any>>,
@@ -118,7 +119,7 @@ impl Compiler {
             let empty: &(dyn Fn(&Session, &mut lint::LintStore) + Sync + Send) = &|_, _| {};
             let result = passes::register_plugins(
                 self.session(),
-                self.cstore(),
+                &*self.codegen_backend().metadata_loader(),
                 self.register_lints
                     .as_ref()
                     .map(|p| &**p)
@@ -164,7 +165,7 @@ impl Compiler {
             passes::configure_and_expand(
                 self.sess.clone(),
                 lint_store.clone(),
-                self.cstore().clone(),
+                self.codegen_backend().metadata_loader(),
                 krate,
                 &crate_name,
                 plugin_info,
@@ -191,7 +192,9 @@ impl Compiler {
         })
     }
 
-    pub fn lower_to_hir(&self) -> Result<&Query<(Steal<hir::map::Forest>, ExpansionResult)>> {
+    pub fn lower_to_hir(
+        &self,
+    ) -> Result<&Query<(Steal<hir::map::Forest>, Steal<ResolverOutputs>)>> {
         self.queries.lower_to_hir.compute(|| {
             let expansion_result = self.expansion()?;
             let peeked = expansion_result.peek();
@@ -202,23 +205,22 @@ impl Compiler {
                 passes::lower_to_hir(
                     self.session(),
                     lint_store,
-                    self.cstore(),
                     resolver,
                     &*self.dep_graph()?.peek(),
                     &krate
                 )
             })?);
-            Ok((hir, BoxedResolver::to_expansion_result(resolver)))
+            Ok((hir, Steal::new(BoxedResolver::to_resolver_outputs(resolver))))
         })
     }
 
     pub fn prepare_outputs(&self) -> Result<&Query<OutputFilenames>> {
         self.queries.prepare_outputs.compute(|| {
-            let krate = self.expansion()?;
-            let krate = krate.peek();
+            let expansion_result = self.expansion()?;
+            let (krate, boxed_resolver, _) = &*expansion_result.peek();
             let crate_name = self.crate_name()?;
             let crate_name = crate_name.peek();
-            passes::prepare_outputs(self.session(), self, &krate.0, &*crate_name)
+            passes::prepare_outputs(self.session(), self, &krate, &boxed_resolver, &crate_name)
         })
     }
 
@@ -229,13 +231,12 @@ impl Compiler {
             let lint_store = self.expansion()?.peek().2.clone();
             let hir = self.lower_to_hir()?;
             let hir = hir.peek();
-            let (ref hir_forest, ref expansion) = *hir;
+            let (hir_forest, resolver_outputs) = &*hir;
             Ok(passes::create_global_ctxt(
                 self,
                 lint_store,
                 hir_forest.steal(),
-                expansion.defs.steal(),
-                expansion.resolutions.steal(),
+                resolver_outputs.steal(),
                 outputs,
                 &crate_name))
         })
diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs
index 7412e8a2cb9..f0a68058de8 100644
--- a/src/librustc_metadata/creader.rs
+++ b/src/librustc_metadata/creader.rs
@@ -3,7 +3,7 @@
 use crate::cstore::{self, CStore, MetadataBlob};
 use crate::locator::{self, CratePaths};
 use crate::schema::{CrateRoot, CrateDep};
-use rustc_data_structures::sync::{Lrc, RwLock, Lock, AtomicCell};
+use rustc_data_structures::sync::{RwLock, Lock, AtomicCell};
 
 use rustc::hir::def_id::CrateNum;
 use rustc_data_structures::svh::Svh;
@@ -14,21 +14,20 @@ 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};
+use rustc::middle::cstore::{CrateSource, ExternCrate, ExternCrateSource, MetadataLoaderDyn};
 use rustc::util::common::record_time;
 use rustc::util::nodemap::FxHashSet;
 use rustc::hir::map::Definitions;
 use rustc::hir::def_id::LOCAL_CRATE;
 
-use std::ops::Deref;
-use std::path::{Path, PathBuf};
+use std::path::Path;
 use std::{cmp, fs};
 
 use syntax::ast;
 use syntax::attr;
 use syntax_expand::allocator::{global_allocator_spans, AllocatorKind};
 use syntax::symbol::{Symbol, sym};
-use syntax::{span_err, span_fatal};
+use syntax::span_fatal;
 use syntax_pos::{Span, DUMMY_SP};
 use log::{debug, info, log_enabled};
 use proc_macro::bridge::client::ProcMacro;
@@ -39,9 +38,12 @@ crate struct Library {
 }
 
 pub struct CrateLoader<'a> {
+    // Immutable configuration.
     sess: &'a Session,
-    cstore: &'a CStore,
+    metadata_loader: &'a MetadataLoaderDyn,
     local_crate_name: Symbol,
+    // Mutable output.
+    cstore: CStore,
 }
 
 fn dump_crates(cstore: &CStore) {
@@ -58,29 +60,6 @@ fn dump_crates(cstore: &CStore) {
     });
 }
 
-// Extra info about a crate loaded for plugins or exported macros.
-struct ExtensionCrate {
-    metadata: PMDSource,
-    dylib: Option<PathBuf>,
-    target_only: bool,
-}
-
-enum PMDSource {
-    Registered(Lrc<cstore::CrateMetadata>),
-    Owned(Library),
-}
-
-impl Deref for PMDSource {
-    type Target = MetadataBlob;
-
-    fn deref(&self) -> &MetadataBlob {
-        match *self {
-            PMDSource::Registered(ref cmd) => &cmd.blob,
-            PMDSource::Owned(ref lib) => &lib.metadata
-        }
-    }
-}
-
 enum LoadResult {
     Previous(CrateNum),
     Loaded(Library),
@@ -99,14 +78,27 @@ impl<'a> LoadError<'a> {
 }
 
 impl<'a> CrateLoader<'a> {
-    pub fn new(sess: &'a Session, cstore: &'a CStore, local_crate_name: &str) -> Self {
+    pub fn new(
+        sess: &'a Session,
+        metadata_loader: &'a MetadataLoaderDyn,
+        local_crate_name: &str,
+    ) -> Self {
         CrateLoader {
             sess,
-            cstore,
+            metadata_loader,
             local_crate_name: Symbol::intern(local_crate_name),
+            cstore: Default::default(),
         }
     }
 
+    pub fn cstore(&self) -> &CStore {
+        &self.cstore
+    }
+
+    pub fn into_cstore(self) -> CStore {
+        self.cstore
+    }
+
     fn existing_match(&self, name: Symbol, hash: Option<&Svh>, kind: PathKind)
                       -> Option<CrateNum> {
         let mut ret = None;
@@ -187,14 +179,14 @@ impl<'a> CrateLoader<'a> {
     }
 
     fn register_crate(
-        &self,
+        &mut self,
         host_lib: Option<Library>,
         root: Option<&CratePaths>,
         span: Span,
         lib: Library,
         dep_kind: DepKind,
         name: Symbol
-    ) -> (CrateNum, Lrc<cstore::CrateMetadata>) {
+    ) -> CrateNum {
         let _prof_timer = self.sess.prof.generic_activity("metadata_register_crate");
 
         let Library { source, metadata } = lib;
@@ -248,9 +240,9 @@ impl<'a> CrateLoader<'a> {
             crate_root.def_path_table.decode((&metadata, self.sess))
         });
 
-        let cmeta = cstore::CrateMetadata {
+        self.cstore.set_crate_data(cnum, cstore::CrateMetadata {
             extern_crate: Lock::new(None),
-            def_path_table: Lrc::new(def_path_table),
+            def_path_table,
             trait_impls,
             root: crate_root,
             blob: metadata,
@@ -264,11 +256,9 @@ impl<'a> CrateLoader<'a> {
             private_dep,
             raw_proc_macros,
             dep_node_index: AtomicCell::new(DepNodeIndex::INVALID),
-        };
+        });
 
-        let cmeta = Lrc::new(cmeta);
-        self.cstore.set_crate_data(cnum, cmeta.clone());
-        (cnum, cmeta)
+        cnum
     }
 
     fn load_proc_macro<'b>(
@@ -327,22 +317,22 @@ impl<'a> CrateLoader<'a> {
     }
 
     fn resolve_crate<'b>(
-        &'b self,
+        &'b mut self,
         name: Symbol,
         span: Span,
         dep_kind: DepKind,
         dep: Option<(&'b CratePaths, &'b CrateDep)>,
-    ) -> (CrateNum, Lrc<cstore::CrateMetadata>) {
+    ) -> CrateNum {
         self.maybe_resolve_crate(name, span, dep_kind, dep).unwrap_or_else(|err| err.report())
     }
 
     fn maybe_resolve_crate<'b>(
-        &'b self,
+        &'b mut self,
         name: Symbol,
         span: Span,
         mut dep_kind: DepKind,
         dep: Option<(&'b CratePaths, &'b CrateDep)>,
-    ) -> Result<(CrateNum, Lrc<cstore::CrateMetadata>), LoadError<'b>> {
+    ) -> Result<CrateNum, LoadError<'b>> {
         info!("resolving crate `{}`", name);
         let (root, hash, extra_filename, path_kind) = match dep {
             Some((root, dep)) =>
@@ -370,7 +360,7 @@ impl<'a> CrateLoader<'a> {
                 rejected_via_filename: vec![],
                 should_match_name: true,
                 is_proc_macro: Some(false),
-                metadata_loader: &*self.cstore.metadata_loader,
+                metadata_loader: self.metadata_loader,
             };
 
             self.load(&mut locate_ctxt).map(|r| (r, None)).or_else(|| {
@@ -388,7 +378,7 @@ impl<'a> CrateLoader<'a> {
                 data.dep_kind.with_lock(|data_dep_kind| {
                     *data_dep_kind = cmp::max(*data_dep_kind, dep_kind);
                 });
-                Ok((cnum, data))
+                Ok(cnum)
             }
             (LoadResult::Loaded(library), host_library) => {
                 Ok(self.register_crate(host_library, root, span, library, dep_kind, name))
@@ -466,7 +456,7 @@ impl<'a> CrateLoader<'a> {
     }
 
     // Go through the crate metadata and load any crates that it references
-    fn resolve_crate_deps(&self,
+    fn resolve_crate_deps(&mut self,
                           root: &CratePaths,
                           crate_root: &CrateRoot<'_>,
                           metadata: &MetadataBlob,
@@ -492,73 +482,10 @@ impl<'a> CrateLoader<'a> {
                 DepKind::MacrosOnly => DepKind::MacrosOnly,
                 _ => dep.kind,
             };
-            self.resolve_crate(dep.name, span, dep_kind, Some((root, &dep))).0
+            self.resolve_crate(dep.name, span, dep_kind, Some((root, &dep)))
         })).collect()
     }
 
-    fn read_extension_crate(&self, name: Symbol, span: Span) -> ExtensionCrate {
-        info!("read extension crate `{}`", name);
-        let target_triple = self.sess.opts.target_triple.clone();
-        let host_triple = TargetTriple::from_triple(config::host_triple());
-        let is_cross = target_triple != host_triple;
-        let mut target_only = false;
-        let mut locate_ctxt = locator::Context {
-            sess: self.sess,
-            span,
-            crate_name: name,
-            hash: None,
-            extra_filename: None,
-            filesearch: self.sess.host_filesearch(PathKind::Crate),
-            target: &self.sess.host,
-            triple: host_triple,
-            root: None,
-            rejected_via_hash: vec![],
-            rejected_via_triple: vec![],
-            rejected_via_kind: vec![],
-            rejected_via_version: vec![],
-            rejected_via_filename: vec![],
-            should_match_name: true,
-            is_proc_macro: None,
-            metadata_loader: &*self.cstore.metadata_loader,
-        };
-        let library = self.load(&mut locate_ctxt).or_else(|| {
-            if !is_cross {
-                return None
-            }
-            // Try loading from target crates. This will abort later if we
-            // try to load a plugin registrar function,
-            target_only = true;
-
-            locate_ctxt.target = &self.sess.target.target;
-            locate_ctxt.triple = target_triple;
-            locate_ctxt.filesearch = self.sess.target_filesearch(PathKind::Crate);
-
-            self.load(&mut locate_ctxt)
-        });
-        let library = match library {
-            Some(l) => l,
-            None => locate_ctxt.report_errs(),
-        };
-
-        let (dylib, metadata) = match library {
-            LoadResult::Previous(cnum) => {
-                let data = self.cstore.get_crate_data(cnum);
-                (data.source.dylib.clone(), PMDSource::Registered(data))
-            }
-            LoadResult::Loaded(library) => {
-                let dylib = library.source.dylib.clone();
-                let metadata = PMDSource::Owned(library);
-                (dylib, metadata)
-            }
-        };
-
-        ExtensionCrate {
-            metadata,
-            dylib: dylib.map(|p| p.0),
-            target_only,
-        }
-    }
-
     fn dlsym_proc_macros(&self,
                          path: &Path,
                          disambiguator: CrateDisambiguator,
@@ -590,42 +517,7 @@ impl<'a> CrateLoader<'a> {
         decls
     }
 
-    /// Look for a plugin registrar. Returns library path, crate
-    /// SVH and DefIndex of the registrar function.
-    pub fn find_plugin_registrar(&self,
-                                 span: Span,
-                                 name: Symbol)
-                                 -> Option<(PathBuf, CrateDisambiguator)> {
-        let ekrate = self.read_extension_crate(name, span);
-
-        if ekrate.target_only {
-            // Need to abort before syntax expansion.
-            let message = format!("plugin `{}` is not available for triple `{}` \
-                                   (only found {})",
-                                  name,
-                                  config::host_triple(),
-                                  self.sess.opts.target_triple);
-            span_fatal!(self.sess, span, E0456, "{}", &message);
-        }
-
-        let root = ekrate.metadata.get_root();
-        match ekrate.dylib.as_ref() {
-            Some(dylib) => {
-                Some((dylib.to_path_buf(), root.disambiguator))
-            }
-            None => {
-                span_err!(self.sess, span, E0457,
-                          "plugin `{}` only found in rlib format, but must be available \
-                           in dylib format",
-                          name);
-                // No need to abort because the loading code will just ignore this
-                // empty dylib.
-                None
-            }
-        }
-    }
-
-    fn inject_panic_runtime(&self, krate: &ast::Crate) {
+    fn inject_panic_runtime(&mut self, krate: &ast::Crate) {
         // If we're only compiling an rlib, then there's no need to select a
         // panic runtime, so we just skip this section entirely.
         let any_non_rlib = self.sess.crate_types.borrow().iter().any(|ct| {
@@ -687,7 +579,8 @@ impl<'a> CrateLoader<'a> {
         };
         info!("panic runtime not found -- loading {}", name);
 
-        let (cnum, data) = self.resolve_crate(name, DUMMY_SP, DepKind::Implicit, None);
+        let cnum = self.resolve_crate(name, DUMMY_SP, DepKind::Implicit, None);
+        let data = self.cstore.get_crate_data(cnum);
 
         // Sanity check the loaded crate to ensure it is indeed a panic runtime
         // and the panic strategy is indeed what we thought it was.
@@ -706,7 +599,7 @@ impl<'a> CrateLoader<'a> {
                                   &|data| data.root.needs_panic_runtime);
     }
 
-    fn inject_sanitizer_runtime(&self) {
+    fn inject_sanitizer_runtime(&mut self) {
         if let Some(ref sanitizer) = self.sess.opts.debugging_opts.sanitizer {
             // Sanitizers can only be used on some tested platforms with
             // executables linked to `std`
@@ -791,7 +684,8 @@ impl<'a> CrateLoader<'a> {
                 });
                 info!("loading sanitizer: {}", name);
 
-                let data = self.resolve_crate(name, DUMMY_SP, DepKind::Explicit, None).1;
+                let cnum = self.resolve_crate(name, DUMMY_SP, DepKind::Explicit, None);
+                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 {
@@ -804,14 +698,15 @@ impl<'a> CrateLoader<'a> {
         }
     }
 
-    fn inject_profiler_runtime(&self) {
+    fn inject_profiler_runtime(&mut self) {
         if self.sess.opts.debugging_opts.profile ||
            self.sess.opts.cg.profile_generate.enabled()
         {
             info!("loading profiler");
 
             let name = Symbol::intern("profiler_builtins");
-            let data = self.resolve_crate(name, DUMMY_SP, DepKind::Implicit, None).1;
+            let cnum = self.resolve_crate(name, DUMMY_SP, DepKind::Implicit, None);
+            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 {
@@ -957,10 +852,8 @@ impl<'a> CrateLoader<'a> {
             data.dependencies.borrow_mut().push(krate);
         });
     }
-}
 
-impl<'a> CrateLoader<'a> {
-    pub fn postprocess(&self, krate: &ast::Crate) {
+    pub fn postprocess(&mut self, krate: &ast::Crate) {
         self.inject_sanitizer_runtime();
         self.inject_profiler_runtime();
         self.inject_allocator_crate(krate);
@@ -971,7 +864,11 @@ impl<'a> CrateLoader<'a> {
         }
     }
 
-    pub fn process_extern_crate(&self, item: &ast::Item, definitions: &Definitions) -> CrateNum {
+    pub fn process_extern_crate(
+        &mut self,
+        item: &ast::Item,
+        definitions: &Definitions,
+    ) -> CrateNum {
         match item.kind {
             ast::ItemKind::ExternCrate(orig_name) => {
                 debug!("resolving extern crate stmt. ident: {} orig_name: {:?}",
@@ -990,7 +887,7 @@ impl<'a> CrateLoader<'a> {
                     DepKind::Explicit
                 };
 
-                let cnum = self.resolve_crate(name, item.span, dep_kind, None).0;
+                let cnum = self.resolve_crate(name, item.span, dep_kind, None);
 
                 let def_id = definitions.opt_local_def_id(item.id).unwrap();
                 let path_len = definitions.def_path(def_id.index).data.len();
@@ -1010,8 +907,8 @@ impl<'a> CrateLoader<'a> {
         }
     }
 
-    pub fn process_path_extern(&self, name: Symbol, span: Span) -> CrateNum {
-        let cnum = self.resolve_crate(name, span, DepKind::Explicit, None).0;
+    pub fn process_path_extern(&mut self, name: Symbol, span: Span) -> CrateNum {
+        let cnum = self.resolve_crate(name, span, DepKind::Explicit, None);
 
         self.update_extern_crate(
             cnum,
@@ -1028,8 +925,8 @@ impl<'a> CrateLoader<'a> {
         cnum
     }
 
-    pub fn maybe_process_path_extern(&self, name: Symbol, span: Span) -> Option<CrateNum> {
-        let cnum = self.maybe_resolve_crate(name, span, DepKind::Explicit, None).ok()?.0;
+    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,
diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs
index 9a0b98ffb73..6b06cf575ed 100644
--- a/src/librustc_metadata/cstore.rs
+++ b/src/librustc_metadata/cstore.rs
@@ -5,12 +5,13 @@ use crate::schema;
 use rustc::dep_graph::DepNodeIndex;
 use rustc::hir::def_id::{CrateNum, DefIndex};
 use rustc::hir::map::definitions::DefPathTable;
-use rustc::middle::cstore::{CrateSource, DepKind, ExternCrate, MetadataLoader};
+use rustc::middle::cstore::{CrateSource, DepKind, ExternCrate};
 use rustc::mir::interpret::AllocDecodingState;
 use rustc_index::vec::IndexVec;
 use rustc::util::nodemap::FxHashMap;
 use rustc_data_structures::sync::{Lrc, RwLock, Lock, MetadataRef, AtomicCell};
 use syntax::ast;
+use syntax::edition::Edition;
 use syntax_expand::base::SyntaxExtension;
 use syntax_pos;
 use proc_macro::bridge::client::ProcMacro;
@@ -36,7 +37,7 @@ crate struct ImportedSourceFile {
     pub translated_source_file: Lrc<syntax_pos::SourceFile>,
 }
 
-pub struct CrateMetadata {
+crate struct CrateMetadata {
     /// The primary crate data - binary metadata blob.
     crate blob: MetadataBlob,
 
@@ -53,7 +54,7 @@ pub struct CrateMetadata {
     /// hashmap, which gives the reverse mapping. This allows us to
     /// quickly retrace a `DefPath`, which is needed for incremental
     /// compilation support.
-    crate def_path_table: Lrc<DefPathTable>,
+    crate def_path_table: DefPathTable,
     /// Trait impl data.
     /// FIXME: Used only from queries and can use query cache,
     /// so pre-decoding can probably be avoided.
@@ -94,50 +95,48 @@ pub struct CrateMetadata {
     crate extern_crate: Lock<Option<ExternCrate>>,
 }
 
+#[derive(Clone)]
 pub struct CStore {
-    metas: RwLock<IndexVec<CrateNum, Option<Lrc<CrateMetadata>>>>,
-    crate metadata_loader: Box<dyn MetadataLoader + Sync>,
+    metas: IndexVec<CrateNum, Option<Lrc<CrateMetadata>>>,
 }
 
 pub enum LoadedMacro {
-    MacroDef(ast::Item),
+    MacroDef(ast::Item, Edition),
     ProcMacro(SyntaxExtension),
 }
 
-impl CStore {
-    pub fn new(metadata_loader: Box<dyn MetadataLoader + Sync>) -> CStore {
+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: RwLock::new(IndexVec::from_elem_n(None, 1)),
-            metadata_loader,
+            metas: IndexVec::from_elem_n(None, 1),
         }
     }
+}
 
-    crate fn alloc_new_crate_num(&self) -> CrateNum {
-        let mut metas = self.metas.borrow_mut();
-        let cnum = CrateNum::new(metas.len());
-        metas.push(None);
-        cnum
+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) -> Lrc<CrateMetadata> {
-        self.metas.borrow()[cnum].clone()
+    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(&self, cnum: CrateNum, data: Lrc<CrateMetadata>) {
-        let mut metas = self.metas.borrow_mut();
-        assert!(metas[cnum].is_none(), "Overwriting crate metadata entry");
-        metas[cnum] = Some(data);
+    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, &Lrc<CrateMetadata>)
+        where I: FnMut(CrateNum, &CrateMetadata)
     {
-        for (k, v) in self.metas.borrow().iter_enumerated() {
+        for (k, v) in self.metas.iter_enumerated() {
             if let &Some(ref v) = v {
                 i(k, v);
             }
@@ -168,7 +167,7 @@ impl CStore {
 
     crate fn do_postorder_cnums_untracked(&self) -> Vec<CrateNum> {
         let mut ordering = Vec::new();
-        for (num, v) in self.metas.borrow().iter_enumerated() {
+        for (num, v) in self.metas.iter_enumerated() {
             if let &Some(_) = v {
                 self.push_dependencies_in_postorder(&mut ordering, num);
             }
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index 6aba66a79ab..d942a19194a 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -29,7 +29,6 @@ use std::sync::Arc;
 use syntax::ast;
 use syntax::attr;
 use syntax::source_map;
-use syntax::edition::Edition;
 use syntax::parse::source_file_to_stream;
 use syntax::parse::parser::emit_unclosed_delims;
 use syntax::source_map::Spanned;
@@ -54,7 +53,7 @@ macro_rules! provide {
                 let ($def_id, $other) = def_id_arg.into_args();
                 assert!(!$def_id.is_local());
 
-                let $cdata = $tcx.crate_data_as_rc_any($def_id.krate);
+                let $cdata = $tcx.crate_data_as_any($def_id.krate);
                 let $cdata = $cdata.downcast_ref::<cstore::CrateMetadata>()
                     .expect("CrateStore created data is not a CrateMetadata");
 
@@ -411,10 +410,6 @@ impl cstore::CStore {
         }
     }
 
-    pub fn crate_edition_untracked(&self, cnum: CrateNum) -> Edition {
-        self.get_crate_data(cnum).root.edition
-    }
-
     pub fn struct_field_names_untracked(&self, def: DefId, sess: &Session) -> Vec<Spanned<Symbol>> {
         self.get_crate_data(def.krate).get_struct_field_names(def.index, sess)
     }
@@ -470,7 +465,7 @@ impl cstore::CStore {
             }),
             vis: source_map::respan(local_span.shrink_to_lo(), ast::VisibilityKind::Inherited),
             tokens: None,
-        })
+        }, data.root.edition)
     }
 
     pub fn associated_item_cloned_untracked(&self, def: DefId) -> ty::AssocItem {
@@ -483,8 +478,8 @@ impl cstore::CStore {
 }
 
 impl CrateStore for cstore::CStore {
-    fn crate_data_as_rc_any(&self, krate: CrateNum) -> Lrc<dyn Any> {
-        self.get_crate_data(krate)
+    fn crate_data_as_any(&self, cnum: CrateNum) -> &dyn Any {
+        self.get_crate_data(cnum)
     }
 
     fn item_generics_cloned_untracked(&self, def: DefId, sess: &Session) -> ty::Generics {
@@ -525,8 +520,8 @@ impl CrateStore for cstore::CStore {
         self.get_crate_data(def.krate).def_path_hash(def.index)
     }
 
-    fn def_path_table(&self, cnum: CrateNum) -> Lrc<DefPathTable> {
-        self.get_crate_data(cnum).def_path_table.clone()
+    fn def_path_table(&self, cnum: CrateNum) -> &DefPathTable {
+        &self.get_crate_data(cnum).def_path_table
     }
 
     fn crates_untracked(&self) -> Vec<CrateNum>
diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs
index 05676dad334..a5298402dd4 100644
--- a/src/librustc_metadata/locator.rs
+++ b/src/librustc_metadata/locator.rs
@@ -212,7 +212,7 @@
 //! no means all of the necessary details. Take a look at the rest of
 //! metadata::locator or metadata::creader for all the juicy details!
 
-use crate::cstore::{MetadataBlob, CStore};
+use crate::cstore::MetadataBlob;
 use crate::creader::Library;
 use crate::schema::{METADATA_HEADER, rustc_version};
 
@@ -220,12 +220,13 @@ use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::svh::Svh;
 use rustc_data_structures::sync::MetadataRef;
 use rustc::middle::cstore::{CrateSource, MetadataLoader};
-use rustc::session::{config, Session};
+use rustc::session::{config, Session, CrateDisambiguator};
 use rustc::session::filesearch::{FileSearch, FileMatches, FileDoesntMatch};
 use rustc::session::search_paths::PathKind;
 use rustc::util::nodemap::FxHashMap;
 
 use errors::DiagnosticBuilder;
+use syntax::{span_err, span_fatal};
 use syntax::symbol::{Symbol, sym};
 use syntax::struct_span_err;
 use syntax_pos::Span;
@@ -911,10 +912,87 @@ fn get_metadata_section_imp(target: &Target,
     }
 }
 
+/// Look for a plugin registrar. Returns its library path and crate disambiguator.
+pub fn find_plugin_registrar(
+    sess: &Session,
+    metadata_loader: &dyn MetadataLoader,
+    span: Span,
+    name: Symbol,
+) -> Option<(PathBuf, CrateDisambiguator)> {
+    info!("find plugin registrar `{}`", name);
+    let target_triple = sess.opts.target_triple.clone();
+    let host_triple = TargetTriple::from_triple(config::host_triple());
+    let is_cross = target_triple != host_triple;
+    let mut target_only = false;
+    let mut locate_ctxt = Context {
+        sess,
+        span,
+        crate_name: name,
+        hash: None,
+        extra_filename: None,
+        filesearch: sess.host_filesearch(PathKind::Crate),
+        target: &sess.host,
+        triple: host_triple,
+        root: None,
+        rejected_via_hash: vec![],
+        rejected_via_triple: vec![],
+        rejected_via_kind: vec![],
+        rejected_via_version: vec![],
+        rejected_via_filename: vec![],
+        should_match_name: true,
+        is_proc_macro: None,
+        metadata_loader,
+    };
+
+    let library = locate_ctxt.maybe_load_library_crate().or_else(|| {
+        if !is_cross {
+            return None
+        }
+        // Try loading from target crates. This will abort later if we
+        // try to load a plugin registrar function,
+        target_only = true;
+
+        locate_ctxt.target = &sess.target.target;
+        locate_ctxt.triple = target_triple;
+        locate_ctxt.filesearch = sess.target_filesearch(PathKind::Crate);
+
+        locate_ctxt.maybe_load_library_crate()
+    });
+    let library = match library {
+        Some(l) => l,
+        None => locate_ctxt.report_errs(),
+    };
+
+    if target_only {
+        // Need to abort before syntax expansion.
+        let message = format!("plugin `{}` is not available for triple `{}` \
+                                (only found {})",
+                                name,
+                                config::host_triple(),
+                                sess.opts.target_triple);
+        span_fatal!(sess, span, E0456, "{}", &message);
+    }
+
+    match library.source.dylib {
+        Some(dylib) => {
+            Some((dylib.0, library.metadata.get_root().disambiguator))
+        }
+        None => {
+            span_err!(sess, span, E0457,
+                        "plugin `{}` only found in rlib format, but must be available \
+                        in dylib format",
+                        name);
+            // No need to abort because the loading code will just ignore this
+            // empty dylib.
+            None
+        }
+    }
+}
+
 /// A diagnostic function for dumping crate metadata to an output stream.
 pub fn list_file_metadata(target: &Target,
                           path: &Path,
-                          cstore: &CStore,
+                          metadata_loader: &dyn MetadataLoader,
                           out: &mut dyn io::Write)
                           -> io::Result<()> {
     let filename = path.file_name().unwrap().to_str().unwrap();
@@ -925,7 +1003,7 @@ pub fn list_file_metadata(target: &Target,
     } else {
         CrateFlavor::Dylib
     };
-    match get_metadata_section(target, flavor, path, &*cstore.metadata_loader) {
+    match get_metadata_section(target, flavor, path, metadata_loader) {
         Ok(metadata) => metadata.list_crate_metadata(out),
         Err(msg) => write!(out, "{}\n", msg),
     }
diff --git a/src/librustc_plugin/load.rs b/src/librustc_plugin/load.rs
index 4481892bcf2..8ceb56b0fd2 100644
--- a/src/librustc_plugin/load.rs
+++ b/src/librustc_plugin/load.rs
@@ -1,8 +1,8 @@
 //! Used by `rustc` when loading a plugin.
 
+use rustc::middle::cstore::MetadataLoader;
 use rustc::session::Session;
-use rustc_metadata::creader::CrateLoader;
-use rustc_metadata::cstore::CStore;
+use rustc_metadata::locator;
 use crate::registry::Registry;
 
 use std::borrow::ToOwned;
@@ -25,7 +25,7 @@ pub struct PluginRegistrar {
 
 struct PluginLoader<'a> {
     sess: &'a Session,
-    reader: CrateLoader<'a>,
+    metadata_loader: &'a dyn MetadataLoader,
     plugins: Vec<PluginRegistrar>,
 }
 
@@ -37,11 +37,10 @@ fn call_malformed_plugin_attribute(sess: &Session, span: Span) {
 
 /// Read plugin metadata and dynamically load registrar functions.
 pub fn load_plugins(sess: &Session,
-                    cstore: &CStore,
+                    metadata_loader: &dyn MetadataLoader,
                     krate: &ast::Crate,
-                    crate_name: &str,
                     addl_plugins: Option<Vec<String>>) -> Vec<PluginRegistrar> {
-    let mut loader = PluginLoader::new(sess, cstore, crate_name);
+    let mut loader = PluginLoader { sess, metadata_loader, plugins: Vec::new() };
 
     // do not report any error now. since crate attributes are
     // not touched by expansion, every use of plugin without
@@ -80,16 +79,8 @@ pub fn load_plugins(sess: &Session,
 }
 
 impl<'a> PluginLoader<'a> {
-    fn new(sess: &'a Session, cstore: &'a CStore, crate_name: &str) -> Self {
-        PluginLoader {
-            sess,
-            reader: CrateLoader::new(sess, cstore, crate_name),
-            plugins: vec![],
-        }
-    }
-
     fn load_plugin(&mut self, span: Span, name: Symbol, args: Vec<ast::NestedMetaItem>) {
-        let registrar = self.reader.find_plugin_registrar(span, name);
+        let registrar = locator::find_plugin_registrar(self.sess, self.metadata_loader, span, name);
 
         if let Some((lib, disambiguator)) = registrar {
             let symbol = self.sess.generate_plugin_registrar_symbol(disambiguator);
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 6444a82fd73..c0fb8e33a81 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -110,9 +110,9 @@ impl<'a> Resolver<'a> {
         }
 
         let (name, parent) = if def_id.index == CRATE_DEF_INDEX {
-            (self.cstore.crate_name_untracked(def_id.krate), None)
+            (self.cstore().crate_name_untracked(def_id.krate), None)
         } else {
-            let def_key = self.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 })))
         };
@@ -153,9 +153,8 @@ impl<'a> Resolver<'a> {
             return Some(ext.clone());
         }
 
-        let ext = Lrc::new(match self.cstore.load_macro_untracked(def_id, &self.session) {
-            LoadedMacro::MacroDef(item) =>
-                self.compile_macro(&item, self.cstore.crate_edition_untracked(def_id.krate)),
+        let ext = Lrc::new(match self.cstore().load_macro_untracked(def_id, &self.session) {
+            LoadedMacro::MacroDef(item, edition) => self.compile_macro(&item, edition),
             LoadedMacro::ProcMacro(ext) => ext,
         });
 
@@ -177,7 +176,7 @@ impl<'a> Resolver<'a> {
 
     crate fn build_reduced_graph_external(&mut self, module: Module<'a>) {
         let def_id = module.def_id().expect("unpopulated module without a def-id");
-        for child in self.cstore.item_children_untracked(def_id, self.session) {
+        for child in self.cstore().item_children_untracked(def_id, self.session) {
             let child = child.map_id(|_| panic!("unexpected id"));
             BuildReducedGraphVisitor { r: self, parent_scope: ParentScope::module(module) }
                 .build_reduced_graph_for_external_crate_res(child);
@@ -885,19 +884,19 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
                 bug!("unexpected resolution: {:?}", res)
         }
         // Record some extra data for better diagnostics.
+        let cstore = self.r.cstore();
         match res {
             Res::Def(DefKind::Struct, def_id) | Res::Def(DefKind::Union, def_id) => {
-                let field_names =
-                    self.r.cstore.struct_field_names_untracked(def_id, self.r.session);
+                let field_names = cstore.struct_field_names_untracked(def_id, self.r.session);
                 self.insert_field_names(def_id, field_names);
             }
             Res::Def(DefKind::Method, def_id) => {
-                if self.r.cstore.associated_item_cloned_untracked(def_id).method_has_self_argument {
+                if cstore.associated_item_cloned_untracked(def_id).method_has_self_argument {
                     self.r.has_self.insert(def_id);
                 }
             }
             Res::Def(DefKind::Ctor(CtorOf::Struct, ..), def_id) => {
-                let parent = self.r.cstore.def_key(def_id).parent;
+                let parent = cstore.def_key(def_id).parent;
                 if let Some(struct_def_id) = parent.map(|index| DefId { index, ..def_id }) {
                     self.r.struct_constructors.insert(struct_def_id, (res, vis));
                 }
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 17d8f0f211a..1c67395fbf0 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -21,14 +21,14 @@ use Determinacy::*;
 
 use rustc::hir::map::Definitions;
 use rustc::hir::{self, PrimTy, Bool, Char, Float, Int, Uint, Str};
-use rustc::middle::cstore::CrateStore;
+use rustc::middle::cstore::{CrateStore, MetadataLoaderDyn};
 use rustc::session::Session;
 use rustc::lint;
 use rustc::hir::def::{self, DefKind, PartialRes, CtorKind, CtorOf, NonMacroAttrKind, ExportMap};
 use rustc::hir::def::Namespace::*;
 use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, CrateNum, DefId};
 use rustc::hir::{TraitMap, GlobMap};
-use rustc::ty::{self, DefIdTree};
+use rustc::ty::{self, DefIdTree, ResolverOutputs};
 use rustc::util::nodemap::{NodeMap, NodeSet, FxHashMap, FxHashSet, DefIdMap};
 use rustc::span_bug;
 
@@ -829,14 +829,13 @@ pub struct ExternPreludeEntry<'a> {
 /// This is the visitor that walks the whole crate.
 pub struct Resolver<'a> {
     session: &'a Session,
-    cstore: &'a CStore,
 
-    pub definitions: Definitions,
+    definitions: Definitions,
 
-    pub graph_root: Module<'a>,
+    graph_root: Module<'a>,
 
     prelude: Option<Module<'a>>,
-    pub extern_prelude: FxHashMap<Ident, ExternPreludeEntry<'a>>,
+    extern_prelude: FxHashMap<Ident, ExternPreludeEntry<'a>>,
 
     /// N.B., this is used only for better diagnostics, not name resolution itself.
     has_self: FxHashSet<DefId>,
@@ -869,9 +868,9 @@ pub struct Resolver<'a> {
     label_res_map: NodeMap<NodeId>,
 
     /// `CrateNum` resolutions of `extern crate` items.
-    pub extern_crate_map: NodeMap<CrateNum>,
-    pub export_map: ExportMap<NodeId>,
-    pub trait_map: TraitMap,
+    extern_crate_map: NodeMap<CrateNum>,
+    export_map: ExportMap<NodeId>,
+    trait_map: TraitMap,
 
     /// A map from nodes to anonymous modules.
     /// Anonymous modules are pseudo-modules that are implicitly created around items
@@ -898,11 +897,11 @@ pub struct Resolver<'a> {
     underscore_disambiguator: u32,
 
     /// Maps glob imports to the names of items actually imported.
-    pub glob_map: GlobMap,
+    glob_map: GlobMap,
 
     used_imports: FxHashSet<(NodeId, Namespace)>,
-    pub maybe_unused_trait_imports: NodeSet,
-    pub maybe_unused_extern_crates: Vec<(NodeId, Span)>,
+    maybe_unused_trait_imports: NodeSet,
+    maybe_unused_extern_crates: Vec<(NodeId, Span)>,
 
     /// Privacy errors are delayed until the end in order to deduplicate them.
     privacy_errors: Vec<PrivacyError<'a>>,
@@ -916,11 +915,11 @@ pub struct Resolver<'a> {
     arenas: &'a ResolverArenas<'a>,
     dummy_binding: &'a NameBinding<'a>,
 
-    crate_loader: &'a CrateLoader<'a>,
+    crate_loader: CrateLoader<'a>,
     macro_names: FxHashSet<Ident>,
     builtin_macros: FxHashMap<Name, SyntaxExtension>,
     macro_use_prelude: FxHashMap<Name, &'a NameBinding<'a>>,
-    pub all_macros: FxHashMap<Name, Res>,
+    all_macros: FxHashMap<Name, Res>,
     macro_map: FxHashMap<DefId, Lrc<SyntaxExtension>>,
     dummy_ext_bang: Lrc<SyntaxExtension>,
     dummy_ext_derive: Lrc<SyntaxExtension>,
@@ -1015,7 +1014,7 @@ impl<'a, 'b> 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.cstore.def_key(id).parent,
+            _ => self.cstore().def_key(id).parent,
         }.map(|index| DefId { index, ..id })
     }
 }
@@ -1023,6 +1022,10 @@ impl<'a, 'b> DefIdTree for &'a Resolver<'b> {
 /// This interface is used through the AST→HIR step, to embed full paths into the HIR. After that
 /// the resolver is no longer needed as all the relevant information is inline.
 impl<'a> hir::lowering::Resolver for Resolver<'a> {
+    fn cstore(&self) -> &dyn CrateStore {
+        self.cstore()
+    }
+
     fn resolve_str_path(
         &mut self,
         span: Span,
@@ -1083,10 +1086,9 @@ impl<'a> hir::lowering::Resolver for Resolver<'a> {
 
 impl<'a> Resolver<'a> {
     pub fn new(session: &'a Session,
-               cstore: &'a CStore,
                krate: &Crate,
                crate_name: &str,
-               crate_loader: &'a CrateLoader<'a>,
+               metadata_loader: &'a MetadataLoaderDyn,
                arenas: &'a ResolverArenas<'a>)
                -> Resolver<'a> {
         let root_def_id = DefId::local(CRATE_DEF_INDEX);
@@ -1147,8 +1149,6 @@ impl<'a> Resolver<'a> {
         Resolver {
             session,
 
-            cstore,
-
             definitions,
 
             // The outermost module has def ID 0; this is not reflected in the
@@ -1202,7 +1202,7 @@ impl<'a> Resolver<'a> {
                 vis: ty::Visibility::Public,
             }),
 
-            crate_loader,
+            crate_loader: CrateLoader::new(session, metadata_loader, crate_name),
             macro_names: FxHashSet::default(),
             builtin_macros: Default::default(),
             macro_use_prelude: FxHashMap::default(),
@@ -1236,6 +1236,42 @@ impl<'a> Resolver<'a> {
         Default::default()
     }
 
+    pub fn into_outputs(self) -> ResolverOutputs {
+        ResolverOutputs {
+            definitions: self.definitions,
+            cstore: Box::new(self.crate_loader.into_cstore()),
+            extern_crate_map: self.extern_crate_map,
+            export_map: self.export_map,
+            trait_map: self.trait_map,
+            glob_map: self.glob_map,
+            maybe_unused_trait_imports: self.maybe_unused_trait_imports,
+            maybe_unused_extern_crates: self.maybe_unused_extern_crates,
+            extern_prelude: self.extern_prelude.iter().map(|(ident, entry)| {
+                (ident.name, entry.introduced_by_item)
+            }).collect(),
+        }
+    }
+
+    pub fn clone_outputs(&self) -> ResolverOutputs {
+        ResolverOutputs {
+            definitions: self.definitions.clone(),
+            cstore: Box::new(self.cstore().clone()),
+            extern_crate_map: self.extern_crate_map.clone(),
+            export_map: self.export_map.clone(),
+            trait_map: self.trait_map.clone(),
+            glob_map: self.glob_map.clone(),
+            maybe_unused_trait_imports: self.maybe_unused_trait_imports.clone(),
+            maybe_unused_extern_crates: self.maybe_unused_extern_crates.clone(),
+            extern_prelude: self.extern_prelude.iter().map(|(ident, entry)| {
+                (ident.name, entry.introduced_by_item)
+            }).collect(),
+        }
+    }
+
+    pub fn cstore(&self) -> &CStore {
+        self.crate_loader.cstore()
+    }
+
     fn non_macro_attr(&self, mark_used: bool) -> Lrc<SyntaxExtension> {
         self.non_macro_attrs[mark_used as usize].clone()
     }
@@ -2808,6 +2844,16 @@ impl<'a> Resolver<'a> {
         seg.id = self.session.next_node_id();
         seg
     }
+
+    // For rustdoc.
+    pub fn graph_root(&self) -> Module<'a> {
+        self.graph_root
+    }
+
+    // For rustdoc.
+    pub fn all_macros(&self) -> &FxHashMap<Name, Res> {
+        &self.all_macros
+    }
 }
 
 fn names_to_string(names: &[Name]) -> String {
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index 34edd5eaf4f..31340ddd683 100644
--- a/src/librustc_resolve/resolve_imports.rs
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -1344,7 +1344,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
                 if res != Res::Err {
                     if let Some(def_id) = res.opt_def_id() {
                         if !def_id.is_local() {
-                            this.cstore.export_macros_untracked(def_id.krate);
+                            this.cstore().export_macros_untracked(def_id.krate);
                         }
                     }
                     reexports.push(Export {
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index e7cc8b76e48..a6a8fec429e 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -479,8 +479,8 @@ fn build_static(cx: &DocContext<'_>, did: DefId, mutable: bool) -> clean::Static
 
 fn build_macro(cx: &DocContext<'_>, did: DefId, name: ast::Name) -> clean::ItemEnum {
     let imported_from = cx.tcx.original_crate_name(did.krate);
-    match cx.cstore.load_macro_untracked(did, cx.sess()) {
-        LoadedMacro::MacroDef(def) => {
+    match cx.enter_resolver(|r| r.cstore().load_macro_untracked(did, cx.sess())) {
+        LoadedMacro::MacroDef(def, _) => {
             let matchers: hir::HirVec<Span> = if let ast::ItemKind::MacroDef(ref def) = def.kind {
                 let tts: Vec<_> = def.stream().into_trees().collect();
                 tts.chunks(4).map(|arm| arm[0].span()).collect()
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 39ab30e8ecf..b227f432a4e 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -12,7 +12,6 @@ use rustc::util::nodemap::{FxHashMap, FxHashSet};
 use rustc_interface::interface;
 use rustc_driver::abort_on_err;
 use rustc_resolve as resolve;
-use rustc_metadata::cstore::CStore;
 
 use syntax::source_map;
 use syntax::attr;
@@ -43,7 +42,6 @@ pub struct DocContext<'tcx> {
 
     pub tcx: TyCtxt<'tcx>,
     pub resolver: Rc<RefCell<interface::BoxedResolver>>,
-    pub cstore: Lrc<CStore>,
     /// Later on moved into `html::render::CACHE_KEY`
     pub renderinfo: RefCell<RenderInfo>,
     /// Later on moved through `clean::Crate` into `html::render::CACHE_KEY`
@@ -117,9 +115,7 @@ impl<'tcx> DocContext<'tcx> {
                     .def_path_table()
                     .next_id()
             } else {
-                self.cstore
-                    .def_path_table(crate_num)
-                    .next_id()
+                self.enter_resolver(|r| r.cstore().def_path_table(crate_num).next_id())
             };
 
             DefId {
@@ -376,7 +372,6 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt
             let mut ctxt = DocContext {
                 tcx,
                 resolver,
-                cstore: compiler.cstore().clone(),
                 external_traits: Default::default(),
                 active_extern_traits: Default::default(),
                 renderinfo: RefCell::new(renderinfo),
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index 4270b162baf..caa7f08f68c 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -432,13 +432,13 @@ fn macro_resolve(cx: &DocContext<'_>, path_str: &str) -> Option<Res> {
     let path = ast::Path::from_ident(Ident::from_str(path_str));
     cx.enter_resolver(|resolver| {
         if let Ok((Some(ext), res)) = resolver.resolve_macro_path(
-            &path, None, &ParentScope::module(resolver.graph_root), false, false
+            &path, None, &ParentScope::module(resolver.graph_root()), false, false
         ) {
             if let SyntaxExtensionKind::LegacyBang { .. } = ext.kind {
                 return Some(res.map_id(|_| panic!("unexpected id")));
             }
         }
-        if let Some(res) = resolver.all_macros.get(&Symbol::intern(path_str)) {
+        if let Some(res) = resolver.all_macros().get(&Symbol::intern(path_str)) {
             return Some(res.map_id(|_| panic!("unexpected id")));
         }
         None
diff --git a/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs b/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs
index 1566a153ec0..eb96c61060b 100644
--- a/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs
+++ b/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs
@@ -9,14 +9,14 @@ extern crate rustc_target;
 extern crate rustc_driver;
 
 use std::any::Any;
-use std::sync::{Arc, mpsc};
+use std::sync::Arc;
 use std::path::Path;
 use syntax::symbol::Symbol;
 use rustc::session::Session;
 use rustc::session::config::OutputFilenames;
 use rustc::ty::TyCtxt;
 use rustc::ty::query::Providers;
-use rustc::middle::cstore::{EncodedMetadata, MetadataLoader};
+use rustc::middle::cstore::{EncodedMetadata, MetadataLoader, MetadataLoaderDyn};
 use rustc::dep_graph::DepGraph;
 use rustc::util::common::ErrorReported;
 use rustc_codegen_utils::codegen_backend::CodegenBackend;
@@ -41,7 +41,7 @@ impl MetadataLoader for NoLlvmMetadataLoader {
 struct TheBackend;
 
 impl CodegenBackend for TheBackend {
-    fn metadata_loader(&self) -> Box<dyn MetadataLoader + Sync> {
+    fn metadata_loader(&self) -> Box<MetadataLoaderDyn> {
         Box::new(NoLlvmMetadataLoader)
     }