about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-10-25 00:40:55 +0000
committerbors <bors@rust-lang.org>2019-10-25 00:40:55 +0000
commitd54111afc061ef398cd8ce28984f9e8d70001b24 (patch)
tree4e68a43ce1cde8526dd1ce1229ed297a8182a1b4 /src
parent10a52c25cad963986cace7a22c167363afca0d74 (diff)
parentfd6795b46a249d33c0127f77e08019b401a67fc5 (diff)
downloadrust-d54111afc061ef398cd8ce28984f9e8d70001b24.tar.gz
rust-d54111afc061ef398cd8ce28984f9e8d70001b24.zip
Auto merge of #65771 - Centril:rollup-upfsvrb, r=Centril
Rollup of 8 pull requests

Successful merges:

 - #65625 (Turn crate store into a resolver output)
 - #65627 (Forbid non-`structural_match` types in const generics)
 - #65710 (Update cargo)
 - #65729 (Update test cases for vxWorks)
 - #65746 (Tweak format string error to point at arguments always)
 - #65753 (Don't assert for different instance on impl trait alias)
 - #65755 (Avoid ICE when adjusting bad self ty)
 - #65766 (Update hashbrown to 0.6.2)

Failed merges:

r? @ghost
Diffstat (limited to 'src')
-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.rs133
-rw-r--r--src/librustc/ty/relate.rs7
-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_mir/hair/pattern/mod.rs144
-rw-r--r--src/librustc_plugin/load.rs21
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs19
-rw-r--r--src/librustc_resolve/diagnostics.rs10
-rw-r--r--src/librustc_resolve/error_codes.rs7
-rw-r--r--src/librustc_resolve/late.rs23
-rw-r--r--src/librustc_resolve/lib.rs101
-rw-r--r--src/librustc_resolve/resolve_imports.rs2
-rw-r--r--src/librustc_typeck/check/method/confirm.rs20
-rw-r--r--src/librustc_typeck/check/mod.rs3
-rw-r--r--src/librustc_typeck/collect.rs11
-rw-r--r--src/librustc_typeck/error_codes.rs24
-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/libstd/Cargo.toml2
-rw-r--r--src/libsyntax_ext/format.rs5
-rw-r--r--src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs6
-rw-r--r--src/test/rustdoc/const-generics/const-impl.rs1
-rw-r--r--src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.rs2
-rw-r--r--src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr14
-rw-r--r--src/test/ui/const-generics/const-param-type-depends-on-type-param.rs3
-rw-r--r--src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr19
-rw-r--r--src/test/ui/const-generics/forbid-non-structural_match-types.rs13
-rw-r--r--src/test/ui/const-generics/forbid-non-structural_match-types.stderr17
-rw-r--r--src/test/ui/fmt/format-string-error.rs2
-rw-r--r--src/test/ui/fmt/format-string-error.stderr8
-rw-r--r--src/test/ui/if/ifmt-bad-arg.stderr10
-rw-r--r--src/test/ui/intrinsics/intrinsic-alignment.rs3
-rw-r--r--src/test/ui/issues/issue-65611.rs63
-rw-r--r--src/test/ui/issues/issue-65611.stderr18
-rw-r--r--src/test/ui/signal-alternate-stack-cleanup.rs1
-rw-r--r--src/test/ui/structs-enums/rec-align-u64.rs3
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs17
m---------src/tools/cargo0
50 files changed, 715 insertions, 638 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..4660e8025d4 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -4,7 +4,7 @@ pub use self::Variance::*;
 pub use self::AssocItemContainer::*;
 pub use self::BorrowKind::*;
 pub use self::IntVarValue::*;
-pub use self::fold::TypeFoldable;
+pub use self::fold::{TypeFoldable, TypeVisitor};
 
 use crate::hir::{map as hir_map, GlobMap, TraitMap};
 use crate::hir::Node;
@@ -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;
@@ -50,7 +51,7 @@ use syntax::symbol::{kw, sym, Symbol};
 use syntax_pos::Span;
 
 use smallvec;
-use rustc_data_structures::fx::FxIndexMap;
+use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
 use rustc_data_structures::stable_hasher::{StableHasher, HashStable};
 use rustc_index::vec::{Idx, IndexVec};
 
@@ -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,
@@ -3393,6 +3395,129 @@ fn asyncness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::IsAsync {
     fn_like.asyncness()
 }
 
+pub enum NonStructuralMatchTy<'tcx> {
+    Adt(&'tcx AdtDef),
+    Param,
+}
+
+/// This method traverses the structure of `ty`, trying to find an
+/// instance of an ADT (i.e. struct or enum) that was declared without
+/// the `#[structural_match]` attribute, or a generic type parameter
+/// (which cannot be determined to be `structural_match`).
+///
+/// The "structure of a type" includes all components that would be
+/// considered when doing a pattern match on a constant of that
+/// type.
+///
+///  * This means this method descends into fields of structs/enums,
+///    and also descends into the inner type `T` of `&T` and `&mut T`
+///
+///  * The traversal doesn't dereference unsafe pointers (`*const T`,
+///    `*mut T`), and it does not visit the type arguments of an
+///    instantiated generic like `PhantomData<T>`.
+///
+/// The reason we do this search is Rust currently require all ADTs
+/// reachable from a constant's type to be annotated with
+/// `#[structural_match]`, an attribute which essentially says that
+/// the implementation of `PartialEq::eq` behaves *equivalently* to a
+/// comparison against the unfolded structure.
+///
+/// For more background on why Rust has this requirement, and issues
+/// that arose when the requirement was not enforced completely, see
+/// Rust RFC 1445, rust-lang/rust#61188, and rust-lang/rust#62307.
+pub fn search_for_structural_match_violation<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    ty: Ty<'tcx>,
+) -> Option<NonStructuralMatchTy<'tcx>> {
+    let mut search = Search { tcx, found: None, seen: FxHashSet::default() };
+    ty.visit_with(&mut search);
+    return search.found;
+
+    struct Search<'tcx> {
+        tcx: TyCtxt<'tcx>,
+
+        // Records the first ADT or type parameter we find without `#[structural_match`.
+        found: Option<NonStructuralMatchTy<'tcx>>,
+
+        // Tracks ADTs previously encountered during search, so that
+        // we will not recurse on them again.
+        seen: FxHashSet<hir::def_id::DefId>,
+    }
+
+    impl<'tcx> TypeVisitor<'tcx> for Search<'tcx> {
+        fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
+            debug!("Search visiting ty: {:?}", ty);
+
+            let (adt_def, substs) = match ty.kind {
+                ty::Adt(adt_def, substs) => (adt_def, substs),
+                ty::Param(_) => {
+                    self.found = Some(NonStructuralMatchTy::Param);
+                    return true; // Stop visiting.
+                }
+                ty::RawPtr(..) => {
+                    // `#[structural_match]` ignores substructure of
+                    // `*const _`/`*mut _`, so skip super_visit_with
+                    //
+                    // (But still tell caller to continue search.)
+                    return false;
+                }
+                ty::FnDef(..) | ty::FnPtr(..) => {
+                    // types of formals and return in `fn(_) -> _` are also irrelevant
+                    //
+                    // (But still tell caller to continue search.)
+                    return false;
+                }
+                ty::Array(_, n) if n.try_eval_usize(self.tcx, ty::ParamEnv::reveal_all()) == Some(0)
+                => {
+                    // rust-lang/rust#62336: ignore type of contents
+                    // for empty array.
+                    return false;
+                }
+                _ => {
+                    ty.super_visit_with(self);
+                    return false;
+                }
+            };
+
+            if !self.tcx.has_attr(adt_def.did, sym::structural_match) {
+                self.found = Some(NonStructuralMatchTy::Adt(&adt_def));
+                debug!("Search found adt_def: {:?}", adt_def);
+                return true; // Stop visiting.
+            }
+
+            if !self.seen.insert(adt_def.did) {
+                debug!("Search already seen adt_def: {:?}", adt_def);
+                // let caller continue its search
+                return false;
+            }
+
+            // `#[structural_match]` does not care about the
+            // instantiation of the generics in an ADT (it
+            // instead looks directly at its fields outside
+            // this match), so we skip super_visit_with.
+            //
+            // (Must not recur on substs for `PhantomData<T>` cf
+            // rust-lang/rust#55028 and rust-lang/rust#55837; but also
+            // want to skip substs when only uses of generic are
+            // behind unsafe pointers `*const T`/`*mut T`.)
+
+            // even though we skip super_visit_with, we must recur on
+            // fields of ADT.
+            let tcx = self.tcx;
+            for field_ty in adt_def.all_fields().map(|field| field.ty(tcx, substs)) {
+                if field_ty.visit_with(self) {
+                    // found an ADT without `#[structural_match]`; halt visiting!
+                    assert!(self.found.is_some());
+                    return true;
+                }
+            }
+
+            // Even though we do not want to recur on substs, we do
+            // want our caller to continue its own search.
+            false
+        }
+    }
+}
 
 pub fn provide(providers: &mut ty::query::Providers<'_>) {
     context::provide(providers);
diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs
index 41f34703622..1da65f4b51d 100644
--- a/src/librustc/ty/relate.rs
+++ b/src/librustc/ty/relate.rs
@@ -557,10 +557,9 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
         x.val
     };
 
-    // Currently, the values that can be unified are those that
-    // implement both `PartialEq` and `Eq`, corresponding to
-    // `structural_match` types.
-    // FIXME(const_generics): check for `structural_match` synthetic attribute.
+    // Currently, the values that can be unified are primitive types,
+    // and those that derive both `PartialEq` and `Eq`, corresponding
+    // to `structural_match` types.
     let new_const_val = match (eagerly_eval(a), eagerly_eval(b)) {
         (ConstValue::Infer(_), _) | (_, ConstValue::Infer(_)) => {
             // The caller should handle these cases!
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_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs
index 58480912929..98e286e61e9 100644
--- a/src/librustc_mir/hair/pattern/mod.rs
+++ b/src/librustc_mir/hair/pattern/mod.rs
@@ -25,7 +25,6 @@ use rustc::hir::pat_util::EnumerateAndAdjustIterator;
 use rustc::hir::ptr::P;
 
 use rustc_index::vec::Idx;
-use rustc_data_structures::fx::FxHashSet;
 
 use std::cmp::Ordering;
 use std::fmt;
@@ -1000,15 +999,21 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
         if self.include_lint_checks && !saw_error {
             // If we were able to successfully convert the const to some pat, double-check
             // that the type of the const obeys `#[structural_match]` constraint.
-            if let Some(adt_def) = search_for_adt_without_structural_match(self.tcx, cv.ty) {
-
-                let path = self.tcx.def_path_str(adt_def.did);
-                let msg = format!(
-                    "to use a constant of type `{}` in a pattern, \
-                     `{}` must be annotated with `#[derive(PartialEq, Eq)]`",
-                    path,
-                    path,
-                );
+            if let Some(non_sm_ty) = ty::search_for_structural_match_violation(self.tcx, cv.ty) {
+                let msg = match non_sm_ty {
+                    ty::NonStructuralMatchTy::Adt(adt_def) => {
+                        let path = self.tcx.def_path_str(adt_def.did);
+                        format!(
+                            "to use a constant of type `{}` in a pattern, \
+                             `{}` must be annotated with `#[derive(PartialEq, Eq)]`",
+                            path,
+                            path,
+                        )
+                    }
+                    ty::NonStructuralMatchTy::Param => {
+                        bug!("use of constant whose type is a parameter inside a pattern");
+                    }
+                };
 
                 // before issuing lint, double-check there even *is* a
                 // semantic PartialEq for us to dispatch to.
@@ -1169,125 +1174,6 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
     }
 }
 
-/// This method traverses the structure of `ty`, trying to find an
-/// instance of an ADT (i.e. struct or enum) that was declared without
-/// the `#[structural_match]` attribute.
-///
-/// The "structure of a type" includes all components that would be
-/// considered when doing a pattern match on a constant of that
-/// type.
-///
-///  * This means this method descends into fields of structs/enums,
-///    and also descends into the inner type `T` of `&T` and `&mut T`
-///
-///  * The traversal doesn't dereference unsafe pointers (`*const T`,
-///    `*mut T`), and it does not visit the type arguments of an
-///    instantiated generic like `PhantomData<T>`.
-///
-/// The reason we do this search is Rust currently require all ADT's
-/// reachable from a constant's type to be annotated with
-/// `#[structural_match]`, an attribute which essentially says that
-/// the implementation of `PartialEq::eq` behaves *equivalently* to a
-/// comparison against the unfolded structure.
-///
-/// For more background on why Rust has this requirement, and issues
-/// that arose when the requirement was not enforced completely, see
-/// Rust RFC 1445, rust-lang/rust#61188, and rust-lang/rust#62307.
-fn search_for_adt_without_structural_match<'tcx>(tcx: TyCtxt<'tcx>,
-                                                 ty: Ty<'tcx>)
-                                                 -> Option<&'tcx AdtDef>
-{
-    // Import here (not mod level), because `TypeFoldable::fold_with`
-    // conflicts with `PatternFoldable::fold_with`
-    use crate::rustc::ty::fold::TypeVisitor;
-    use crate::rustc::ty::TypeFoldable;
-
-    let mut search = Search { tcx, found: None, seen: FxHashSet::default() };
-    ty.visit_with(&mut search);
-    return search.found;
-
-    struct Search<'tcx> {
-        tcx: TyCtxt<'tcx>,
-
-        // records the first ADT we find without `#[structural_match`
-        found: Option<&'tcx AdtDef>,
-
-        // tracks ADT's previously encountered during search, so that
-        // we will not recur on them again.
-        seen: FxHashSet<hir::def_id::DefId>,
-    }
-
-    impl<'tcx> TypeVisitor<'tcx> for Search<'tcx> {
-        fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
-            debug!("Search visiting ty: {:?}", ty);
-
-            let (adt_def, substs) = match ty.kind {
-                ty::Adt(adt_def, substs) => (adt_def, substs),
-                ty::RawPtr(..) => {
-                    // `#[structural_match]` ignores substructure of
-                    // `*const _`/`*mut _`, so skip super_visit_with
-                    //
-                    // (But still tell caller to continue search.)
-                    return false;
-                }
-                ty::FnDef(..) | ty::FnPtr(..) => {
-                    // types of formals and return in `fn(_) -> _` are also irrelevant
-                    //
-                    // (But still tell caller to continue search.)
-                    return false;
-                }
-                ty::Array(_, n) if n.try_eval_usize(self.tcx, ty::ParamEnv::reveal_all()) == Some(0)
-                => {
-                    // rust-lang/rust#62336: ignore type of contents
-                    // for empty array.
-                    return false;
-                }
-                _ => {
-                    ty.super_visit_with(self);
-                    return false;
-                }
-            };
-
-            if !self.tcx.has_attr(adt_def.did, sym::structural_match) {
-                self.found = Some(&adt_def);
-                debug!("Search found adt_def: {:?}", adt_def);
-                return true // Halt visiting!
-            }
-
-            if !self.seen.insert(adt_def.did) {
-                debug!("Search already seen adt_def: {:?}", adt_def);
-                // let caller continue its search
-                return false;
-            }
-
-            // `#[structural_match]` does not care about the
-            // instantiation of the generics in an ADT (it
-            // instead looks directly at its fields outside
-            // this match), so we skip super_visit_with.
-            //
-            // (Must not recur on substs for `PhantomData<T>` cf
-            // rust-lang/rust#55028 and rust-lang/rust#55837; but also
-            // want to skip substs when only uses of generic are
-            // behind unsafe pointers `*const T`/`*mut T`.)
-
-            // even though we skip super_visit_with, we must recur on
-            // fields of ADT.
-            let tcx = self.tcx;
-            for field_ty in adt_def.all_fields().map(|field| field.ty(tcx, substs)) {
-                if field_ty.visit_with(self) {
-                    // found an ADT without `#[structural_match]`; halt visiting!
-                    assert!(self.found.is_some());
-                    return true;
-                }
-            }
-
-            // Even though we do not want to recur on substs, we do
-            // want our caller to continue its own search.
-            false
-        }
-    }
-}
-
 impl UserAnnotatedTyHelpers<'tcx> for PatCtxt<'_, 'tcx> {
     fn tcx(&self) -> TyCtxt<'tcx> {
         self.tcx
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/diagnostics.rs b/src/librustc_resolve/diagnostics.rs
index 5647d5b2794..7634093fbef 100644
--- a/src/librustc_resolve/diagnostics.rs
+++ b/src/librustc_resolve/diagnostics.rs
@@ -367,16 +367,6 @@ impl<'a> Resolver<'a> {
                     span, "`Self` in type parameter default".to_string());
                 err
             }
-            ResolutionError::ConstParamDependentOnTypeParam => {
-                let mut err = struct_span_err!(
-                    self.session,
-                    span,
-                    E0671,
-                    "const parameters cannot depend on type parameters"
-                );
-                err.span_label(span, format!("const parameter depends on type parameter"));
-                err
-            }
         }
     }
 
diff --git a/src/librustc_resolve/error_codes.rs b/src/librustc_resolve/error_codes.rs
index aea8db6f044..9883a64a1e8 100644
--- a/src/librustc_resolve/error_codes.rs
+++ b/src/librustc_resolve/error_codes.rs
@@ -1880,13 +1880,14 @@ fn main() {
 "##,
 
 E0671: r##"
+#### Note: this error code is no longer emitted by the compiler.
+
 Const parameters cannot depend on type parameters.
 The following is therefore invalid:
-```compile_fail,E0671
+```compile_fail,E0741
 #![feature(const_generics)]
 
-fn const_id<T, const N: T>() -> T { // error: const parameter
-                                    // depends on type parameter
+fn const_id<T, const N: T>() -> T { // error
     N
 }
 ```
diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs
index 73a282b1a0e..136ab1f0444 100644
--- a/src/librustc_resolve/late.rs
+++ b/src/librustc_resolve/late.rs
@@ -111,9 +111,6 @@ crate enum RibKind<'a> {
     /// from the default of a type parameter because they're not declared
     /// before said type parameter. Also see the `visit_generics` override.
     ForwardTyParamBanRibKind,
-
-    /// We forbid the use of type parameters as the types of const parameters.
-    TyParamAsConstParamTy,
 }
 
 impl RibKind<'_> {
@@ -128,8 +125,7 @@ impl RibKind<'_> {
             | MacroDefinition(_) => false,
             AssocItemRibKind
             | ItemRibKind(_)
-            | ForwardTyParamBanRibKind
-            | TyParamAsConstParamTy => true,
+            | ForwardTyParamBanRibKind => true,
         }
     }
 }
@@ -483,18 +479,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
             default_ban_rib.bindings.insert(Ident::with_dummy_span(kw::SelfUpper), Res::Err);
         }
 
-        // We also ban access to type parameters for use as the types of const parameters.
-        let mut const_ty_param_ban_rib = Rib::new(TyParamAsConstParamTy);
-        const_ty_param_ban_rib.bindings.extend(generics.params.iter()
-            .filter(|param| {
-                if let GenericParamKind::Type { .. } = param.kind {
-                    true
-                } else {
-                    false
-                }
-            })
-            .map(|param| (Ident::with_dummy_span(param.ident.name), Res::Err)));
-
         for param in &generics.params {
             match param.kind {
                 GenericParamKind::Lifetime { .. } => self.visit_generic_param(param),
@@ -513,15 +497,10 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
                     default_ban_rib.bindings.remove(&Ident::with_dummy_span(param.ident.name));
                 }
                 GenericParamKind::Const { ref ty } => {
-                    self.ribs[TypeNS].push(const_ty_param_ban_rib);
-
                     for bound in &param.bounds {
                         self.visit_param_bound(bound);
                     }
-
                     self.visit_ty(ty);
-
-                    const_ty_param_ban_rib = self.ribs[TypeNS].pop().unwrap();
                 }
             }
         }
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 17d8f0f211a..92392806347 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;
 
@@ -215,8 +215,6 @@ enum ResolutionError<'a> {
     ForwardDeclaredTyParam, // FIXME(const_generics:defaults)
     /// Error E0735: type parameters with a default cannot use `Self`
     SelfInTyParamDefault,
-    /// Error E0671: const parameter cannot depend on type parameter.
-    ConstParamDependentOnTypeParam,
 }
 
 // A minimal representation of a path segment. We use this in resolve because
@@ -829,14 +827,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 +866,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 +895,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 +913,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 +1012,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 +1020,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 +1084,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 +1147,6 @@ impl<'a> Resolver<'a> {
         Resolver {
             session,
 
-            cstore,
-
             definitions,
 
             // The outermost module has def ID 0; this is not reflected in the
@@ -1202,7 +1200,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 +1234,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()
     }
@@ -2169,15 +2203,6 @@ impl<'a> Resolver<'a> {
             return Res::Err;
         }
 
-        // An invalid use of a type parameter as the type of a const parameter.
-        if let TyParamAsConstParamTy = all_ribs[rib_index].kind {
-            if record_used {
-                self.report_error(span, ResolutionError::ConstParamDependentOnTypeParam);
-            }
-            assert_eq!(res, Res::Err);
-            return Res::Err;
-        }
-
         match res {
             Res::Local(_) => {
                 use ResolutionError::*;
@@ -2186,7 +2211,7 @@ impl<'a> Resolver<'a> {
                 for rib in ribs {
                     match rib.kind {
                         NormalRibKind | ModuleRibKind(..) | MacroDefinition(..) |
-                        ForwardTyParamBanRibKind | TyParamAsConstParamTy => {
+                        ForwardTyParamBanRibKind => {
                             // Nothing to do. Continue.
                         }
                         ItemRibKind(_) | FnItemRibKind | AssocItemRibKind => {
@@ -2220,7 +2245,7 @@ impl<'a> Resolver<'a> {
                     let has_generic_params = match rib.kind {
                         NormalRibKind | AssocItemRibKind |
                         ModuleRibKind(..) | MacroDefinition(..) | ForwardTyParamBanRibKind |
-                        ConstantItemRibKind | TyParamAsConstParamTy => {
+                        ConstantItemRibKind => {
                             // Nothing to do. Continue.
                             continue;
                         }
@@ -2808,6 +2833,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/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs
index 9baf06be3f6..59636d32bc0 100644
--- a/src/librustc_typeck/check/method/confirm.rs
+++ b/src/librustc_typeck/check/method/confirm.rs
@@ -141,14 +141,24 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
     ///////////////////////////////////////////////////////////////////////////
     // ADJUSTMENTS
 
-    fn adjust_self_ty(&mut self,
-                      unadjusted_self_ty: Ty<'tcx>,
-                      pick: &probe::Pick<'tcx>)
-                      -> Ty<'tcx> {
+    fn adjust_self_ty(
+        &mut self,
+        unadjusted_self_ty: Ty<'tcx>,
+        pick: &probe::Pick<'tcx>,
+    ) -> Ty<'tcx> {
         // Commit the autoderefs by calling `autoderef` again, but this
         // time writing the results into the various tables.
         let mut autoderef = self.autoderef(self.span, unadjusted_self_ty);
-        let (_, n) = autoderef.nth(pick.autoderefs).unwrap();
+        let (_, n) = match autoderef.nth(pick.autoderefs) {
+            Some(n) => n,
+            None => {
+                self.tcx.sess.delay_span_bug(
+                    syntax_pos::DUMMY_SP,
+                    &format!("failed autoderef {}", pick.autoderefs),
+                );
+                return self.tcx.types.err;
+            }
+        };
         assert_eq!(n, pick.autoderefs);
 
         let mut adjustments = autoderef.adjust_steps(self, Needs::None);
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index d1a8a6f6026..96a097695fa 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -2767,8 +2767,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         let mut opaque_types = self.opaque_types.borrow_mut();
         for (ty, decl) in opaque_type_map {
-            let old_value = opaque_types.insert(ty, decl);
-            assert!(old_value.is_none(), "instantiated twice: {:?}/{:?}", ty, decl);
+            let _ = opaque_types.insert(ty, decl);
         }
 
         value
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index d4c64512f98..00435d67184 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -1532,6 +1532,17 @@ pub fn checked_type_of(tcx: TyCtxt<'_>, def_id: DefId, fail: bool) -> Option<Ty<
                         );
                     };
                 }
+                if ty::search_for_structural_match_violation(tcx, ty).is_some() {
+                    struct_span_err!(
+                        tcx.sess,
+                        hir_ty.span,
+                        E0741,
+                        "the types of const generic parameters must derive `PartialEq` and `Eq`",
+                    ).span_label(
+                        hir_ty.span,
+                        format!("`{}` doesn't derive both `PartialEq` and `Eq`", ty),
+                    ).emit();
+                }
                 ty
             }
             x => {
diff --git a/src/librustc_typeck/error_codes.rs b/src/librustc_typeck/error_codes.rs
index 3d41c6e09c6..75b508a1bbf 100644
--- a/src/librustc_typeck/error_codes.rs
+++ b/src/librustc_typeck/error_codes.rs
@@ -5005,6 +5005,30 @@ the future, [RFC 2091] prohibits their implementation without a follow-up RFC.
 [RFC 2091]: https://github.com/rust-lang/rfcs/blob/master/text/2091-inline-semantic.md
 "##,
 
+E0741: r##"
+Only `structural_match` types (that is, types that derive `PartialEq` and `Eq`)
+may be used as the types of const generic parameters.
+
+```compile_fail,E0741
+#![feature(const_generics)]
+
+struct A;
+
+struct B<const X: A>; // error!
+```
+
+To fix this example, we derive `PartialEq` and `Eq`.
+
+```
+#![feature(const_generics)]
+
+#[derive(PartialEq, Eq)]
+struct A;
+
+struct B<const X: A>; // ok!
+```
+"##,
+
 ;
 //  E0035, merged into E0087/E0089
 //  E0036, merged into E0087/E0089
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/libstd/Cargo.toml b/src/libstd/Cargo.toml
index 5309af6f4c3..efe5c9d28f0 100644
--- a/src/libstd/Cargo.toml
+++ b/src/libstd/Cargo.toml
@@ -23,7 +23,7 @@ libc = { version = "0.2.51", default-features = false, features = ['rustc-dep-of
 compiler_builtins = { version = "0.1.16" }
 profiler_builtins = { path = "../libprofiler_builtins", optional = true }
 unwind = { path = "../libunwind" }
-hashbrown = { version = "0.6.1", default-features = false, features = ['rustc-dep-of-std'] }
+hashbrown = { version = "0.6.2", default-features = false, features = ['rustc-dep-of-std'] }
 
 [dependencies.backtrace_rs]
 package = "backtrace"
diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs
index 45d9f79c28f..37310f46f7e 100644
--- a/src/libsyntax_ext/format.rs
+++ b/src/libsyntax_ext/format.rs
@@ -278,7 +278,7 @@ impl<'a, 'b> Context<'a, 'b> {
     /// format string.
     fn report_invalid_references(&self, numbered_position_args: bool) {
         let mut e;
-        let sp = if self.is_literal {
+        let sp = if self.is_literal { // Point at the formatting arguments.
             MultiSpan::from_spans(self.arg_spans.clone())
         } else {
             MultiSpan::from_span(self.fmtsp)
@@ -304,6 +304,9 @@ impl<'a, 'b> Context<'a, 'b> {
                     self.describe_num_args(),
                 ),
             );
+            for arg in &self.args { // Point at the arguments that will be formatted.
+                e.span_label(arg.span, "");
+            }
         } else {
             let (mut refs, spans): (Vec<_>, Vec<_>) = refs.unzip();
             // Avoid `invalid reference to positional arguments 7 and 7 (there is 1 argument)`
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)
     }
 
diff --git a/src/test/rustdoc/const-generics/const-impl.rs b/src/test/rustdoc/const-generics/const-impl.rs
index 85ee6d3376b..2d506787b3b 100644
--- a/src/test/rustdoc/const-generics/const-impl.rs
+++ b/src/test/rustdoc/const-generics/const-impl.rs
@@ -4,6 +4,7 @@
 
 #![crate_name = "foo"]
 
+#[derive(PartialEq, Eq)]
 pub enum Order {
     Sorted,
     Unsorted,
diff --git a/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.rs b/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.rs
index af5e8f49754..78bd549ba79 100644
--- a/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.rs
+++ b/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.rs
@@ -1,6 +1,6 @@
 use std::marker::PhantomData;
 
 struct B<T, const N: T>(PhantomData<[T; N]>); //~ ERROR const generics are unstable
-//~^ ERROR const parameters cannot depend on type parameters
+//~^ ERROR the types of const generic parameters must derive `PartialEq` and `Eq`
 
 fn main() {}
diff --git a/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr b/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr
index c659074a091..a2872ab982d 100644
--- a/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr
+++ b/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr
@@ -1,9 +1,3 @@
-error[E0671]: const parameters cannot depend on type parameters
-  --> $DIR/const-param-type-depends-on-type-param-ungated.rs:3:22
-   |
-LL | struct B<T, const N: T>(PhantomData<[T; N]>);
-   |                      ^ const parameter depends on type parameter
-
 error[E0658]: const generics are unstable
   --> $DIR/const-param-type-depends-on-type-param-ungated.rs:3:19
    |
@@ -13,7 +7,13 @@ LL | struct B<T, const N: T>(PhantomData<[T; N]>);
    = note: for more information, see https://github.com/rust-lang/rust/issues/44580
    = help: add `#![feature(const_generics)]` to the crate attributes to enable
 
+error[E0741]: the types of const generic parameters must derive `PartialEq` and `Eq`
+  --> $DIR/const-param-type-depends-on-type-param-ungated.rs:3:22
+   |
+LL | struct B<T, const N: T>(PhantomData<[T; N]>);
+   |                      ^ `T` doesn't derive both `PartialEq` and `Eq`
+
 error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0658, E0671.
+Some errors have detailed explanations: E0658, E0741.
 For more information about an error, try `rustc --explain E0658`.
diff --git a/src/test/ui/const-generics/const-param-type-depends-on-type-param.rs b/src/test/ui/const-generics/const-param-type-depends-on-type-param.rs
index 28e0d6c2bb7..b76209571b0 100644
--- a/src/test/ui/const-generics/const-param-type-depends-on-type-param.rs
+++ b/src/test/ui/const-generics/const-param-type-depends-on-type-param.rs
@@ -7,7 +7,6 @@
 // details.
 
 pub struct Dependent<T, const X: T>([(); X]);
-//~^ ERROR const parameters cannot depend on type parameters
-//~^^ ERROR parameter `T` is never used
+//~^ ERROR the types of const generic parameters must derive `PartialEq` and `Eq`
 
 fn main() {}
diff --git a/src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr b/src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr
index db14f9c9bf6..c9d6db7e2c2 100644
--- a/src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr
+++ b/src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr
@@ -1,9 +1,3 @@
-error[E0671]: const parameters cannot depend on type parameters
-  --> $DIR/const-param-type-depends-on-type-param.rs:9:34
-   |
-LL | pub struct Dependent<T, const X: T>([(); X]);
-   |                                  ^ const parameter depends on type parameter
-
 warning: the feature `const_generics` is incomplete and may cause the compiler to crash
   --> $DIR/const-param-type-depends-on-type-param.rs:1:12
    |
@@ -12,15 +6,12 @@ LL | #![feature(const_generics)]
    |
    = note: `#[warn(incomplete_features)]` on by default
 
-error[E0392]: parameter `T` is never used
-  --> $DIR/const-param-type-depends-on-type-param.rs:9:22
+error[E0741]: the types of const generic parameters must derive `PartialEq` and `Eq`
+  --> $DIR/const-param-type-depends-on-type-param.rs:9:34
    |
 LL | pub struct Dependent<T, const X: T>([(); X]);
-   |                      ^ unused parameter
-   |
-   = help: consider removing `T`, referring to it in a field, or using a marker such as `std::marker::PhantomData`
+   |                                  ^ `T` doesn't derive both `PartialEq` and `Eq`
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0392, E0671.
-For more information about an error, try `rustc --explain E0392`.
+For more information about this error, try `rustc --explain E0741`.
diff --git a/src/test/ui/const-generics/forbid-non-structural_match-types.rs b/src/test/ui/const-generics/forbid-non-structural_match-types.rs
new file mode 100644
index 00000000000..7bc4f3986eb
--- /dev/null
+++ b/src/test/ui/const-generics/forbid-non-structural_match-types.rs
@@ -0,0 +1,13 @@
+#![feature(const_generics)]
+//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
+
+#[derive(PartialEq, Eq)]
+struct A;
+
+struct B<const X: A>; // ok
+
+struct C;
+
+struct D<const X: C>; //~ ERROR the types of const generic parameters must derive
+
+fn main() {}
diff --git a/src/test/ui/const-generics/forbid-non-structural_match-types.stderr b/src/test/ui/const-generics/forbid-non-structural_match-types.stderr
new file mode 100644
index 00000000000..0fd9e0599e8
--- /dev/null
+++ b/src/test/ui/const-generics/forbid-non-structural_match-types.stderr
@@ -0,0 +1,17 @@
+warning: the feature `const_generics` is incomplete and may cause the compiler to crash
+  --> $DIR/forbid-non-structural_match-types.rs:1:12
+   |
+LL | #![feature(const_generics)]
+   |            ^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0741]: the types of const generic parameters must derive `PartialEq` and `Eq`
+  --> $DIR/forbid-non-structural_match-types.rs:11:19
+   |
+LL | struct D<const X: C>;
+   |                   ^ `C` doesn't derive both `PartialEq` and `Eq`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0741`.
diff --git a/src/test/ui/fmt/format-string-error.rs b/src/test/ui/fmt/format-string-error.rs
index cca949aab63..691c06a2402 100644
--- a/src/test/ui/fmt/format-string-error.rs
+++ b/src/test/ui/fmt/format-string-error.rs
@@ -48,4 +48,6 @@ fn main() {
 
 "###);
     //~^^^ ERROR invalid format string: unmatched `}` found
+    println!("{} {} {}", 1, 2);
+    //~^ ERROR 3 positional arguments in format string, but there are 2 arguments
 }
diff --git a/src/test/ui/fmt/format-string-error.stderr b/src/test/ui/fmt/format-string-error.stderr
index 3dc122a7399..32119b18774 100644
--- a/src/test/ui/fmt/format-string-error.stderr
+++ b/src/test/ui/fmt/format-string-error.stderr
@@ -107,5 +107,11 @@ LL |         }
    |
    = note: if you intended to print `}`, you can escape it using `}}`
 
-error: aborting due to 12 previous errors
+error: 3 positional arguments in format string, but there are 2 arguments
+  --> $DIR/format-string-error.rs:51:15
+   |
+LL |     println!("{} {} {}", 1, 2);
+   |               ^^ ^^ ^^   -  -
+
+error: aborting due to 13 previous errors
 
diff --git a/src/test/ui/if/ifmt-bad-arg.stderr b/src/test/ui/if/ifmt-bad-arg.stderr
index 336ea2254bf..c58cbc31233 100644
--- a/src/test/ui/if/ifmt-bad-arg.stderr
+++ b/src/test/ui/if/ifmt-bad-arg.stderr
@@ -224,8 +224,9 @@ error: 4 positional arguments in format string, but there are 3 arguments
   --> $DIR/ifmt-bad-arg.rs:78:15
    |
 LL |     println!("{} {:.*} {}", 1, 3.2, 4);
-   |               ^^ ^^--^ ^^      --- this parameter corresponds to the precision flag
-   |                    |
+   |               ^^ ^^--^ ^^   -  ---  -
+   |                    |           |
+   |                    |           this parameter corresponds to the precision flag
    |                    this precision flag adds an extra required argument at position 1, which is why there are 4 arguments expected
    |
    = note: positional arguments are zero-based
@@ -235,8 +236,9 @@ error: 4 positional arguments in format string, but there are 3 arguments
   --> $DIR/ifmt-bad-arg.rs:81:15
    |
 LL |     println!("{} {:07$.*} {}", 1, 3.2, 4);
-   |               ^^ ^^^----^ ^^      --- this parameter corresponds to the precision flag
-   |                     | |
+   |               ^^ ^^^----^ ^^   -  ---  -
+   |                     | |           |
+   |                     | |           this parameter corresponds to the precision flag
    |                     | this precision flag adds an extra required argument at position 1, which is why there are 4 arguments expected
    |                     this width flag expects an `usize` argument at position 7, but there are 3 arguments
    |
diff --git a/src/test/ui/intrinsics/intrinsic-alignment.rs b/src/test/ui/intrinsics/intrinsic-alignment.rs
index 6a67d04a54c..02e3139d294 100644
--- a/src/test/ui/intrinsics/intrinsic-alignment.rs
+++ b/src/test/ui/intrinsics/intrinsic-alignment.rs
@@ -19,7 +19,8 @@ mod rusti {
           target_os = "macos",
           target_os = "netbsd",
           target_os = "openbsd",
-          target_os = "solaris"))]
+          target_os = "solaris",
+          target_os = "vxworks"))]
 mod m {
     #[main]
     #[cfg(target_arch = "x86")]
diff --git a/src/test/ui/issues/issue-65611.rs b/src/test/ui/issues/issue-65611.rs
new file mode 100644
index 00000000000..b74ee1b0c6e
--- /dev/null
+++ b/src/test/ui/issues/issue-65611.rs
@@ -0,0 +1,63 @@
+use std::mem::MaybeUninit;
+use std::ops::Deref;
+
+pub unsafe trait Array {
+    /// The array’s element type
+    type Item;
+    #[doc(hidden)]
+    /// The smallest index type that indexes the array.
+    type Index: Index;
+    #[doc(hidden)]
+    fn as_ptr(&self) -> *const Self::Item;
+    #[doc(hidden)]
+    fn as_mut_ptr(&mut self) -> *mut Self::Item;
+    #[doc(hidden)]
+    fn capacity() -> usize;
+}
+
+pub trait Index : PartialEq + Copy {
+    fn to_usize(self) -> usize;
+    fn from(usize) -> Self;
+}
+
+impl Index for usize {
+    fn to_usize(self) -> usize { self }
+    fn from(val: usize) -> Self {
+        val
+    }
+}
+
+unsafe impl<T> Array for [T; 1] {
+    type Item = T;
+    type Index = usize;
+    fn as_ptr(&self) -> *const T { self as *const _ as *const _ }
+    fn as_mut_ptr(&mut self) -> *mut T { self as *mut _ as *mut _}
+    fn capacity() -> usize { 1 }
+}
+
+impl<A: Array> Deref for ArrayVec<A> {
+    type Target = [A::Item];
+    #[inline]
+    fn deref(&self) -> &[A::Item] {
+        panic!()
+    }
+}
+
+pub struct ArrayVec<A: Array> {
+    xs: MaybeUninit<A>,
+    len: usize,
+}
+
+impl<A: Array> ArrayVec<A> {
+    pub fn new() -> ArrayVec<A> {
+        panic!()
+    }
+}
+
+fn main() {
+    let mut buffer = ArrayVec::new();
+    let x = buffer.last().unwrap().0.clone();
+    //~^ ERROR type annotations needed
+    //~| ERROR no field `0` on type `&_`
+    buffer.reverse();
+}
diff --git a/src/test/ui/issues/issue-65611.stderr b/src/test/ui/issues/issue-65611.stderr
new file mode 100644
index 00000000000..cb441c13c6b
--- /dev/null
+++ b/src/test/ui/issues/issue-65611.stderr
@@ -0,0 +1,18 @@
+error[E0282]: type annotations needed
+  --> $DIR/issue-65611.rs:59:20
+   |
+LL |     let x = buffer.last().unwrap().0.clone();
+   |                    ^^^^ cannot infer type for `T`
+   |
+   = note: type must be known at this point
+
+error[E0609]: no field `0` on type `&_`
+  --> $DIR/issue-65611.rs:59:36
+   |
+LL |     let x = buffer.last().unwrap().0.clone();
+   |                                    ^
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0282, E0609.
+For more information about an error, try `rustc --explain E0282`.
diff --git a/src/test/ui/signal-alternate-stack-cleanup.rs b/src/test/ui/signal-alternate-stack-cleanup.rs
index 787ff51799a..8fef66eac8d 100644
--- a/src/test/ui/signal-alternate-stack-cleanup.rs
+++ b/src/test/ui/signal-alternate-stack-cleanup.rs
@@ -7,6 +7,7 @@
 // ignore-wasm32-bare no libc
 // ignore-windows
 // ignore-sgx no libc
+// ignore-vxworks no SIGWINCH in user space
 
 #![feature(rustc_private)]
 extern crate libc;
diff --git a/src/test/ui/structs-enums/rec-align-u64.rs b/src/test/ui/structs-enums/rec-align-u64.rs
index c4e9e9ea5ee..680a690ba34 100644
--- a/src/test/ui/structs-enums/rec-align-u64.rs
+++ b/src/test/ui/structs-enums/rec-align-u64.rs
@@ -40,7 +40,8 @@ struct Outer {
           target_os = "macos",
           target_os = "netbsd",
           target_os = "openbsd",
-          target_os = "solaris"))]
+          target_os = "solaris",
+          target_os = "vxworks"))]
 mod m {
     #[cfg(target_arch = "x86")]
     pub mod m {
diff --git a/src/test/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs b/src/test/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs
new file mode 100644
index 00000000000..12eb75ae4c0
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs
@@ -0,0 +1,17 @@
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+
+type T = impl Sized;
+// The concrete type referred by impl-trait-type-alias(`T`) is guaranteed
+// to be the same as where it occurs, whereas `impl Trait`'s instance is location sensitive;
+// so difference assertion should not be declared on impl-trait-type-alias's instances.
+// for details, check RFC-2515:
+// https://github.com/rust-lang/rfcs/blob/master/text/2515-type_alias_impl_trait.md
+
+fn take(_: fn() -> T) {}
+
+fn main() {
+    take(|| {});
+    take(|| {});
+}
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject 3a9abe3f065554a7fbc59f440df2baba4a6e47e
+Subproject 3ba5f27170db10af7a92f2b682e049397197b8f