about summary refs log tree commit diff
path: root/src/librustc
diff options
context:
space:
mode:
Diffstat (limited to 'src/librustc')
-rw-r--r--src/librustc/Cargo.toml39
-rw-r--r--src/librustc/README.md3
-rw-r--r--src/librustc/arena.rs352
-rw-r--r--src/librustc/benches/lib.rs54
-rw-r--r--src/librustc/build.rs12
-rw-r--r--src/librustc/dep_graph/README.md4
-rw-r--r--src/librustc/dep_graph/debug.rs58
-rw-r--r--src/librustc/dep_graph/dep_node.rs533
-rw-r--r--src/librustc/dep_graph/graph.rs1198
-rw-r--r--src/librustc/dep_graph/mod.rs16
-rw-r--r--src/librustc/dep_graph/prev.rs55
-rw-r--r--src/librustc/dep_graph/query.rs74
-rw-r--r--src/librustc/dep_graph/safe.rs57
-rw-r--r--src/librustc/dep_graph/serialized.rs34
-rw-r--r--src/librustc/hir/exports.rs32
-rw-r--r--src/librustc/hir/map/blocks.rs262
-rw-r--r--src/librustc/hir/map/collector.rs603
-rw-r--r--src/librustc/hir/map/definitions.rs558
-rw-r--r--src/librustc/hir/map/hir_id_validator.rs175
-rw-r--r--src/librustc/hir/map/mod.rs1363
-rw-r--r--src/librustc/hir/mod.rs53
-rw-r--r--src/librustc/ich/hcx.rs281
-rw-r--r--src/librustc/ich/impls_hir.rs289
-rw-r--r--src/librustc/ich/impls_syntax.rs151
-rw-r--r--src/librustc/ich/impls_ty.rs210
-rw-r--r--src/librustc/ich/mod.rs25
-rw-r--r--src/librustc/infer/canonical.rs357
-rw-r--r--src/librustc/infer/mod.rs32
-rw-r--r--src/librustc/infer/unify_key.rs227
-rw-r--r--src/librustc/lib.rs93
-rw-r--r--src/librustc/lint.rs401
-rw-r--r--src/librustc/macros.rs216
-rw-r--r--src/librustc/middle/codegen_fn_attrs.rs124
-rw-r--r--src/librustc/middle/cstore.rs265
-rw-r--r--src/librustc/middle/dependency_format.rs28
-rw-r--r--src/librustc/middle/exported_symbols.rs55
-rw-r--r--src/librustc/middle/free_region.rs44
-rw-r--r--src/librustc/middle/lang_items.rs65
-rw-r--r--src/librustc/middle/mod.rs35
-rw-r--r--src/librustc/middle/privacy.rs65
-rw-r--r--src/librustc/middle/recursion_limit.rs67
-rw-r--r--src/librustc/middle/region.rs669
-rw-r--r--src/librustc/middle/resolve_lifetime.rs86
-rw-r--r--src/librustc/middle/stability.rs413
-rw-r--r--src/librustc/mir/cache.rs271
-rw-r--r--src/librustc/mir/interpret/allocation.rs906
-rw-r--r--src/librustc/mir/interpret/error.rs614
-rw-r--r--src/librustc/mir/interpret/mod.rs565
-rw-r--r--src/librustc/mir/interpret/pointer.rs232
-rw-r--r--src/librustc/mir/interpret/queries.rs78
-rw-r--r--src/librustc/mir/interpret/value.rs679
-rw-r--r--src/librustc/mir/mod.rs2995
-rw-r--r--src/librustc/mir/mono.rs494
-rw-r--r--src/librustc/mir/query.rs229
-rw-r--r--src/librustc/mir/tcx.rs291
-rw-r--r--src/librustc/mir/traversal.rs294
-rw-r--r--src/librustc/mir/visit.rs1177
-rw-r--r--src/librustc/query/mod.rs1261
-rw-r--r--src/librustc/tests.rs13
-rw-r--r--src/librustc/traits/mod.rs871
-rw-r--r--src/librustc/traits/query.rs332
-rw-r--r--src/librustc/traits/select.rs290
-rw-r--r--src/librustc/traits/specialization_graph.rs202
-rw-r--r--src/librustc/traits/structural_impls.rs712
-rw-r--r--src/librustc/ty/_match.rs120
-rw-r--r--src/librustc/ty/adjustment.rs194
-rw-r--r--src/librustc/ty/binding.rs22
-rw-r--r--src/librustc/ty/cast.rs67
-rw-r--r--src/librustc/ty/codec.rs494
-rw-r--r--src/librustc/ty/context.rs2796
-rw-r--r--src/librustc/ty/diagnostics.rs65
-rw-r--r--src/librustc/ty/erase_regions.rs68
-rw-r--r--src/librustc/ty/error.rs495
-rw-r--r--src/librustc/ty/fast_reject.rs174
-rw-r--r--src/librustc/ty/flags.rs264
-rw-r--r--src/librustc/ty/fold.rs1002
-rw-r--r--src/librustc/ty/free_region_map.rs133
-rw-r--r--src/librustc/ty/inhabitedness/def_id_forest.rs113
-rw-r--r--src/librustc/ty/inhabitedness/mod.rs206
-rw-r--r--src/librustc/ty/instance.rs428
-rw-r--r--src/librustc/ty/layout.rs2744
-rw-r--r--src/librustc/ty/mod.rs3169
-rw-r--r--src/librustc/ty/normalize_erasing_regions.rs102
-rw-r--r--src/librustc/ty/outlives.rs178
-rw-r--r--src/librustc/ty/print/mod.rs347
-rw-r--r--src/librustc/ty/print/obsolete.rs250
-rw-r--r--src/librustc/ty/print/pretty.rs1853
-rw-r--r--src/librustc/ty/query/README.md3
-rw-r--r--src/librustc/ty/query/caches.rs112
-rw-r--r--src/librustc/ty/query/config.rs95
-rw-r--r--src/librustc/ty/query/job.rs589
-rw-r--r--src/librustc/ty/query/keys.rs287
-rw-r--r--src/librustc/ty/query/mod.rs112
-rw-r--r--src/librustc/ty/query/on_disk_cache.rs1057
-rw-r--r--src/librustc/ty/query/plumbing.rs1266
-rw-r--r--src/librustc/ty/query/profiling_support.rs218
-rw-r--r--src/librustc/ty/query/stats.rs139
-rw-r--r--src/librustc/ty/query/values.rs32
-rw-r--r--src/librustc/ty/relate.rs990
-rw-r--r--src/librustc/ty/steal.rs44
-rw-r--r--src/librustc/ty/structural_impls.rs1084
-rw-r--r--src/librustc/ty/sty.rs2602
-rw-r--r--src/librustc/ty/subst.rs724
-rw-r--r--src/librustc/ty/trait_def.rs191
-rw-r--r--src/librustc/ty/util.rs1096
-rw-r--r--src/librustc/ty/walk.rs138
-rw-r--r--src/librustc/util/bug.rs41
-rw-r--r--src/librustc/util/common.rs71
-rw-r--r--src/librustc/util/common/tests.rs14
109 files changed, 0 insertions, 48428 deletions
diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml
deleted file mode 100644
index af2be30cc0a..00000000000
--- a/src/librustc/Cargo.toml
+++ /dev/null
@@ -1,39 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "rustc"
-version = "0.0.0"
-edition = "2018"
-
-[lib]
-name = "rustc"
-path = "lib.rs"
-doctest = false
-
-[dependencies]
-arena = { path = "../libarena" }
-bitflags = "1.2.1"
-jobserver = "0.1"
-scoped-tls = "1.0"
-log = { version = "0.4", features = ["release_max_level_info", "std"] }
-rustc-rayon = "0.3.0"
-rustc-rayon-core = "0.3.0"
-polonius-engine = "0.11.0"
-rustc_apfloat = { path = "../librustc_apfloat" }
-rustc_attr = { path = "../librustc_attr" }
-rustc_feature = { path = "../librustc_feature" }
-rustc_hir = { path = "../librustc_hir" }
-rustc_target = { path = "../librustc_target" }
-rustc_macros = { path = "../librustc_macros" }
-rustc_data_structures = { path = "../librustc_data_structures" }
-rustc_errors = { path = "../librustc_errors" }
-rustc_index = { path = "../librustc_index" }
-rustc_serialize = { path = "../libserialize", package = "serialize" }
-syntax = { path = "../libsyntax" }
-rustc_span = { path = "../librustc_span" }
-backtrace = "0.3.40"
-parking_lot = "0.9"
-byteorder = { version = "1.3" }
-chalk-engine = { version = "0.9.0", default-features=false }
-smallvec = { version = "1.0", features = ["union", "may_dangle"] }
-measureme = "0.7.1"
-rustc_session = { path = "../librustc_session" }
diff --git a/src/librustc/README.md b/src/librustc/README.md
deleted file mode 100644
index c0e5c542bdc..00000000000
--- a/src/librustc/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-For more information about how rustc works, see the [rustc guide].
-
-[rustc guide]: https://rust-lang.github.io/rustc-guide/
diff --git a/src/librustc/arena.rs b/src/librustc/arena.rs
deleted file mode 100644
index ca55d410ceb..00000000000
--- a/src/librustc/arena.rs
+++ /dev/null
@@ -1,352 +0,0 @@
-use arena::{DroplessArena, TypedArena};
-use smallvec::SmallVec;
-use std::cell::RefCell;
-use std::marker::PhantomData;
-use std::mem;
-use std::ptr;
-use std::slice;
-
-/// This declares a list of types which can be allocated by `Arena`.
-///
-/// The `few` modifier will cause allocation to use the shared arena and recording the destructor.
-/// This is faster and more memory efficient if there's only a few allocations of the type.
-/// Leaving `few` out will cause the type to get its own dedicated `TypedArena` which is
-/// faster and more memory efficient if there is lots of allocations.
-///
-/// Specifying the `decode` modifier will add decode impls for &T and &[T] where T is the type
-/// listed. These impls will appear in the implement_ty_decoder! macro.
-#[macro_export]
-macro_rules! arena_types {
-    ($macro:path, $args:tt, $tcx:lifetime) => (
-        $macro!($args, [
-            [] layouts: rustc::ty::layout::LayoutDetails,
-            [] generics: rustc::ty::Generics,
-            [] trait_def: rustc::ty::TraitDef,
-            [] adt_def: rustc::ty::AdtDef,
-            [] steal_mir: rustc::ty::steal::Steal<rustc::mir::BodyAndCache<$tcx>>,
-            [] mir: rustc::mir::BodyAndCache<$tcx>,
-            [] steal_promoted: rustc::ty::steal::Steal<
-                rustc_index::vec::IndexVec<
-                    rustc::mir::Promoted,
-                    rustc::mir::BodyAndCache<$tcx>
-                >
-            >,
-            [] promoted: rustc_index::vec::IndexVec<
-                rustc::mir::Promoted,
-                rustc::mir::BodyAndCache<$tcx>
-            >,
-            [decode] tables: rustc::ty::TypeckTables<$tcx>,
-            [decode] borrowck_result: rustc::mir::BorrowCheckResult<$tcx>,
-            [] const_allocs: rustc::mir::interpret::Allocation,
-            [] vtable_method: Option<(
-                rustc_hir::def_id::DefId,
-                rustc::ty::subst::SubstsRef<$tcx>
-            )>,
-            [few, decode] mir_keys: rustc_hir::def_id::DefIdSet,
-            [decode] specialization_graph: rustc::traits::specialization_graph::Graph,
-            [] region_scope_tree: rustc::middle::region::ScopeTree,
-            [] item_local_set: rustc_hir::ItemLocalSet,
-            [decode] mir_const_qualif: rustc_index::bit_set::BitSet<rustc::mir::Local>,
-            [] trait_impls_of: rustc::ty::trait_def::TraitImpls,
-            [] associated_items: rustc::ty::AssociatedItems,
-            [] dropck_outlives:
-                rustc::infer::canonical::Canonical<'tcx,
-                    rustc::infer::canonical::QueryResponse<'tcx,
-                        rustc::traits::query::DropckOutlivesResult<'tcx>
-                    >
-                >,
-            [] normalize_projection_ty:
-                rustc::infer::canonical::Canonical<'tcx,
-                    rustc::infer::canonical::QueryResponse<'tcx,
-                        rustc::traits::query::NormalizationResult<'tcx>
-                    >
-                >,
-            [] implied_outlives_bounds:
-                rustc::infer::canonical::Canonical<'tcx,
-                    rustc::infer::canonical::QueryResponse<'tcx,
-                        Vec<rustc::traits::query::OutlivesBound<'tcx>>
-                    >
-                >,
-            [] type_op_subtype:
-                rustc::infer::canonical::Canonical<'tcx,
-                    rustc::infer::canonical::QueryResponse<'tcx, ()>
-                >,
-            [] type_op_normalize_poly_fn_sig:
-                rustc::infer::canonical::Canonical<'tcx,
-                    rustc::infer::canonical::QueryResponse<'tcx, rustc::ty::PolyFnSig<'tcx>>
-                >,
-            [] type_op_normalize_fn_sig:
-                rustc::infer::canonical::Canonical<'tcx,
-                    rustc::infer::canonical::QueryResponse<'tcx, rustc::ty::FnSig<'tcx>>
-                >,
-            [] type_op_normalize_predicate:
-                rustc::infer::canonical::Canonical<'tcx,
-                    rustc::infer::canonical::QueryResponse<'tcx, rustc::ty::Predicate<'tcx>>
-                >,
-            [] type_op_normalize_ty:
-                rustc::infer::canonical::Canonical<'tcx,
-                    rustc::infer::canonical::QueryResponse<'tcx, rustc::ty::Ty<'tcx>>
-                >,
-            [few] crate_inherent_impls: rustc::ty::CrateInherentImpls,
-            [few] upstream_monomorphizations:
-                rustc_hir::def_id::DefIdMap<
-                    rustc_data_structures::fx::FxHashMap<
-                        rustc::ty::subst::SubstsRef<'tcx>,
-                        rustc_hir::def_id::CrateNum
-                    >
-                >,
-            [few] diagnostic_items: rustc_data_structures::fx::FxHashMap<
-                rustc_span::symbol::Symbol,
-                rustc_hir::def_id::DefId,
-            >,
-            [few] resolve_lifetimes: rustc::middle::resolve_lifetime::ResolveLifetimes,
-            [few] lint_levels: rustc::lint::LintLevelMap,
-            [few] stability_index: rustc::middle::stability::Index<'tcx>,
-            [few] features: rustc_feature::Features,
-            [few] all_traits: Vec<rustc_hir::def_id::DefId>,
-            [few] privacy_access_levels: rustc::middle::privacy::AccessLevels,
-            [few] target_features_whitelist: rustc_data_structures::fx::FxHashMap<
-                String,
-                Option<rustc_span::symbol::Symbol>
-            >,
-            [few] wasm_import_module_map: rustc_data_structures::fx::FxHashMap<
-                rustc_hir::def_id::DefId,
-                String
-            >,
-            [few] get_lib_features: rustc::middle::lib_features::LibFeatures,
-            [few] defined_lib_features: rustc::middle::lang_items::LanguageItems,
-            [few] visible_parent_map: rustc_hir::def_id::DefIdMap<rustc_hir::def_id::DefId>,
-            [few] foreign_module: rustc::middle::cstore::ForeignModule,
-            [few] foreign_modules: Vec<rustc::middle::cstore::ForeignModule>,
-            [few] reachable_non_generics: rustc_hir::def_id::DefIdMap<
-                rustc::middle::exported_symbols::SymbolExportLevel
-            >,
-            [few] crate_variances: rustc::ty::CrateVariancesMap<'tcx>,
-            [few] inferred_outlives_crate: rustc::ty::CratePredicatesMap<'tcx>,
-            [] upvars: rustc_data_structures::fx::FxIndexMap<rustc_hir::HirId, rustc_hir::Upvar>,
-
-            // Interned types
-            [] tys: rustc::ty::TyS<$tcx>,
-
-            // HIR types
-            [few] hir_krate: rustc_hir::Crate<$tcx>,
-            [] arm: rustc_hir::Arm<$tcx>,
-            [] attribute: syntax::ast::Attribute,
-            [] block: rustc_hir::Block<$tcx>,
-            [] bare_fn_ty: rustc_hir::BareFnTy<$tcx>,
-            [few] global_asm: rustc_hir::GlobalAsm,
-            [] generic_arg: rustc_hir::GenericArg<$tcx>,
-            [] generic_args: rustc_hir::GenericArgs<$tcx>,
-            [] generic_bound: rustc_hir::GenericBound<$tcx>,
-            [] generic_param: rustc_hir::GenericParam<$tcx>,
-            [] expr: rustc_hir::Expr<$tcx>,
-            [] field: rustc_hir::Field<$tcx>,
-            [] field_pat: rustc_hir::FieldPat<$tcx>,
-            [] fn_decl: rustc_hir::FnDecl<$tcx>,
-            [] foreign_item: rustc_hir::ForeignItem<$tcx>,
-            [] impl_item_ref: rustc_hir::ImplItemRef<$tcx>,
-            [] inline_asm: rustc_hir::InlineAsm<$tcx>,
-            [] local: rustc_hir::Local<$tcx>,
-            [few] macro_def: rustc_hir::MacroDef<$tcx>,
-            [] param: rustc_hir::Param<$tcx>,
-            [] pat: rustc_hir::Pat<$tcx>,
-            [] path: rustc_hir::Path<$tcx>,
-            [] path_segment: rustc_hir::PathSegment<$tcx>,
-            [] poly_trait_ref: rustc_hir::PolyTraitRef<$tcx>,
-            [] qpath: rustc_hir::QPath<$tcx>,
-            [] stmt: rustc_hir::Stmt<$tcx>,
-            [] struct_field: rustc_hir::StructField<$tcx>,
-            [] trait_item_ref: rustc_hir::TraitItemRef,
-            [] ty: rustc_hir::Ty<$tcx>,
-            [] type_binding: rustc_hir::TypeBinding<$tcx>,
-            [] variant: rustc_hir::Variant<$tcx>,
-            [] where_predicate: rustc_hir::WherePredicate<$tcx>,
-        ], $tcx);
-    )
-}
-
-macro_rules! arena_for_type {
-    ([][$ty:ty]) => {
-        TypedArena<$ty>
-    };
-    ([few $(, $attrs:ident)*][$ty:ty]) => {
-        PhantomData<$ty>
-    };
-    ([$ignore:ident $(, $attrs:ident)*]$args:tt) => {
-        arena_for_type!([$($attrs),*]$args)
-    };
-}
-
-macro_rules! declare_arena {
-    ([], [$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) => {
-        #[derive(Default)]
-        pub struct Arena<$tcx> {
-            pub dropless: DroplessArena,
-            drop: DropArena,
-            $($name: arena_for_type!($a[$ty]),)*
-        }
-    }
-}
-
-macro_rules! which_arena_for_type {
-    ([][$arena:expr]) => {
-        Some($arena)
-    };
-    ([few$(, $attrs:ident)*][$arena:expr]) => {
-        None
-    };
-    ([$ignore:ident$(, $attrs:ident)*]$args:tt) => {
-        which_arena_for_type!([$($attrs),*]$args)
-    };
-}
-
-macro_rules! impl_arena_allocatable {
-    ([], [$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) => {
-        $(
-            impl ArenaAllocatable for $ty {}
-            unsafe impl<$tcx> ArenaField<$tcx> for $ty {
-                #[inline]
-                fn arena<'a>(_arena: &'a Arena<$tcx>) -> Option<&'a TypedArena<Self>> {
-                    which_arena_for_type!($a[&_arena.$name])
-                }
-            }
-        )*
-    }
-}
-
-arena_types!(declare_arena, [], 'tcx);
-
-arena_types!(impl_arena_allocatable, [], 'tcx);
-
-#[marker]
-pub trait ArenaAllocatable {}
-
-impl<T: Copy> ArenaAllocatable for T {}
-
-unsafe trait ArenaField<'tcx>: Sized {
-    /// Returns a specific arena to allocate from.
-    /// If `None` is returned, the `DropArena` will be used.
-    fn arena<'a>(arena: &'a Arena<'tcx>) -> Option<&'a TypedArena<Self>>;
-}
-
-unsafe impl<'tcx, T> ArenaField<'tcx> for T {
-    #[inline]
-    default fn arena<'a>(_: &'a Arena<'tcx>) -> Option<&'a TypedArena<Self>> {
-        panic!()
-    }
-}
-
-impl<'tcx> Arena<'tcx> {
-    #[inline]
-    pub fn alloc<T: ArenaAllocatable>(&self, value: T) -> &mut T {
-        if !mem::needs_drop::<T>() {
-            return self.dropless.alloc(value);
-        }
-        match <T as ArenaField<'tcx>>::arena(self) {
-            Some(arena) => arena.alloc(value),
-            None => unsafe { self.drop.alloc(value) },
-        }
-    }
-
-    #[inline]
-    pub fn alloc_slice<T: Copy>(&self, value: &[T]) -> &mut [T] {
-        if value.len() == 0 {
-            return &mut [];
-        }
-        self.dropless.alloc_slice(value)
-    }
-
-    pub fn alloc_from_iter<T: ArenaAllocatable, I: IntoIterator<Item = T>>(
-        &'a self,
-        iter: I,
-    ) -> &'a mut [T] {
-        if !mem::needs_drop::<T>() {
-            return self.dropless.alloc_from_iter(iter);
-        }
-        match <T as ArenaField<'tcx>>::arena(self) {
-            Some(arena) => arena.alloc_from_iter(iter),
-            None => unsafe { self.drop.alloc_from_iter(iter) },
-        }
-    }
-}
-
-/// Calls the destructor for an object when dropped.
-struct DropType {
-    drop_fn: unsafe fn(*mut u8),
-    obj: *mut u8,
-}
-
-unsafe fn drop_for_type<T>(to_drop: *mut u8) {
-    std::ptr::drop_in_place(to_drop as *mut T)
-}
-
-impl Drop for DropType {
-    fn drop(&mut self) {
-        unsafe { (self.drop_fn)(self.obj) }
-    }
-}
-
-/// An arena which can be used to allocate any type.
-/// Allocating in this arena is unsafe since the type system
-/// doesn't know which types it contains. In order to
-/// allocate safely, you must store a PhantomData<T>
-/// alongside this arena for each type T you allocate.
-#[derive(Default)]
-struct DropArena {
-    /// A list of destructors to run when the arena drops.
-    /// Ordered so `destructors` gets dropped before the arena
-    /// since its destructor can reference memory in the arena.
-    destructors: RefCell<Vec<DropType>>,
-    arena: DroplessArena,
-}
-
-impl DropArena {
-    #[inline]
-    unsafe fn alloc<T>(&self, object: T) -> &mut T {
-        let mem =
-            self.arena.alloc_raw(mem::size_of::<T>(), mem::align_of::<T>()) as *mut _ as *mut T;
-        // Write into uninitialized memory.
-        ptr::write(mem, object);
-        let result = &mut *mem;
-        // Record the destructor after doing the allocation as that may panic
-        // and would cause `object`'s destuctor to run twice if it was recorded before
-        self.destructors
-            .borrow_mut()
-            .push(DropType { drop_fn: drop_for_type::<T>, obj: result as *mut T as *mut u8 });
-        result
-    }
-
-    #[inline]
-    unsafe fn alloc_from_iter<T, I: IntoIterator<Item = T>>(&self, iter: I) -> &mut [T] {
-        let mut vec: SmallVec<[_; 8]> = iter.into_iter().collect();
-        if vec.is_empty() {
-            return &mut [];
-        }
-        let len = vec.len();
-
-        let start_ptr = self
-            .arena
-            .alloc_raw(len.checked_mul(mem::size_of::<T>()).unwrap(), mem::align_of::<T>())
-            as *mut _ as *mut T;
-
-        let mut destructors = self.destructors.borrow_mut();
-        // Reserve space for the destructors so we can't panic while adding them
-        destructors.reserve(len);
-
-        // Move the content to the arena by copying it and then forgetting
-        // the content of the SmallVec
-        vec.as_ptr().copy_to_nonoverlapping(start_ptr, len);
-        mem::forget(vec.drain(..));
-
-        // Record the destructors after doing the allocation as that may panic
-        // and would cause `object`'s destuctor to run twice if it was recorded before
-        for i in 0..len {
-            destructors.push(DropType {
-                drop_fn: drop_for_type::<T>,
-                obj: start_ptr.offset(i as isize) as *mut u8,
-            });
-        }
-
-        slice::from_raw_parts_mut(start_ptr, len)
-    }
-}
diff --git a/src/librustc/benches/lib.rs b/src/librustc/benches/lib.rs
deleted file mode 100644
index 237751bcbd7..00000000000
--- a/src/librustc/benches/lib.rs
+++ /dev/null
@@ -1,54 +0,0 @@
-#![feature(test)]
-
-extern crate test;
-
-use test::Bencher;
-
-// Static/dynamic method dispatch
-
-struct Struct {
-    field: isize,
-}
-
-trait Trait {
-    fn method(&self) -> isize;
-}
-
-impl Trait for Struct {
-    fn method(&self) -> isize {
-        self.field
-    }
-}
-
-#[bench]
-fn trait_vtable_method_call(b: &mut Bencher) {
-    let s = Struct { field: 10 };
-    let t = &s as &dyn Trait;
-    b.iter(|| t.method());
-}
-
-#[bench]
-fn trait_static_method_call(b: &mut Bencher) {
-    let s = Struct { field: 10 };
-    b.iter(|| s.method());
-}
-
-// Overhead of various match forms
-
-#[bench]
-fn option_some(b: &mut Bencher) {
-    let x = Some(10);
-    b.iter(|| match x {
-        Some(y) => y,
-        None => 11,
-    });
-}
-
-#[bench]
-fn vec_pattern(b: &mut Bencher) {
-    let x = [1, 2, 3, 4, 5, 6];
-    b.iter(|| match x {
-        [1, 2, 3, ..] => 10,
-        _ => 11,
-    });
-}
diff --git a/src/librustc/build.rs b/src/librustc/build.rs
deleted file mode 100644
index af7723aea34..00000000000
--- a/src/librustc/build.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-use std::env;
-
-fn main() {
-    println!("cargo:rerun-if-changed=build.rs");
-    println!("cargo:rerun-if-env-changed=CFG_LIBDIR_RELATIVE");
-    println!("cargo:rerun-if-env-changed=CFG_COMPILER_HOST_TRIPLE");
-    println!("cargo:rerun-if-env-changed=RUSTC_VERIFY_LLVM_IR");
-
-    if env::var_os("RUSTC_VERIFY_LLVM_IR").is_some() {
-        println!("cargo:rustc-cfg=always_verify_llvm_ir");
-    }
-}
diff --git a/src/librustc/dep_graph/README.md b/src/librustc/dep_graph/README.md
deleted file mode 100644
index 91a06e452e5..00000000000
--- a/src/librustc/dep_graph/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-To learn more about how dependency tracking works in rustc, see the [rustc
-guide].
-
-[rustc guide]: https://rust-lang.github.io/rustc-guide/query.html
diff --git a/src/librustc/dep_graph/debug.rs b/src/librustc/dep_graph/debug.rs
deleted file mode 100644
index d44c54593a6..00000000000
--- a/src/librustc/dep_graph/debug.rs
+++ /dev/null
@@ -1,58 +0,0 @@
-//! Code for debugging the dep-graph.
-
-use super::dep_node::DepNode;
-use std::error::Error;
-
-/// A dep-node filter goes from a user-defined string to a query over
-/// nodes. Right now the format is like this:
-///
-///     x & y & z
-///
-/// where the format-string of the dep-node must contain `x`, `y`, and
-/// `z`.
-#[derive(Debug)]
-pub struct DepNodeFilter {
-    text: String,
-}
-
-impl DepNodeFilter {
-    pub fn new(text: &str) -> Self {
-        DepNodeFilter { text: text.trim().to_string() }
-    }
-
-    /// Returns `true` if all nodes always pass the filter.
-    pub fn accepts_all(&self) -> bool {
-        self.text.is_empty()
-    }
-
-    /// Tests whether `node` meets the filter, returning true if so.
-    pub fn test(&self, node: &DepNode) -> bool {
-        let debug_str = format!("{:?}", node);
-        self.text.split('&').map(|s| s.trim()).all(|f| debug_str.contains(f))
-    }
-}
-
-/// A filter like `F -> G` where `F` and `G` are valid dep-node
-/// filters. This can be used to test the source/target independently.
-pub struct EdgeFilter {
-    pub source: DepNodeFilter,
-    pub target: DepNodeFilter,
-}
-
-impl EdgeFilter {
-    pub fn new(test: &str) -> Result<EdgeFilter, Box<dyn Error>> {
-        let parts: Vec<_> = test.split("->").collect();
-        if parts.len() != 2 {
-            Err(format!("expected a filter like `a&b -> c&d`, not `{}`", test).into())
-        } else {
-            Ok(EdgeFilter {
-                source: DepNodeFilter::new(parts[0]),
-                target: DepNodeFilter::new(parts[1]),
-            })
-        }
-    }
-
-    pub fn test(&self, source: &DepNode, target: &DepNode) -> bool {
-        self.source.test(source) && self.target.test(target)
-    }
-}
diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs
deleted file mode 100644
index eb7e2871bfc..00000000000
--- a/src/librustc/dep_graph/dep_node.rs
+++ /dev/null
@@ -1,533 +0,0 @@
-//! This module defines the `DepNode` type which the compiler uses to represent
-//! nodes in the dependency graph. A `DepNode` consists of a `DepKind` (which
-//! specifies the kind of thing it represents, like a piece of HIR, MIR, etc)
-//! and a `Fingerprint`, a 128 bit hash value the exact meaning of which
-//! depends on the node's `DepKind`. Together, the kind and the fingerprint
-//! fully identify a dependency node, even across multiple compilation sessions.
-//! In other words, the value of the fingerprint does not depend on anything
-//! that is specific to a given compilation session, like an unpredictable
-//! interning key (e.g., NodeId, DefId, Symbol) or the numeric value of a
-//! pointer. The concept behind this could be compared to how git commit hashes
-//! uniquely identify a given commit and has a few advantages:
-//!
-//! * A `DepNode` can simply be serialized to disk and loaded in another session
-//!   without the need to do any "rebasing (like we have to do for Spans and
-//!   NodeIds) or "retracing" like we had to do for `DefId` in earlier
-//!   implementations of the dependency graph.
-//! * A `Fingerprint` is just a bunch of bits, which allows `DepNode` to
-//!   implement `Copy`, `Sync`, `Send`, `Freeze`, etc.
-//! * Since we just have a bit pattern, `DepNode` can be mapped from disk into
-//!   memory without any post-processing (e.g., "abomination-style" pointer
-//!   reconstruction).
-//! * Because a `DepNode` is self-contained, we can instantiate `DepNodes` that
-//!   refer to things that do not exist anymore. In previous implementations
-//!   `DepNode` contained a `DefId`. A `DepNode` referring to something that
-//!   had been removed between the previous and the current compilation session
-//!   could not be instantiated because the current compilation session
-//!   contained no `DefId` for thing that had been removed.
-//!
-//! `DepNode` definition happens in the `define_dep_nodes!()` macro. This macro
-//! defines the `DepKind` enum and a corresponding `DepConstructor` enum. The
-//! `DepConstructor` enum links a `DepKind` to the parameters that are needed at
-//! runtime in order to construct a valid `DepNode` fingerprint.
-//!
-//! Because the macro sees what parameters a given `DepKind` requires, it can
-//! "infer" some properties for each kind of `DepNode`:
-//!
-//! * Whether a `DepNode` of a given kind has any parameters at all. Some
-//!   `DepNode`s, like `AllLocalTraitImpls`, represent global concepts with only one value.
-//! * Whether it is possible, in principle, to reconstruct a query key from a
-//!   given `DepNode`. Many `DepKind`s only require a single `DefId` parameter,
-//!   in which case it is possible to map the node's fingerprint back to the
-//!   `DefId` it was computed from. In other cases, too much information gets
-//!   lost during fingerprint computation.
-//!
-//! The `DepConstructor` enum, together with `DepNode::new()` ensures that only
-//! valid `DepNode` instances can be constructed. For example, the API does not
-//! allow for constructing parameterless `DepNode`s with anything other
-//! than a zeroed out fingerprint. More generally speaking, it relieves the
-//! user of the `DepNode` API of having to know how to compute the expected
-//! fingerprint for a given set of node parameters.
-
-use crate::hir::map::DefPathHash;
-use crate::ich::{Fingerprint, StableHashingContext};
-use crate::mir;
-use crate::mir::interpret::{GlobalId, LitToConstInput};
-use crate::traits;
-use crate::traits::query::{
-    CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal,
-    CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpEqGoal, CanonicalTypeOpNormalizeGoal,
-    CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpSubtypeGoal,
-};
-use crate::ty::subst::SubstsRef;
-use crate::ty::{self, ParamEnvAnd, Ty, TyCtxt};
-
-use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
-use rustc_hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX};
-use rustc_hir::HirId;
-use rustc_span::symbol::Symbol;
-use std::fmt;
-use std::hash::Hash;
-
-// erase!() just makes tokens go away. It's used to specify which macro argument
-// is repeated (i.e., which sub-expression of the macro we are in) but don't need
-// to actually use any of the arguments.
-macro_rules! erase {
-    ($x:tt) => {{}};
-}
-
-macro_rules! is_anon_attr {
-    (anon) => {
-        true
-    };
-    ($attr:ident) => {
-        false
-    };
-}
-
-macro_rules! is_eval_always_attr {
-    (eval_always) => {
-        true
-    };
-    ($attr:ident) => {
-        false
-    };
-}
-
-macro_rules! contains_anon_attr {
-    ($($attr:ident $(($($attr_args:tt)*))* ),*) => ({$(is_anon_attr!($attr) | )* false});
-}
-
-macro_rules! contains_eval_always_attr {
-    ($($attr:ident $(($($attr_args:tt)*))* ),*) => ({$(is_eval_always_attr!($attr) | )* false});
-}
-
-macro_rules! define_dep_nodes {
-    (<$tcx:tt>
-    $(
-        [$($attrs:tt)*]
-        $variant:ident $(( $tuple_arg_ty:ty $(,)? ))*
-      ,)*
-    ) => (
-        #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash,
-                 RustcEncodable, RustcDecodable)]
-        pub enum DepKind {
-            $($variant),*
-        }
-
-        impl DepKind {
-            #[allow(unreachable_code)]
-            pub fn can_reconstruct_query_key<$tcx>(&self) -> bool {
-                match *self {
-                    $(
-                        DepKind :: $variant => {
-                            if contains_anon_attr!($($attrs)*) {
-                                return false;
-                            }
-
-                            // tuple args
-                            $({
-                                return <$tuple_arg_ty as DepNodeParams>
-                                    ::CAN_RECONSTRUCT_QUERY_KEY;
-                            })*
-
-                            true
-                        }
-                    )*
-                }
-            }
-
-            pub fn is_anon(&self) -> bool {
-                match *self {
-                    $(
-                        DepKind :: $variant => { contains_anon_attr!($($attrs)*) }
-                    )*
-                }
-            }
-
-            pub fn is_eval_always(&self) -> bool {
-                match *self {
-                    $(
-                        DepKind :: $variant => { contains_eval_always_attr!($($attrs)*) }
-                    )*
-                }
-            }
-
-            #[allow(unreachable_code)]
-            pub fn has_params(&self) -> bool {
-                match *self {
-                    $(
-                        DepKind :: $variant => {
-                            // tuple args
-                            $({
-                                erase!($tuple_arg_ty);
-                                return true;
-                            })*
-
-                            false
-                        }
-                    )*
-                }
-            }
-        }
-
-        pub struct DepConstructor;
-
-        impl DepConstructor {
-            $(
-                #[inline(always)]
-                #[allow(unreachable_code, non_snake_case)]
-                pub fn $variant<'tcx>(_tcx: TyCtxt<'tcx>, $(arg: $tuple_arg_ty)*) -> DepNode {
-                    // tuple args
-                    $({
-                        erase!($tuple_arg_ty);
-                        let hash = DepNodeParams::to_fingerprint(&arg, _tcx);
-                        let dep_node = DepNode {
-                            kind: DepKind::$variant,
-                            hash
-                        };
-
-                        #[cfg(debug_assertions)]
-                        {
-                            if !dep_node.kind.can_reconstruct_query_key() &&
-                            (_tcx.sess.opts.debugging_opts.incremental_info ||
-                                _tcx.sess.opts.debugging_opts.query_dep_graph)
-                            {
-                                _tcx.dep_graph.register_dep_node_debug_str(dep_node, || {
-                                    arg.to_debug_str(_tcx)
-                                });
-                            }
-                        }
-
-                        return dep_node;
-                    })*
-
-                    DepNode {
-                        kind: DepKind::$variant,
-                        hash: Fingerprint::ZERO,
-                    }
-                }
-            )*
-        }
-
-        #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash,
-                 RustcEncodable, RustcDecodable)]
-        pub struct DepNode {
-            pub kind: DepKind,
-            pub hash: Fingerprint,
-        }
-
-        impl DepNode {
-            /// Construct a DepNode from the given DepKind and DefPathHash. This
-            /// method will assert that the given DepKind actually requires a
-            /// single DefId/DefPathHash parameter.
-            pub fn from_def_path_hash(kind: DepKind,
-                                      def_path_hash: DefPathHash)
-                                      -> DepNode {
-                debug_assert!(kind.can_reconstruct_query_key() && kind.has_params());
-                DepNode {
-                    kind,
-                    hash: def_path_hash.0,
-                }
-            }
-
-            /// Creates a new, parameterless DepNode. This method will assert
-            /// that the DepNode corresponding to the given DepKind actually
-            /// does not require any parameters.
-            pub fn new_no_params(kind: DepKind) -> DepNode {
-                debug_assert!(!kind.has_params());
-                DepNode {
-                    kind,
-                    hash: Fingerprint::ZERO,
-                }
-            }
-
-            /// Extracts the DefId corresponding to this DepNode. This will work
-            /// if two conditions are met:
-            ///
-            /// 1. The Fingerprint of the DepNode actually is a DefPathHash, and
-            /// 2. the item that the DefPath refers to exists in the current tcx.
-            ///
-            /// Condition (1) is determined by the DepKind variant of the
-            /// DepNode. Condition (2) might not be fulfilled if a DepNode
-            /// refers to something from the previous compilation session that
-            /// has been removed.
-            pub fn extract_def_id(&self, tcx: TyCtxt<'_>) -> Option<DefId> {
-                if self.kind.can_reconstruct_query_key() {
-                    let def_path_hash = DefPathHash(self.hash);
-                    tcx.def_path_hash_to_def_id.as_ref()?
-                        .get(&def_path_hash).cloned()
-                } else {
-                    None
-                }
-            }
-
-            /// Used in testing
-            pub fn from_label_string(label: &str,
-                                     def_path_hash: DefPathHash)
-                                     -> Result<DepNode, ()> {
-                let kind = match label {
-                    $(
-                        stringify!($variant) => DepKind::$variant,
-                    )*
-                    _ => return Err(()),
-                };
-
-                if !kind.can_reconstruct_query_key() {
-                    return Err(());
-                }
-
-                if kind.has_params() {
-                    Ok(def_path_hash.to_dep_node(kind))
-                } else {
-                    Ok(DepNode::new_no_params(kind))
-                }
-            }
-
-            /// Used in testing
-            pub fn has_label_string(label: &str) -> bool {
-                match label {
-                    $(
-                        stringify!($variant) => true,
-                    )*
-                    _ => false,
-                }
-            }
-        }
-
-        /// Contains variant => str representations for constructing
-        /// DepNode groups for tests.
-        #[allow(dead_code, non_upper_case_globals)]
-        pub mod label_strs {
-           $(
-                pub const $variant: &str = stringify!($variant);
-            )*
-        }
-    );
-}
-
-impl fmt::Debug for DepNode {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "{:?}", self.kind)?;
-
-        if !self.kind.has_params() && !self.kind.is_anon() {
-            return Ok(());
-        }
-
-        write!(f, "(")?;
-
-        crate::ty::tls::with_opt(|opt_tcx| {
-            if let Some(tcx) = opt_tcx {
-                if let Some(def_id) = self.extract_def_id(tcx) {
-                    write!(f, "{}", tcx.def_path_debug_str(def_id))?;
-                } else if let Some(ref s) = tcx.dep_graph.dep_node_debug_str(*self) {
-                    write!(f, "{}", s)?;
-                } else {
-                    write!(f, "{}", self.hash)?;
-                }
-            } else {
-                write!(f, "{}", self.hash)?;
-            }
-            Ok(())
-        })?;
-
-        write!(f, ")")
-    }
-}
-
-impl DefPathHash {
-    pub fn to_dep_node(self, kind: DepKind) -> DepNode {
-        DepNode::from_def_path_hash(kind, self)
-    }
-}
-
-rustc_dep_node_append!([define_dep_nodes!][ <'tcx>
-    // We use this for most things when incr. comp. is turned off.
-    [] Null,
-
-    // Represents the body of a function or method. The def-id is that of the
-    // function/method.
-    [eval_always] HirBody(DefId),
-
-    // Represents the HIR node with the given node-id
-    [eval_always] Hir(DefId),
-
-    // Represents metadata from an extern crate.
-    [eval_always] CrateMetadata(CrateNum),
-
-    [eval_always] AllLocalTraitImpls,
-
-    [anon] TraitSelect,
-
-    [] CompileCodegenUnit(Symbol),
-
-    [eval_always] Analysis(CrateNum),
-]);
-
-pub trait RecoverKey<'tcx>: Sized {
-    fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self>;
-}
-
-impl RecoverKey<'tcx> for CrateNum {
-    fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
-        dep_node.extract_def_id(tcx).map(|id| id.krate)
-    }
-}
-
-impl RecoverKey<'tcx> for DefId {
-    fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
-        dep_node.extract_def_id(tcx)
-    }
-}
-
-impl RecoverKey<'tcx> for DefIndex {
-    fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
-        dep_node.extract_def_id(tcx).map(|id| id.index)
-    }
-}
-
-trait DepNodeParams<'tcx>: fmt::Debug {
-    const CAN_RECONSTRUCT_QUERY_KEY: bool;
-
-    /// This method turns the parameters of a DepNodeConstructor into an opaque
-    /// Fingerprint to be used in DepNode.
-    /// Not all DepNodeParams support being turned into a Fingerprint (they
-    /// don't need to if the corresponding DepNode is anonymous).
-    fn to_fingerprint(&self, _: TyCtxt<'tcx>) -> Fingerprint {
-        panic!("Not implemented. Accidentally called on anonymous node?")
-    }
-
-    fn to_debug_str(&self, _: TyCtxt<'tcx>) -> String {
-        format!("{:?}", self)
-    }
-}
-
-impl<'tcx, T> DepNodeParams<'tcx> for T
-where
-    T: HashStable<StableHashingContext<'tcx>> + fmt::Debug,
-{
-    default const CAN_RECONSTRUCT_QUERY_KEY: bool = false;
-
-    default fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
-        let mut hcx = tcx.create_stable_hashing_context();
-        let mut hasher = StableHasher::new();
-
-        self.hash_stable(&mut hcx, &mut hasher);
-
-        hasher.finish()
-    }
-
-    default fn to_debug_str(&self, _: TyCtxt<'tcx>) -> String {
-        format!("{:?}", *self)
-    }
-}
-
-impl<'tcx> DepNodeParams<'tcx> for DefId {
-    const CAN_RECONSTRUCT_QUERY_KEY: bool = true;
-
-    fn to_fingerprint(&self, tcx: TyCtxt<'_>) -> Fingerprint {
-        tcx.def_path_hash(*self).0
-    }
-
-    fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
-        tcx.def_path_str(*self)
-    }
-}
-
-impl<'tcx> DepNodeParams<'tcx> for DefIndex {
-    const CAN_RECONSTRUCT_QUERY_KEY: bool = true;
-
-    fn to_fingerprint(&self, tcx: TyCtxt<'_>) -> Fingerprint {
-        tcx.hir().definitions().def_path_hash(*self).0
-    }
-
-    fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
-        tcx.def_path_str(DefId::local(*self))
-    }
-}
-
-impl<'tcx> DepNodeParams<'tcx> for CrateNum {
-    const CAN_RECONSTRUCT_QUERY_KEY: bool = true;
-
-    fn to_fingerprint(&self, tcx: TyCtxt<'_>) -> Fingerprint {
-        let def_id = DefId { krate: *self, index: CRATE_DEF_INDEX };
-        tcx.def_path_hash(def_id).0
-    }
-
-    fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
-        tcx.crate_name(*self).to_string()
-    }
-}
-
-impl<'tcx> DepNodeParams<'tcx> for (DefId, DefId) {
-    const CAN_RECONSTRUCT_QUERY_KEY: bool = false;
-
-    // We actually would not need to specialize the implementation of this
-    // method but it's faster to combine the hashes than to instantiate a full
-    // hashing context and stable-hashing state.
-    fn to_fingerprint(&self, tcx: TyCtxt<'_>) -> Fingerprint {
-        let (def_id_0, def_id_1) = *self;
-
-        let def_path_hash_0 = tcx.def_path_hash(def_id_0);
-        let def_path_hash_1 = tcx.def_path_hash(def_id_1);
-
-        def_path_hash_0.0.combine(def_path_hash_1.0)
-    }
-
-    fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
-        let (def_id_0, def_id_1) = *self;
-
-        format!("({}, {})", tcx.def_path_debug_str(def_id_0), tcx.def_path_debug_str(def_id_1))
-    }
-}
-
-impl<'tcx> DepNodeParams<'tcx> for HirId {
-    const CAN_RECONSTRUCT_QUERY_KEY: bool = false;
-
-    // We actually would not need to specialize the implementation of this
-    // method but it's faster to combine the hashes than to instantiate a full
-    // hashing context and stable-hashing state.
-    fn to_fingerprint(&self, tcx: TyCtxt<'_>) -> Fingerprint {
-        let HirId { owner, local_id } = *self;
-
-        let def_path_hash = tcx.def_path_hash(DefId::local(owner));
-        let local_id = Fingerprint::from_smaller_hash(local_id.as_u32().into());
-
-        def_path_hash.0.combine(local_id)
-    }
-}
-
-/// A "work product" corresponds to a `.o` (or other) file that we
-/// save in between runs. These IDs do not have a `DefId` but rather
-/// some independent path or string that persists between runs without
-/// the need to be mapped or unmapped. (This ensures we can serialize
-/// them even in the absence of a tcx.)
-#[derive(
-    Clone,
-    Copy,
-    Debug,
-    PartialEq,
-    Eq,
-    PartialOrd,
-    Ord,
-    Hash,
-    RustcEncodable,
-    RustcDecodable,
-    HashStable
-)]
-pub struct WorkProductId {
-    hash: Fingerprint,
-}
-
-impl WorkProductId {
-    pub fn from_cgu_name(cgu_name: &str) -> WorkProductId {
-        let mut hasher = StableHasher::new();
-        cgu_name.len().hash(&mut hasher);
-        cgu_name.hash(&mut hasher);
-        WorkProductId { hash: hasher.finish() }
-    }
-
-    pub fn from_fingerprint(fingerprint: Fingerprint) -> WorkProductId {
-        WorkProductId { hash: fingerprint }
-    }
-}
diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs
deleted file mode 100644
index 531a45b120c..00000000000
--- a/src/librustc/dep_graph/graph.rs
+++ /dev/null
@@ -1,1198 +0,0 @@
-use crate::ty::{self, TyCtxt};
-use parking_lot::{Condvar, Mutex};
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
-use rustc_data_structures::profiling::QueryInvocationId;
-use rustc_data_structures::sharded::{self, Sharded};
-use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
-use rustc_data_structures::sync::{AtomicU32, AtomicU64, Lock, Lrc, Ordering};
-use rustc_errors::Diagnostic;
-use rustc_hir::def_id::DefId;
-use rustc_index::vec::{Idx, IndexVec};
-use smallvec::SmallVec;
-use std::collections::hash_map::Entry;
-use std::env;
-use std::hash::Hash;
-use std::mem;
-use std::sync::atomic::Ordering::Relaxed;
-
-use crate::ich::{Fingerprint, StableHashingContext, StableHashingContextProvider};
-
-use super::debug::EdgeFilter;
-use super::dep_node::{DepKind, DepNode, WorkProductId};
-use super::prev::PreviousDepGraph;
-use super::query::DepGraphQuery;
-use super::safe::DepGraphSafe;
-use super::serialized::{SerializedDepGraph, SerializedDepNodeIndex};
-
-#[derive(Clone)]
-pub struct DepGraph {
-    data: Option<Lrc<DepGraphData>>,
-
-    /// This field is used for assigning DepNodeIndices when running in
-    /// non-incremental mode. Even in non-incremental mode we make sure that
-    /// each task has a `DepNodeIndex` that uniquely identifies it. This unique
-    /// ID is used for self-profiling.
-    virtual_dep_node_index: Lrc<AtomicU32>,
-}
-
-rustc_index::newtype_index! {
-    pub struct DepNodeIndex { .. }
-}
-
-impl DepNodeIndex {
-    pub const INVALID: DepNodeIndex = DepNodeIndex::MAX;
-}
-
-impl std::convert::From<DepNodeIndex> for QueryInvocationId {
-    #[inline]
-    fn from(dep_node_index: DepNodeIndex) -> Self {
-        QueryInvocationId(dep_node_index.as_u32())
-    }
-}
-
-#[derive(PartialEq)]
-pub enum DepNodeColor {
-    Red,
-    Green(DepNodeIndex),
-}
-
-impl DepNodeColor {
-    pub fn is_green(self) -> bool {
-        match self {
-            DepNodeColor::Red => false,
-            DepNodeColor::Green(_) => true,
-        }
-    }
-}
-
-struct DepGraphData {
-    /// The new encoding of the dependency graph, optimized for red/green
-    /// tracking. The `current` field is the dependency graph of only the
-    /// current compilation session: We don't merge the previous dep-graph into
-    /// current one anymore.
-    current: CurrentDepGraph,
-
-    /// The dep-graph from the previous compilation session. It contains all
-    /// nodes and edges as well as all fingerprints of nodes that have them.
-    previous: PreviousDepGraph,
-
-    colors: DepNodeColorMap,
-
-    /// A set of loaded diagnostics that is in the progress of being emitted.
-    emitting_diagnostics: Mutex<FxHashSet<DepNodeIndex>>,
-
-    /// Used to wait for diagnostics to be emitted.
-    emitting_diagnostics_cond_var: Condvar,
-
-    /// When we load, there may be `.o` files, cached MIR, or other such
-    /// things available to us. If we find that they are not dirty, we
-    /// load the path to the file storing those work-products here into
-    /// this map. We can later look for and extract that data.
-    previous_work_products: FxHashMap<WorkProductId, WorkProduct>,
-
-    dep_node_debug: Lock<FxHashMap<DepNode, String>>,
-}
-
-pub fn hash_result<R>(hcx: &mut StableHashingContext<'_>, result: &R) -> Option<Fingerprint>
-where
-    R: for<'a> HashStable<StableHashingContext<'a>>,
-{
-    let mut stable_hasher = StableHasher::new();
-    result.hash_stable(hcx, &mut stable_hasher);
-
-    Some(stable_hasher.finish())
-}
-
-impl DepGraph {
-    pub fn new(
-        prev_graph: PreviousDepGraph,
-        prev_work_products: FxHashMap<WorkProductId, WorkProduct>,
-    ) -> DepGraph {
-        let prev_graph_node_count = prev_graph.node_count();
-
-        DepGraph {
-            data: Some(Lrc::new(DepGraphData {
-                previous_work_products: prev_work_products,
-                dep_node_debug: Default::default(),
-                current: CurrentDepGraph::new(prev_graph_node_count),
-                emitting_diagnostics: Default::default(),
-                emitting_diagnostics_cond_var: Condvar::new(),
-                previous: prev_graph,
-                colors: DepNodeColorMap::new(prev_graph_node_count),
-            })),
-            virtual_dep_node_index: Lrc::new(AtomicU32::new(0)),
-        }
-    }
-
-    pub fn new_disabled() -> DepGraph {
-        DepGraph { data: None, virtual_dep_node_index: Lrc::new(AtomicU32::new(0)) }
-    }
-
-    /// Returns `true` if we are actually building the full dep-graph, and `false` otherwise.
-    #[inline]
-    pub fn is_fully_enabled(&self) -> bool {
-        self.data.is_some()
-    }
-
-    pub fn query(&self) -> DepGraphQuery {
-        let data = self.data.as_ref().unwrap().current.data.lock();
-        let nodes: Vec<_> = data.iter().map(|n| n.node).collect();
-        let mut edges = Vec::new();
-        for (from, edge_targets) in data.iter().map(|d| (d.node, &d.edges)) {
-            for &edge_target in edge_targets.iter() {
-                let to = data[edge_target].node;
-                edges.push((from, to));
-            }
-        }
-
-        DepGraphQuery::new(&nodes[..], &edges[..])
-    }
-
-    pub fn assert_ignored(&self) {
-        if let Some(..) = self.data {
-            ty::tls::with_context_opt(|icx| {
-                let icx = if let Some(icx) = icx { icx } else { return };
-                assert!(icx.task_deps.is_none(), "expected no task dependency tracking");
-            })
-        }
-    }
-
-    pub fn with_ignore<OP, R>(&self, op: OP) -> R
-    where
-        OP: FnOnce() -> R,
-    {
-        ty::tls::with_context(|icx| {
-            let icx = ty::tls::ImplicitCtxt { task_deps: None, ..icx.clone() };
-
-            ty::tls::enter_context(&icx, |_| op())
-        })
-    }
-
-    /// Starts a new dep-graph task. Dep-graph tasks are specified
-    /// using a free function (`task`) and **not** a closure -- this
-    /// is intentional because we want to exercise tight control over
-    /// what state they have access to. In particular, we want to
-    /// prevent implicit 'leaks' of tracked state into the task (which
-    /// could then be read without generating correct edges in the
-    /// dep-graph -- see the [rustc guide] for more details on
-    /// the dep-graph). To this end, the task function gets exactly two
-    /// pieces of state: the context `cx` and an argument `arg`. Both
-    /// of these bits of state must be of some type that implements
-    /// `DepGraphSafe` and hence does not leak.
-    ///
-    /// The choice of two arguments is not fundamental. One argument
-    /// would work just as well, since multiple values can be
-    /// collected using tuples. However, using two arguments works out
-    /// to be quite convenient, since it is common to need a context
-    /// (`cx`) and some argument (e.g., a `DefId` identifying what
-    /// item to process).
-    ///
-    /// For cases where you need some other number of arguments:
-    ///
-    /// - If you only need one argument, just use `()` for the `arg`
-    ///   parameter.
-    /// - If you need 3+ arguments, use a tuple for the
-    ///   `arg` parameter.
-    ///
-    /// [rustc guide]: https://rust-lang.github.io/rustc-guide/incremental-compilation.html
-    pub fn with_task<'a, C, A, R>(
-        &self,
-        key: DepNode,
-        cx: C,
-        arg: A,
-        task: fn(C, A) -> R,
-        hash_result: impl FnOnce(&mut StableHashingContext<'_>, &R) -> Option<Fingerprint>,
-    ) -> (R, DepNodeIndex)
-    where
-        C: DepGraphSafe + StableHashingContextProvider<'a>,
-    {
-        self.with_task_impl(
-            key,
-            cx,
-            arg,
-            false,
-            task,
-            |_key| {
-                Some(TaskDeps {
-                    #[cfg(debug_assertions)]
-                    node: Some(_key),
-                    reads: SmallVec::new(),
-                    read_set: Default::default(),
-                })
-            },
-            |data, key, fingerprint, task| data.complete_task(key, task.unwrap(), fingerprint),
-            hash_result,
-        )
-    }
-
-    /// Creates a new dep-graph input with value `input`
-    pub fn input_task<'a, C, R>(&self, key: DepNode, cx: C, input: R) -> (R, DepNodeIndex)
-    where
-        C: DepGraphSafe + StableHashingContextProvider<'a>,
-        R: for<'b> HashStable<StableHashingContext<'b>>,
-    {
-        fn identity_fn<C, A>(_: C, arg: A) -> A {
-            arg
-        }
-
-        self.with_task_impl(
-            key,
-            cx,
-            input,
-            true,
-            identity_fn,
-            |_| None,
-            |data, key, fingerprint, _| data.alloc_node(key, SmallVec::new(), fingerprint),
-            hash_result::<R>,
-        )
-    }
-
-    fn with_task_impl<'a, C, A, R>(
-        &self,
-        key: DepNode,
-        cx: C,
-        arg: A,
-        no_tcx: bool,
-        task: fn(C, A) -> R,
-        create_task: fn(DepNode) -> Option<TaskDeps>,
-        finish_task_and_alloc_depnode: fn(
-            &CurrentDepGraph,
-            DepNode,
-            Fingerprint,
-            Option<TaskDeps>,
-        ) -> DepNodeIndex,
-        hash_result: impl FnOnce(&mut StableHashingContext<'_>, &R) -> Option<Fingerprint>,
-    ) -> (R, DepNodeIndex)
-    where
-        C: DepGraphSafe + StableHashingContextProvider<'a>,
-    {
-        if let Some(ref data) = self.data {
-            let task_deps = create_task(key).map(|deps| Lock::new(deps));
-
-            // In incremental mode, hash the result of the task. We don't
-            // do anything with the hash yet, but we are computing it
-            // anyway so that
-            //  - we make sure that the infrastructure works and
-            //  - we can get an idea of the runtime cost.
-            let mut hcx = cx.get_stable_hashing_context();
-
-            let result = if no_tcx {
-                task(cx, arg)
-            } else {
-                ty::tls::with_context(|icx| {
-                    let icx =
-                        ty::tls::ImplicitCtxt { task_deps: task_deps.as_ref(), ..icx.clone() };
-
-                    ty::tls::enter_context(&icx, |_| task(cx, arg))
-                })
-            };
-
-            let current_fingerprint = hash_result(&mut hcx, &result);
-
-            let dep_node_index = finish_task_and_alloc_depnode(
-                &data.current,
-                key,
-                current_fingerprint.unwrap_or(Fingerprint::ZERO),
-                task_deps.map(|lock| lock.into_inner()),
-            );
-
-            let print_status = cfg!(debug_assertions) && hcx.sess().opts.debugging_opts.dep_tasks;
-
-            // Determine the color of the new DepNode.
-            if let Some(prev_index) = data.previous.node_to_index_opt(&key) {
-                let prev_fingerprint = data.previous.fingerprint_by_index(prev_index);
-
-                let color = if let Some(current_fingerprint) = current_fingerprint {
-                    if current_fingerprint == prev_fingerprint {
-                        if print_status {
-                            eprintln!("[task::green] {:?}", key);
-                        }
-                        DepNodeColor::Green(dep_node_index)
-                    } else {
-                        if print_status {
-                            eprintln!("[task::red] {:?}", key);
-                        }
-                        DepNodeColor::Red
-                    }
-                } else {
-                    if print_status {
-                        eprintln!("[task::unknown] {:?}", key);
-                    }
-                    // Mark the node as Red if we can't hash the result
-                    DepNodeColor::Red
-                };
-
-                debug_assert!(
-                    data.colors.get(prev_index).is_none(),
-                    "DepGraph::with_task() - Duplicate DepNodeColor \
-                            insertion for {:?}",
-                    key
-                );
-
-                data.colors.insert(prev_index, color);
-            } else {
-                if print_status {
-                    eprintln!("[task::new] {:?}", key);
-                }
-            }
-
-            (result, dep_node_index)
-        } else {
-            (task(cx, arg), self.next_virtual_depnode_index())
-        }
-    }
-
-    /// Executes something within an "anonymous" task, that is, a task the
-    /// `DepNode` of which is determined by the list of inputs it read from.
-    pub fn with_anon_task<OP, R>(&self, dep_kind: DepKind, op: OP) -> (R, DepNodeIndex)
-    where
-        OP: FnOnce() -> R,
-    {
-        if let Some(ref data) = self.data {
-            let (result, task_deps) = ty::tls::with_context(|icx| {
-                let task_deps = Lock::new(TaskDeps {
-                    #[cfg(debug_assertions)]
-                    node: None,
-                    reads: SmallVec::new(),
-                    read_set: Default::default(),
-                });
-
-                let r = {
-                    let icx = ty::tls::ImplicitCtxt { task_deps: Some(&task_deps), ..icx.clone() };
-
-                    ty::tls::enter_context(&icx, |_| op())
-                };
-
-                (r, task_deps.into_inner())
-            });
-            let dep_node_index = data.current.complete_anon_task(dep_kind, task_deps);
-            (result, dep_node_index)
-        } else {
-            (op(), self.next_virtual_depnode_index())
-        }
-    }
-
-    /// Executes something within an "eval-always" task which is a task
-    /// that runs whenever anything changes.
-    pub fn with_eval_always_task<'a, C, A, R>(
-        &self,
-        key: DepNode,
-        cx: C,
-        arg: A,
-        task: fn(C, A) -> R,
-        hash_result: impl FnOnce(&mut StableHashingContext<'_>, &R) -> Option<Fingerprint>,
-    ) -> (R, DepNodeIndex)
-    where
-        C: DepGraphSafe + StableHashingContextProvider<'a>,
-    {
-        self.with_task_impl(
-            key,
-            cx,
-            arg,
-            false,
-            task,
-            |_| None,
-            |data, key, fingerprint, _| data.alloc_node(key, smallvec![], fingerprint),
-            hash_result,
-        )
-    }
-
-    #[inline]
-    pub fn read(&self, v: DepNode) {
-        if let Some(ref data) = self.data {
-            let map = data.current.node_to_node_index.get_shard_by_value(&v).lock();
-            if let Some(dep_node_index) = map.get(&v).copied() {
-                std::mem::drop(map);
-                data.read_index(dep_node_index);
-            } else {
-                bug!("DepKind {:?} should be pre-allocated but isn't.", v.kind)
-            }
-        }
-    }
-
-    #[inline]
-    pub fn read_index(&self, dep_node_index: DepNodeIndex) {
-        if let Some(ref data) = self.data {
-            data.read_index(dep_node_index);
-        }
-    }
-
-    #[inline]
-    pub fn dep_node_index_of(&self, dep_node: &DepNode) -> DepNodeIndex {
-        self.data
-            .as_ref()
-            .unwrap()
-            .current
-            .node_to_node_index
-            .get_shard_by_value(dep_node)
-            .lock()
-            .get(dep_node)
-            .cloned()
-            .unwrap()
-    }
-
-    #[inline]
-    pub fn dep_node_exists(&self, dep_node: &DepNode) -> bool {
-        if let Some(ref data) = self.data {
-            data.current
-                .node_to_node_index
-                .get_shard_by_value(&dep_node)
-                .lock()
-                .contains_key(dep_node)
-        } else {
-            false
-        }
-    }
-
-    #[inline]
-    pub fn fingerprint_of(&self, dep_node_index: DepNodeIndex) -> Fingerprint {
-        let data = self.data.as_ref().expect("dep graph enabled").current.data.lock();
-        data[dep_node_index].fingerprint
-    }
-
-    pub fn prev_fingerprint_of(&self, dep_node: &DepNode) -> Option<Fingerprint> {
-        self.data.as_ref().unwrap().previous.fingerprint_of(dep_node)
-    }
-
-    #[inline]
-    pub fn prev_dep_node_index_of(&self, dep_node: &DepNode) -> SerializedDepNodeIndex {
-        self.data.as_ref().unwrap().previous.node_to_index(dep_node)
-    }
-
-    /// Checks whether a previous work product exists for `v` and, if
-    /// so, return the path that leads to it. Used to skip doing work.
-    pub fn previous_work_product(&self, v: &WorkProductId) -> Option<WorkProduct> {
-        self.data.as_ref().and_then(|data| data.previous_work_products.get(v).cloned())
-    }
-
-    /// Access the map of work-products created during the cached run. Only
-    /// used during saving of the dep-graph.
-    pub fn previous_work_products(&self) -> &FxHashMap<WorkProductId, WorkProduct> {
-        &self.data.as_ref().unwrap().previous_work_products
-    }
-
-    #[inline(always)]
-    pub fn register_dep_node_debug_str<F>(&self, dep_node: DepNode, debug_str_gen: F)
-    where
-        F: FnOnce() -> String,
-    {
-        let dep_node_debug = &self.data.as_ref().unwrap().dep_node_debug;
-
-        if dep_node_debug.borrow().contains_key(&dep_node) {
-            return;
-        }
-        let debug_str = debug_str_gen();
-        dep_node_debug.borrow_mut().insert(dep_node, debug_str);
-    }
-
-    pub(super) fn dep_node_debug_str(&self, dep_node: DepNode) -> Option<String> {
-        self.data.as_ref()?.dep_node_debug.borrow().get(&dep_node).cloned()
-    }
-
-    pub fn edge_deduplication_data(&self) -> Option<(u64, u64)> {
-        if cfg!(debug_assertions) {
-            let current_dep_graph = &self.data.as_ref().unwrap().current;
-
-            Some((
-                current_dep_graph.total_read_count.load(Relaxed),
-                current_dep_graph.total_duplicate_read_count.load(Relaxed),
-            ))
-        } else {
-            None
-        }
-    }
-
-    pub fn serialize(&self) -> SerializedDepGraph {
-        let data = self.data.as_ref().unwrap().current.data.lock();
-
-        let fingerprints: IndexVec<SerializedDepNodeIndex, _> =
-            data.iter().map(|d| d.fingerprint).collect();
-        let nodes: IndexVec<SerializedDepNodeIndex, _> = data.iter().map(|d| d.node).collect();
-
-        let total_edge_count: usize = data.iter().map(|d| d.edges.len()).sum();
-
-        let mut edge_list_indices = IndexVec::with_capacity(nodes.len());
-        let mut edge_list_data = Vec::with_capacity(total_edge_count);
-
-        for (current_dep_node_index, edges) in data.iter_enumerated().map(|(i, d)| (i, &d.edges)) {
-            let start = edge_list_data.len() as u32;
-            // This should really just be a memcpy :/
-            edge_list_data.extend(edges.iter().map(|i| SerializedDepNodeIndex::new(i.index())));
-            let end = edge_list_data.len() as u32;
-
-            debug_assert_eq!(current_dep_node_index.index(), edge_list_indices.len());
-            edge_list_indices.push((start, end));
-        }
-
-        debug_assert!(edge_list_data.len() <= ::std::u32::MAX as usize);
-        debug_assert_eq!(edge_list_data.len(), total_edge_count);
-
-        SerializedDepGraph { nodes, fingerprints, edge_list_indices, edge_list_data }
-    }
-
-    pub fn node_color(&self, dep_node: &DepNode) -> Option<DepNodeColor> {
-        if let Some(ref data) = self.data {
-            if let Some(prev_index) = data.previous.node_to_index_opt(dep_node) {
-                return data.colors.get(prev_index);
-            } else {
-                // This is a node that did not exist in the previous compilation
-                // session, so we consider it to be red.
-                return Some(DepNodeColor::Red);
-            }
-        }
-
-        None
-    }
-
-    /// Try to read a node index for the node dep_node.
-    /// A node will have an index, when it's already been marked green, or when we can mark it
-    /// green. This function will mark the current task as a reader of the specified node, when
-    /// a node index can be found for that node.
-    pub fn try_mark_green_and_read(
-        &self,
-        tcx: TyCtxt<'_>,
-        dep_node: &DepNode,
-    ) -> Option<(SerializedDepNodeIndex, DepNodeIndex)> {
-        self.try_mark_green(tcx, dep_node).map(|(prev_index, dep_node_index)| {
-            debug_assert!(self.is_green(&dep_node));
-            self.read_index(dep_node_index);
-            (prev_index, dep_node_index)
-        })
-    }
-
-    pub fn try_mark_green(
-        &self,
-        tcx: TyCtxt<'_>,
-        dep_node: &DepNode,
-    ) -> Option<(SerializedDepNodeIndex, DepNodeIndex)> {
-        debug_assert!(!dep_node.kind.is_eval_always());
-
-        // Return None if the dep graph is disabled
-        let data = self.data.as_ref()?;
-
-        // Return None if the dep node didn't exist in the previous session
-        let prev_index = data.previous.node_to_index_opt(dep_node)?;
-
-        match data.colors.get(prev_index) {
-            Some(DepNodeColor::Green(dep_node_index)) => Some((prev_index, dep_node_index)),
-            Some(DepNodeColor::Red) => None,
-            None => {
-                // This DepNode and the corresponding query invocation existed
-                // in the previous compilation session too, so we can try to
-                // mark it as green by recursively marking all of its
-                // dependencies green.
-                self.try_mark_previous_green(tcx, data, prev_index, &dep_node)
-                    .map(|dep_node_index| (prev_index, dep_node_index))
-            }
-        }
-    }
-
-    /// Try to mark a dep-node which existed in the previous compilation session as green.
-    fn try_mark_previous_green<'tcx>(
-        &self,
-        tcx: TyCtxt<'tcx>,
-        data: &DepGraphData,
-        prev_dep_node_index: SerializedDepNodeIndex,
-        dep_node: &DepNode,
-    ) -> Option<DepNodeIndex> {
-        debug!("try_mark_previous_green({:?}) - BEGIN", dep_node);
-
-        #[cfg(not(parallel_compiler))]
-        {
-            debug_assert!(
-                !data
-                    .current
-                    .node_to_node_index
-                    .get_shard_by_value(dep_node)
-                    .lock()
-                    .contains_key(dep_node)
-            );
-            debug_assert!(data.colors.get(prev_dep_node_index).is_none());
-        }
-
-        // We never try to mark eval_always nodes as green
-        debug_assert!(!dep_node.kind.is_eval_always());
-
-        debug_assert_eq!(data.previous.index_to_node(prev_dep_node_index), *dep_node);
-
-        let prev_deps = data.previous.edge_targets_from(prev_dep_node_index);
-
-        let mut current_deps = SmallVec::new();
-
-        for &dep_dep_node_index in prev_deps {
-            let dep_dep_node_color = data.colors.get(dep_dep_node_index);
-
-            match dep_dep_node_color {
-                Some(DepNodeColor::Green(node_index)) => {
-                    // This dependency has been marked as green before, we are
-                    // still fine and can continue with checking the other
-                    // dependencies.
-                    debug!(
-                        "try_mark_previous_green({:?}) --- found dependency {:?} to \
-                            be immediately green",
-                        dep_node,
-                        data.previous.index_to_node(dep_dep_node_index)
-                    );
-                    current_deps.push(node_index);
-                }
-                Some(DepNodeColor::Red) => {
-                    // We found a dependency the value of which has changed
-                    // compared to the previous compilation session. We cannot
-                    // mark the DepNode as green and also don't need to bother
-                    // with checking any of the other dependencies.
-                    debug!(
-                        "try_mark_previous_green({:?}) - END - dependency {:?} was \
-                            immediately red",
-                        dep_node,
-                        data.previous.index_to_node(dep_dep_node_index)
-                    );
-                    return None;
-                }
-                None => {
-                    let dep_dep_node = &data.previous.index_to_node(dep_dep_node_index);
-
-                    // We don't know the state of this dependency. If it isn't
-                    // an eval_always node, let's try to mark it green recursively.
-                    if !dep_dep_node.kind.is_eval_always() {
-                        debug!(
-                            "try_mark_previous_green({:?}) --- state of dependency {:?} \
-                                 is unknown, trying to mark it green",
-                            dep_node, dep_dep_node
-                        );
-
-                        let node_index = self.try_mark_previous_green(
-                            tcx,
-                            data,
-                            dep_dep_node_index,
-                            dep_dep_node,
-                        );
-                        if let Some(node_index) = node_index {
-                            debug!(
-                                "try_mark_previous_green({:?}) --- managed to MARK \
-                                    dependency {:?} as green",
-                                dep_node, dep_dep_node
-                            );
-                            current_deps.push(node_index);
-                            continue;
-                        }
-                    } else {
-                        match dep_dep_node.kind {
-                            DepKind::Hir | DepKind::HirBody | DepKind::CrateMetadata => {
-                                if let Some(def_id) = dep_dep_node.extract_def_id(tcx) {
-                                    if def_id_corresponds_to_hir_dep_node(tcx, def_id) {
-                                        // The `DefPath` has corresponding node,
-                                        // and that node should have been marked
-                                        // either red or green in `data.colors`.
-                                        bug!(
-                                            "DepNode {:?} should have been \
-                                             pre-marked as red or green but wasn't.",
-                                            dep_dep_node
-                                        );
-                                    } else {
-                                        // This `DefPath` does not have a
-                                        // corresponding `DepNode` (e.g. a
-                                        // struct field), and the ` DefPath`
-                                        // collided with the `DefPath` of a
-                                        // proper item that existed in the
-                                        // previous compilation session.
-                                        //
-                                        // Since the given `DefPath` does not
-                                        // denote the item that previously
-                                        // existed, we just fail to mark green.
-                                        return None;
-                                    }
-                                } else {
-                                    // If the node does not exist anymore, we
-                                    // just fail to mark green.
-                                    return None;
-                                }
-                            }
-                            _ => {
-                                // For other kinds of nodes it's OK to be
-                                // forced.
-                            }
-                        }
-                    }
-
-                    // We failed to mark it green, so we try to force the query.
-                    debug!(
-                        "try_mark_previous_green({:?}) --- trying to force \
-                            dependency {:?}",
-                        dep_node, dep_dep_node
-                    );
-                    if crate::ty::query::force_from_dep_node(tcx, dep_dep_node) {
-                        let dep_dep_node_color = data.colors.get(dep_dep_node_index);
-
-                        match dep_dep_node_color {
-                            Some(DepNodeColor::Green(node_index)) => {
-                                debug!(
-                                    "try_mark_previous_green({:?}) --- managed to \
-                                        FORCE dependency {:?} to green",
-                                    dep_node, dep_dep_node
-                                );
-                                current_deps.push(node_index);
-                            }
-                            Some(DepNodeColor::Red) => {
-                                debug!(
-                                    "try_mark_previous_green({:?}) - END - \
-                                        dependency {:?} was red after forcing",
-                                    dep_node, dep_dep_node
-                                );
-                                return None;
-                            }
-                            None => {
-                                if !tcx.sess.has_errors_or_delayed_span_bugs() {
-                                    bug!(
-                                        "try_mark_previous_green() - Forcing the DepNode \
-                                          should have set its color"
-                                    )
-                                } else {
-                                    // If the query we just forced has resulted in
-                                    // some kind of compilation error, we cannot rely on
-                                    // the dep-node color having been properly updated.
-                                    // This means that the query system has reached an
-                                    // invalid state. We let the compiler continue (by
-                                    // returning `None`) so it can emit error messages
-                                    // and wind down, but rely on the fact that this
-                                    // invalid state will not be persisted to the
-                                    // incremental compilation cache because of
-                                    // compilation errors being present.
-                                    debug!(
-                                        "try_mark_previous_green({:?}) - END - \
-                                            dependency {:?} resulted in compilation error",
-                                        dep_node, dep_dep_node
-                                    );
-                                    return None;
-                                }
-                            }
-                        }
-                    } else {
-                        // The DepNode could not be forced.
-                        debug!(
-                            "try_mark_previous_green({:?}) - END - dependency {:?} \
-                                could not be forced",
-                            dep_node, dep_dep_node
-                        );
-                        return None;
-                    }
-                }
-            }
-        }
-
-        // If we got here without hitting a `return` that means that all
-        // dependencies of this DepNode could be marked as green. Therefore we
-        // can also mark this DepNode as green.
-
-        // There may be multiple threads trying to mark the same dep node green concurrently
-
-        let dep_node_index = {
-            // Copy the fingerprint from the previous graph,
-            // so we don't have to recompute it
-            let fingerprint = data.previous.fingerprint_by_index(prev_dep_node_index);
-
-            // We allocating an entry for the node in the current dependency graph and
-            // adding all the appropriate edges imported from the previous graph
-            data.current.intern_node(*dep_node, current_deps, fingerprint)
-        };
-
-        // ... emitting any stored diagnostic ...
-
-        // FIXME: Store the fact that a node has diagnostics in a bit in the dep graph somewhere
-        // Maybe store a list on disk and encode this fact in the DepNodeState
-        let diagnostics = tcx.queries.on_disk_cache.load_diagnostics(tcx, prev_dep_node_index);
-
-        #[cfg(not(parallel_compiler))]
-        debug_assert!(
-            data.colors.get(prev_dep_node_index).is_none(),
-            "DepGraph::try_mark_previous_green() - Duplicate DepNodeColor \
-                      insertion for {:?}",
-            dep_node
-        );
-
-        if unlikely!(diagnostics.len() > 0) {
-            self.emit_diagnostics(tcx, data, dep_node_index, prev_dep_node_index, diagnostics);
-        }
-
-        // ... and finally storing a "Green" entry in the color map.
-        // Multiple threads can all write the same color here
-        data.colors.insert(prev_dep_node_index, DepNodeColor::Green(dep_node_index));
-
-        debug!("try_mark_previous_green({:?}) - END - successfully marked as green", dep_node);
-        Some(dep_node_index)
-    }
-
-    /// Atomically emits some loaded diagnostics.
-    /// This may be called concurrently on multiple threads for the same dep node.
-    #[cold]
-    #[inline(never)]
-    fn emit_diagnostics<'tcx>(
-        &self,
-        tcx: TyCtxt<'tcx>,
-        data: &DepGraphData,
-        dep_node_index: DepNodeIndex,
-        prev_dep_node_index: SerializedDepNodeIndex,
-        diagnostics: Vec<Diagnostic>,
-    ) {
-        let mut emitting = data.emitting_diagnostics.lock();
-
-        if data.colors.get(prev_dep_node_index) == Some(DepNodeColor::Green(dep_node_index)) {
-            // The node is already green so diagnostics must have been emitted already
-            return;
-        }
-
-        if emitting.insert(dep_node_index) {
-            // We were the first to insert the node in the set so this thread
-            // must emit the diagnostics and signal other potentially waiting
-            // threads after.
-            mem::drop(emitting);
-
-            // Promote the previous diagnostics to the current session.
-            tcx.queries.on_disk_cache.store_diagnostics(dep_node_index, diagnostics.clone().into());
-
-            let handle = tcx.sess.diagnostic();
-
-            for diagnostic in diagnostics {
-                handle.emit_diagnostic(&diagnostic);
-            }
-
-            // Mark the node as green now that diagnostics are emitted
-            data.colors.insert(prev_dep_node_index, DepNodeColor::Green(dep_node_index));
-
-            // Remove the node from the set
-            data.emitting_diagnostics.lock().remove(&dep_node_index);
-
-            // Wake up waiters
-            data.emitting_diagnostics_cond_var.notify_all();
-        } else {
-            // We must wait for the other thread to finish emitting the diagnostic
-
-            loop {
-                data.emitting_diagnostics_cond_var.wait(&mut emitting);
-                if data.colors.get(prev_dep_node_index) == Some(DepNodeColor::Green(dep_node_index))
-                {
-                    break;
-                }
-            }
-        }
-    }
-
-    // Returns true if the given node has been marked as green during the
-    // current compilation session. Used in various assertions
-    pub fn is_green(&self, dep_node: &DepNode) -> bool {
-        self.node_color(dep_node).map(|c| c.is_green()).unwrap_or(false)
-    }
-
-    // This method loads all on-disk cacheable query results into memory, so
-    // they can be written out to the new cache file again. Most query results
-    // will already be in memory but in the case where we marked something as
-    // green but then did not need the value, that value will never have been
-    // loaded from disk.
-    //
-    // This method will only load queries that will end up in the disk cache.
-    // Other queries will not be executed.
-    pub fn exec_cache_promotions(&self, tcx: TyCtxt<'_>) {
-        let _prof_timer = tcx.prof.generic_activity("incr_comp_query_cache_promotion");
-
-        let data = self.data.as_ref().unwrap();
-        for prev_index in data.colors.values.indices() {
-            match data.colors.get(prev_index) {
-                Some(DepNodeColor::Green(_)) => {
-                    let dep_node = data.previous.index_to_node(prev_index);
-                    dep_node.try_load_from_on_disk_cache(tcx);
-                }
-                None | Some(DepNodeColor::Red) => {
-                    // We can skip red nodes because a node can only be marked
-                    // as red if the query result was recomputed and thus is
-                    // already in memory.
-                }
-            }
-        }
-    }
-
-    fn next_virtual_depnode_index(&self) -> DepNodeIndex {
-        let index = self.virtual_dep_node_index.fetch_add(1, Relaxed);
-        DepNodeIndex::from_u32(index)
-    }
-}
-
-fn def_id_corresponds_to_hir_dep_node(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
-    let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
-    def_id.index == hir_id.owner
-}
-
-/// A "work product" is an intermediate result that we save into the
-/// incremental directory for later re-use. The primary example are
-/// the object files that we save for each partition at code
-/// generation time.
-///
-/// Each work product is associated with a dep-node, representing the
-/// process that produced the work-product. If that dep-node is found
-/// to be dirty when we load up, then we will delete the work-product
-/// at load time. If the work-product is found to be clean, then we
-/// will keep a record in the `previous_work_products` list.
-///
-/// In addition, work products have an associated hash. This hash is
-/// an extra hash that can be used to decide if the work-product from
-/// a previous compilation can be re-used (in addition to the dirty
-/// edges check).
-///
-/// As the primary example, consider the object files we generate for
-/// each partition. In the first run, we create partitions based on
-/// the symbols that need to be compiled. For each partition P, we
-/// hash the symbols in P and create a `WorkProduct` record associated
-/// with `DepNode::CodegenUnit(P)`; the hash is the set of symbols
-/// in P.
-///
-/// The next time we compile, if the `DepNode::CodegenUnit(P)` is
-/// judged to be clean (which means none of the things we read to
-/// generate the partition were found to be dirty), it will be loaded
-/// into previous work products. We will then regenerate the set of
-/// symbols in the partition P and hash them (note that new symbols
-/// may be added -- for example, new monomorphizations -- even if
-/// nothing in P changed!). We will compare that hash against the
-/// previous hash. If it matches up, we can reuse the object file.
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
-pub struct WorkProduct {
-    pub cgu_name: String,
-    /// Saved files associated with this CGU.
-    pub saved_files: Vec<(WorkProductFileKind, String)>,
-}
-
-#[derive(Clone, Copy, Debug, RustcEncodable, RustcDecodable, PartialEq)]
-pub enum WorkProductFileKind {
-    Object,
-    Bytecode,
-    BytecodeCompressed,
-}
-
-#[derive(Clone)]
-struct DepNodeData {
-    node: DepNode,
-    edges: SmallVec<[DepNodeIndex; 8]>,
-    fingerprint: Fingerprint,
-}
-
-/// `CurrentDepGraph` stores the dependency graph for the current session.
-/// It will be populated as we run queries or tasks.
-///
-/// The nodes in it are identified by an index (`DepNodeIndex`).
-/// The data for each node is stored in its `DepNodeData`, found in the `data` field.
-///
-/// We never remove nodes from the graph: they are only added.
-///
-/// This struct uses two locks internally. The `data` and `node_to_node_index` fields are
-/// locked separately. Operations that take a `DepNodeIndex` typically just access
-/// the data field.
-///
-/// The only operation that must manipulate both locks is adding new nodes, in which case
-/// we first acquire the `node_to_node_index` lock and then, once a new node is to be inserted,
-/// acquire the lock on `data.`
-pub(super) struct CurrentDepGraph {
-    data: Lock<IndexVec<DepNodeIndex, DepNodeData>>,
-    node_to_node_index: Sharded<FxHashMap<DepNode, DepNodeIndex>>,
-
-    /// Used to trap when a specific edge is added to the graph.
-    /// This is used for debug purposes and is only active with `debug_assertions`.
-    #[allow(dead_code)]
-    forbidden_edge: Option<EdgeFilter>,
-
-    /// Anonymous `DepNode`s are nodes whose IDs we compute from the list of
-    /// their edges. This has the beneficial side-effect that multiple anonymous
-    /// nodes can be coalesced into one without changing the semantics of the
-    /// dependency graph. However, the merging of nodes can lead to a subtle
-    /// problem during red-green marking: The color of an anonymous node from
-    /// the current session might "shadow" the color of the node with the same
-    /// ID from the previous session. In order to side-step this problem, we make
-    /// sure that anonymous `NodeId`s allocated in different sessions don't overlap.
-    /// This is implemented by mixing a session-key into the ID fingerprint of
-    /// each anon node. The session-key is just a random number generated when
-    /// the `DepGraph` is created.
-    anon_id_seed: Fingerprint,
-
-    /// These are simple counters that are for profiling and
-    /// debugging and only active with `debug_assertions`.
-    total_read_count: AtomicU64,
-    total_duplicate_read_count: AtomicU64,
-}
-
-impl CurrentDepGraph {
-    fn new(prev_graph_node_count: usize) -> CurrentDepGraph {
-        use std::time::{SystemTime, UNIX_EPOCH};
-
-        let duration = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
-        let nanos = duration.as_secs() * 1_000_000_000 + duration.subsec_nanos() as u64;
-        let mut stable_hasher = StableHasher::new();
-        nanos.hash(&mut stable_hasher);
-
-        let forbidden_edge = if cfg!(debug_assertions) {
-            match env::var("RUST_FORBID_DEP_GRAPH_EDGE") {
-                Ok(s) => match EdgeFilter::new(&s) {
-                    Ok(f) => Some(f),
-                    Err(err) => bug!("RUST_FORBID_DEP_GRAPH_EDGE invalid: {}", err),
-                },
-                Err(_) => None,
-            }
-        } else {
-            None
-        };
-
-        // Pre-allocate the dep node structures. We over-allocate a little so
-        // that we hopefully don't have to re-allocate during this compilation
-        // session. The over-allocation is 2% plus a small constant to account
-        // for the fact that in very small crates 2% might not be enough.
-        let new_node_count_estimate = (prev_graph_node_count * 102) / 100 + 200;
-
-        CurrentDepGraph {
-            data: Lock::new(IndexVec::with_capacity(new_node_count_estimate)),
-            node_to_node_index: Sharded::new(|| {
-                FxHashMap::with_capacity_and_hasher(
-                    new_node_count_estimate / sharded::SHARDS,
-                    Default::default(),
-                )
-            }),
-            anon_id_seed: stable_hasher.finish(),
-            forbidden_edge,
-            total_read_count: AtomicU64::new(0),
-            total_duplicate_read_count: AtomicU64::new(0),
-        }
-    }
-
-    fn complete_task(
-        &self,
-        node: DepNode,
-        task_deps: TaskDeps,
-        fingerprint: Fingerprint,
-    ) -> DepNodeIndex {
-        self.alloc_node(node, task_deps.reads, fingerprint)
-    }
-
-    fn complete_anon_task(&self, kind: DepKind, task_deps: TaskDeps) -> DepNodeIndex {
-        debug_assert!(!kind.is_eval_always());
-
-        let mut hasher = StableHasher::new();
-
-        // The dep node indices are hashed here instead of hashing the dep nodes of the
-        // dependencies. These indices may refer to different nodes per session, but this isn't
-        // a problem here because we that ensure the final dep node hash is per session only by
-        // combining it with the per session random number `anon_id_seed`. This hash only need
-        // to map the dependencies to a single value on a per session basis.
-        task_deps.reads.hash(&mut hasher);
-
-        let target_dep_node = DepNode {
-            kind,
-
-            // Fingerprint::combine() is faster than sending Fingerprint
-            // through the StableHasher (at least as long as StableHasher
-            // is so slow).
-            hash: self.anon_id_seed.combine(hasher.finish()),
-        };
-
-        self.intern_node(target_dep_node, task_deps.reads, Fingerprint::ZERO)
-    }
-
-    fn alloc_node(
-        &self,
-        dep_node: DepNode,
-        edges: SmallVec<[DepNodeIndex; 8]>,
-        fingerprint: Fingerprint,
-    ) -> DepNodeIndex {
-        debug_assert!(
-            !self.node_to_node_index.get_shard_by_value(&dep_node).lock().contains_key(&dep_node)
-        );
-        self.intern_node(dep_node, edges, fingerprint)
-    }
-
-    fn intern_node(
-        &self,
-        dep_node: DepNode,
-        edges: SmallVec<[DepNodeIndex; 8]>,
-        fingerprint: Fingerprint,
-    ) -> DepNodeIndex {
-        match self.node_to_node_index.get_shard_by_value(&dep_node).lock().entry(dep_node) {
-            Entry::Occupied(entry) => *entry.get(),
-            Entry::Vacant(entry) => {
-                let mut data = self.data.lock();
-                let dep_node_index = DepNodeIndex::new(data.len());
-                data.push(DepNodeData { node: dep_node, edges, fingerprint });
-                entry.insert(dep_node_index);
-                dep_node_index
-            }
-        }
-    }
-}
-
-impl DepGraphData {
-    #[inline(never)]
-    fn read_index(&self, source: DepNodeIndex) {
-        ty::tls::with_context_opt(|icx| {
-            let icx = if let Some(icx) = icx { icx } else { return };
-            if let Some(task_deps) = icx.task_deps {
-                let mut task_deps = task_deps.lock();
-                if cfg!(debug_assertions) {
-                    self.current.total_read_count.fetch_add(1, Relaxed);
-                }
-                if task_deps.read_set.insert(source) {
-                    task_deps.reads.push(source);
-
-                    #[cfg(debug_assertions)]
-                    {
-                        if let Some(target) = task_deps.node {
-                            let data = self.current.data.lock();
-                            if let Some(ref forbidden_edge) = self.current.forbidden_edge {
-                                let source = data[source].node;
-                                if forbidden_edge.test(&source, &target) {
-                                    bug!("forbidden edge {:?} -> {:?} created", source, target)
-                                }
-                            }
-                        }
-                    }
-                } else if cfg!(debug_assertions) {
-                    self.current.total_duplicate_read_count.fetch_add(1, Relaxed);
-                }
-            }
-        })
-    }
-}
-
-pub struct TaskDeps {
-    #[cfg(debug_assertions)]
-    node: Option<DepNode>,
-    reads: SmallVec<[DepNodeIndex; 8]>,
-    read_set: FxHashSet<DepNodeIndex>,
-}
-
-// A data structure that stores Option<DepNodeColor> values as a contiguous
-// array, using one u32 per entry.
-struct DepNodeColorMap {
-    values: IndexVec<SerializedDepNodeIndex, AtomicU32>,
-}
-
-const COMPRESSED_NONE: u32 = 0;
-const COMPRESSED_RED: u32 = 1;
-const COMPRESSED_FIRST_GREEN: u32 = 2;
-
-impl DepNodeColorMap {
-    fn new(size: usize) -> DepNodeColorMap {
-        DepNodeColorMap { values: (0..size).map(|_| AtomicU32::new(COMPRESSED_NONE)).collect() }
-    }
-
-    fn get(&self, index: SerializedDepNodeIndex) -> Option<DepNodeColor> {
-        match self.values[index].load(Ordering::Acquire) {
-            COMPRESSED_NONE => None,
-            COMPRESSED_RED => Some(DepNodeColor::Red),
-            value => {
-                Some(DepNodeColor::Green(DepNodeIndex::from_u32(value - COMPRESSED_FIRST_GREEN)))
-            }
-        }
-    }
-
-    fn insert(&self, index: SerializedDepNodeIndex, color: DepNodeColor) {
-        self.values[index].store(
-            match color {
-                DepNodeColor::Red => COMPRESSED_RED,
-                DepNodeColor::Green(index) => index.as_u32() + COMPRESSED_FIRST_GREEN,
-            },
-            Ordering::Release,
-        )
-    }
-}
diff --git a/src/librustc/dep_graph/mod.rs b/src/librustc/dep_graph/mod.rs
deleted file mode 100644
index eb377d20f59..00000000000
--- a/src/librustc/dep_graph/mod.rs
+++ /dev/null
@@ -1,16 +0,0 @@
-pub mod debug;
-mod dep_node;
-mod graph;
-mod prev;
-mod query;
-mod safe;
-mod serialized;
-
-pub use self::dep_node::{label_strs, DepConstructor, DepKind, DepNode, RecoverKey, WorkProductId};
-pub use self::graph::WorkProductFileKind;
-pub use self::graph::{hash_result, DepGraph, DepNodeColor, DepNodeIndex, TaskDeps, WorkProduct};
-pub use self::prev::PreviousDepGraph;
-pub use self::query::DepGraphQuery;
-pub use self::safe::AssertDepGraphSafe;
-pub use self::safe::DepGraphSafe;
-pub use self::serialized::{SerializedDepGraph, SerializedDepNodeIndex};
diff --git a/src/librustc/dep_graph/prev.rs b/src/librustc/dep_graph/prev.rs
deleted file mode 100644
index fbc8f7bc997..00000000000
--- a/src/librustc/dep_graph/prev.rs
+++ /dev/null
@@ -1,55 +0,0 @@
-use super::dep_node::DepNode;
-use super::serialized::{SerializedDepGraph, SerializedDepNodeIndex};
-use crate::ich::Fingerprint;
-use rustc_data_structures::fx::FxHashMap;
-
-#[derive(Debug, RustcEncodable, RustcDecodable, Default)]
-pub struct PreviousDepGraph {
-    data: SerializedDepGraph,
-    index: FxHashMap<DepNode, SerializedDepNodeIndex>,
-}
-
-impl PreviousDepGraph {
-    pub fn new(data: SerializedDepGraph) -> PreviousDepGraph {
-        let index: FxHashMap<_, _> =
-            data.nodes.iter_enumerated().map(|(idx, &dep_node)| (dep_node, idx)).collect();
-        PreviousDepGraph { data, index }
-    }
-
-    #[inline]
-    pub fn edge_targets_from(
-        &self,
-        dep_node_index: SerializedDepNodeIndex,
-    ) -> &[SerializedDepNodeIndex] {
-        self.data.edge_targets_from(dep_node_index)
-    }
-
-    #[inline]
-    pub fn index_to_node(&self, dep_node_index: SerializedDepNodeIndex) -> DepNode {
-        self.data.nodes[dep_node_index]
-    }
-
-    #[inline]
-    pub fn node_to_index(&self, dep_node: &DepNode) -> SerializedDepNodeIndex {
-        self.index[dep_node]
-    }
-
-    #[inline]
-    pub fn node_to_index_opt(&self, dep_node: &DepNode) -> Option<SerializedDepNodeIndex> {
-        self.index.get(dep_node).cloned()
-    }
-
-    #[inline]
-    pub fn fingerprint_of(&self, dep_node: &DepNode) -> Option<Fingerprint> {
-        self.index.get(dep_node).map(|&node_index| self.data.fingerprints[node_index])
-    }
-
-    #[inline]
-    pub fn fingerprint_by_index(&self, dep_node_index: SerializedDepNodeIndex) -> Fingerprint {
-        self.data.fingerprints[dep_node_index]
-    }
-
-    pub fn node_count(&self) -> usize {
-        self.index.len()
-    }
-}
diff --git a/src/librustc/dep_graph/query.rs b/src/librustc/dep_graph/query.rs
deleted file mode 100644
index c71c11ed0eb..00000000000
--- a/src/librustc/dep_graph/query.rs
+++ /dev/null
@@ -1,74 +0,0 @@
-use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::graph::implementation::{
-    Direction, Graph, NodeIndex, INCOMING, OUTGOING,
-};
-
-use super::DepNode;
-
-pub struct DepGraphQuery {
-    pub graph: Graph<DepNode, ()>,
-    pub indices: FxHashMap<DepNode, NodeIndex>,
-}
-
-impl DepGraphQuery {
-    pub fn new(nodes: &[DepNode], edges: &[(DepNode, DepNode)]) -> DepGraphQuery {
-        let mut graph = Graph::with_capacity(nodes.len(), edges.len());
-        let mut indices = FxHashMap::default();
-        for node in nodes {
-            indices.insert(node.clone(), graph.add_node(node.clone()));
-        }
-
-        for &(ref source, ref target) in edges {
-            let source = indices[source];
-            let target = indices[target];
-            graph.add_edge(source, target, ());
-        }
-
-        DepGraphQuery { graph, indices }
-    }
-
-    pub fn contains_node(&self, node: &DepNode) -> bool {
-        self.indices.contains_key(&node)
-    }
-
-    pub fn nodes(&self) -> Vec<&DepNode> {
-        self.graph.all_nodes().iter().map(|n| &n.data).collect()
-    }
-
-    pub fn edges(&self) -> Vec<(&DepNode, &DepNode)> {
-        self.graph
-            .all_edges()
-            .iter()
-            .map(|edge| (edge.source(), edge.target()))
-            .map(|(s, t)| (self.graph.node_data(s), self.graph.node_data(t)))
-            .collect()
-    }
-
-    fn reachable_nodes(&self, node: &DepNode, direction: Direction) -> Vec<&DepNode> {
-        if let Some(&index) = self.indices.get(node) {
-            self.graph.depth_traverse(index, direction).map(|s| self.graph.node_data(s)).collect()
-        } else {
-            vec![]
-        }
-    }
-
-    /// All nodes reachable from `node`. In other words, things that
-    /// will have to be recomputed if `node` changes.
-    pub fn transitive_successors(&self, node: &DepNode) -> Vec<&DepNode> {
-        self.reachable_nodes(node, OUTGOING)
-    }
-
-    /// All nodes that can reach `node`.
-    pub fn transitive_predecessors(&self, node: &DepNode) -> Vec<&DepNode> {
-        self.reachable_nodes(node, INCOMING)
-    }
-
-    /// Just the outgoing edges from `node`.
-    pub fn immediate_successors(&self, node: &DepNode) -> Vec<&DepNode> {
-        if let Some(&index) = self.indices.get(&node) {
-            self.graph.successor_nodes(index).map(|s| self.graph.node_data(s)).collect()
-        } else {
-            vec![]
-        }
-    }
-}
diff --git a/src/librustc/dep_graph/safe.rs b/src/librustc/dep_graph/safe.rs
deleted file mode 100644
index 23aef0c4298..00000000000
--- a/src/librustc/dep_graph/safe.rs
+++ /dev/null
@@ -1,57 +0,0 @@
-//! The `DepGraphSafe` trait
-
-use crate::ty::TyCtxt;
-
-use rustc_hir::def_id::DefId;
-use rustc_hir::BodyId;
-use syntax::ast::NodeId;
-
-/// The `DepGraphSafe` trait is used to specify what kinds of values
-/// are safe to "leak" into a task. The idea is that this should be
-/// only be implemented for things like the tcx as well as various id
-/// types, which will create reads in the dep-graph whenever the trait
-/// loads anything that might depend on the input program.
-pub trait DepGraphSafe {}
-
-/// A `BodyId` on its own doesn't give access to any particular state.
-/// You must fetch the state from the various maps or generate
-/// on-demand queries, all of which create reads.
-impl DepGraphSafe for BodyId {}
-
-/// A `NodeId` on its own doesn't give access to any particular state.
-/// You must fetch the state from the various maps or generate
-/// on-demand queries, all of which create reads.
-impl DepGraphSafe for NodeId {}
-
-/// A `DefId` on its own doesn't give access to any particular state.
-/// You must fetch the state from the various maps or generate
-/// on-demand queries, all of which create reads.
-impl DepGraphSafe for DefId {}
-
-/// The type context itself can be used to access all kinds of tracked
-/// state, but those accesses should always generate read events.
-impl<'tcx> DepGraphSafe for TyCtxt<'tcx> {}
-
-/// Tuples make it easy to build up state.
-impl<A, B> DepGraphSafe for (A, B)
-where
-    A: DepGraphSafe,
-    B: DepGraphSafe,
-{
-}
-
-/// Shared ref to dep-graph-safe stuff should still be dep-graph-safe.
-impl<'a, A> DepGraphSafe for &'a A where A: DepGraphSafe {}
-
-/// Mut ref to dep-graph-safe stuff should still be dep-graph-safe.
-impl<'a, A> DepGraphSafe for &'a mut A where A: DepGraphSafe {}
-
-/// No data here! :)
-impl DepGraphSafe for () {}
-
-/// A convenient override that lets you pass arbitrary state into a
-/// task. Every use should be accompanied by a comment explaining why
-/// it makes sense (or how it could be refactored away in the future).
-pub struct AssertDepGraphSafe<T>(pub T);
-
-impl<T> DepGraphSafe for AssertDepGraphSafe<T> {}
diff --git a/src/librustc/dep_graph/serialized.rs b/src/librustc/dep_graph/serialized.rs
deleted file mode 100644
index 45ef52dbf39..00000000000
--- a/src/librustc/dep_graph/serialized.rs
+++ /dev/null
@@ -1,34 +0,0 @@
-//! The data that we will serialize and deserialize.
-
-use crate::dep_graph::DepNode;
-use crate::ich::Fingerprint;
-use rustc_index::vec::IndexVec;
-
-rustc_index::newtype_index! {
-    pub struct SerializedDepNodeIndex { .. }
-}
-
-/// Data for use when recompiling the **current crate**.
-#[derive(Debug, RustcEncodable, RustcDecodable, Default)]
-pub struct SerializedDepGraph {
-    /// The set of all DepNodes in the graph
-    pub nodes: IndexVec<SerializedDepNodeIndex, DepNode>,
-    /// The set of all Fingerprints in the graph. Each Fingerprint corresponds to
-    /// the DepNode at the same index in the nodes vector.
-    pub fingerprints: IndexVec<SerializedDepNodeIndex, Fingerprint>,
-    /// For each DepNode, stores the list of edges originating from that
-    /// DepNode. Encoded as a [start, end) pair indexing into edge_list_data,
-    /// which holds the actual DepNodeIndices of the target nodes.
-    pub edge_list_indices: IndexVec<SerializedDepNodeIndex, (u32, u32)>,
-    /// A flattened list of all edge targets in the graph. Edge sources are
-    /// implicit in edge_list_indices.
-    pub edge_list_data: Vec<SerializedDepNodeIndex>,
-}
-
-impl SerializedDepGraph {
-    #[inline]
-    pub fn edge_targets_from(&self, source: SerializedDepNodeIndex) -> &[SerializedDepNodeIndex] {
-        let targets = self.edge_list_indices[source];
-        &self.edge_list_data[targets.0 as usize..targets.1 as usize]
-    }
-}
diff --git a/src/librustc/hir/exports.rs b/src/librustc/hir/exports.rs
deleted file mode 100644
index db020e39e8e..00000000000
--- a/src/librustc/hir/exports.rs
+++ /dev/null
@@ -1,32 +0,0 @@
-use crate::ty;
-
-use rustc_hir::def::Res;
-use rustc_hir::def_id::DefIdMap;
-use rustc_macros::HashStable;
-use rustc_span::Span;
-use syntax::ast;
-
-use std::fmt::Debug;
-
-/// This is the replacement export map. It maps a module to all of the exports
-/// within.
-pub type ExportMap<Id> = DefIdMap<Vec<Export<Id>>>;
-
-#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
-pub struct Export<Id> {
-    /// The name of the target.
-    pub ident: ast::Ident,
-    /// The resolution of the target.
-    pub res: Res<Id>,
-    /// The span of the target.
-    pub span: Span,
-    /// The visibility of the export.
-    /// We include non-`pub` exports for hygienic macros that get used from extern crates.
-    pub vis: ty::Visibility,
-}
-
-impl<Id> Export<Id> {
-    pub fn map_id<R>(self, map: impl FnMut(Id) -> R) -> Export<R> {
-        Export { ident: self.ident, res: self.res.map_id(map), span: self.span, vis: self.vis }
-    }
-}
diff --git a/src/librustc/hir/map/blocks.rs b/src/librustc/hir/map/blocks.rs
deleted file mode 100644
index 016fc939a7a..00000000000
--- a/src/librustc/hir/map/blocks.rs
+++ /dev/null
@@ -1,262 +0,0 @@
-//! This module provides a simplified abstraction for working with
-//! code blocks identified by their integer `NodeId`. In particular,
-//! it captures a common set of attributes that all "function-like
-//! things" (represented by `FnLike` instances) share. For example,
-//! all `FnLike` instances have a type signature (be it explicit or
-//! inferred). And all `FnLike` instances have a body, i.e., the code
-//! that is run when the function-like thing it represents is invoked.
-//!
-//! With the above abstraction in place, one can treat the program
-//! text as a collection of blocks of code (and most such blocks are
-//! nested within a uniquely determined `FnLike`), and users can ask
-//! for the `Code` associated with a particular NodeId.
-
-use crate::hir::map::Map;
-use rustc_hir as hir;
-use rustc_hir::intravisit::FnKind;
-use rustc_hir::{Expr, FnDecl, Node};
-use rustc_span::Span;
-use syntax::ast::{Attribute, Ident};
-
-/// An FnLikeNode is a Node that is like a fn, in that it has a decl
-/// and a body (as well as a NodeId, a span, etc).
-///
-/// More specifically, it is one of either:
-///
-///   - A function item,
-///   - A closure expr (i.e., an ExprKind::Closure), or
-///   - The default implementation for a trait method.
-///
-/// To construct one, use the `Code::from_node` function.
-#[derive(Copy, Clone, Debug)]
-pub struct FnLikeNode<'a> {
-    node: Node<'a>,
-}
-
-/// MaybeFnLike wraps a method that indicates if an object
-/// corresponds to some FnLikeNode.
-trait MaybeFnLike {
-    fn is_fn_like(&self) -> bool;
-}
-
-impl MaybeFnLike for hir::Item<'_> {
-    fn is_fn_like(&self) -> bool {
-        match self.kind {
-            hir::ItemKind::Fn(..) => true,
-            _ => false,
-        }
-    }
-}
-
-impl MaybeFnLike for hir::ImplItem<'_> {
-    fn is_fn_like(&self) -> bool {
-        match self.kind {
-            hir::ImplItemKind::Method(..) => true,
-            _ => false,
-        }
-    }
-}
-
-impl MaybeFnLike for hir::TraitItem<'_> {
-    fn is_fn_like(&self) -> bool {
-        match self.kind {
-            hir::TraitItemKind::Method(_, hir::TraitMethod::Provided(_)) => true,
-            _ => false,
-        }
-    }
-}
-
-impl MaybeFnLike for hir::Expr<'_> {
-    fn is_fn_like(&self) -> bool {
-        match self.kind {
-            hir::ExprKind::Closure(..) => true,
-            _ => false,
-        }
-    }
-}
-
-/// Carries either an FnLikeNode or a Expr, as these are the two
-/// constructs that correspond to "code" (as in, something from which
-/// we can construct a control-flow graph).
-#[derive(Copy, Clone)]
-pub enum Code<'a> {
-    FnLike(FnLikeNode<'a>),
-    Expr(&'a Expr<'a>),
-}
-
-impl<'a> Code<'a> {
-    pub fn id(&self) -> hir::HirId {
-        match *self {
-            Code::FnLike(node) => node.id(),
-            Code::Expr(block) => block.hir_id,
-        }
-    }
-
-    /// Attempts to construct a Code from presumed FnLike or Expr node input.
-    pub fn from_node(map: &Map<'a>, id: hir::HirId) -> Option<Code<'a>> {
-        match map.get(id) {
-            Node::Block(_) => {
-                //  Use the parent, hopefully an expression node.
-                Code::from_node(map, map.get_parent_node(id))
-            }
-            Node::Expr(expr) => Some(Code::Expr(expr)),
-            node => FnLikeNode::from_node(node).map(Code::FnLike),
-        }
-    }
-}
-
-/// These are all the components one can extract from a fn item for
-/// use when implementing FnLikeNode operations.
-struct ItemFnParts<'a> {
-    ident: Ident,
-    decl: &'a hir::FnDecl<'a>,
-    header: hir::FnHeader,
-    vis: &'a hir::Visibility<'a>,
-    generics: &'a hir::Generics<'a>,
-    body: hir::BodyId,
-    id: hir::HirId,
-    span: Span,
-    attrs: &'a [Attribute],
-}
-
-/// These are all the components one can extract from a closure expr
-/// for use when implementing FnLikeNode operations.
-struct ClosureParts<'a> {
-    decl: &'a FnDecl<'a>,
-    body: hir::BodyId,
-    id: hir::HirId,
-    span: Span,
-    attrs: &'a [Attribute],
-}
-
-impl<'a> ClosureParts<'a> {
-    fn new(
-        d: &'a FnDecl<'a>,
-        b: hir::BodyId,
-        id: hir::HirId,
-        s: Span,
-        attrs: &'a [Attribute],
-    ) -> Self {
-        ClosureParts { decl: d, body: b, id, span: s, attrs }
-    }
-}
-
-impl<'a> FnLikeNode<'a> {
-    /// Attempts to construct a FnLikeNode from presumed FnLike node input.
-    pub fn from_node(node: Node<'_>) -> Option<FnLikeNode<'_>> {
-        let fn_like = match node {
-            Node::Item(item) => item.is_fn_like(),
-            Node::TraitItem(tm) => tm.is_fn_like(),
-            Node::ImplItem(it) => it.is_fn_like(),
-            Node::Expr(e) => e.is_fn_like(),
-            _ => false,
-        };
-        fn_like.then_some(FnLikeNode { node })
-    }
-
-    pub fn body(self) -> hir::BodyId {
-        self.handle(
-            |i: ItemFnParts<'a>| i.body,
-            |_, _, _: &'a hir::FnSig<'a>, _, body: hir::BodyId, _, _| body,
-            |c: ClosureParts<'a>| c.body,
-        )
-    }
-
-    pub fn decl(self) -> &'a FnDecl<'a> {
-        self.handle(
-            |i: ItemFnParts<'a>| &*i.decl,
-            |_, _, sig: &'a hir::FnSig<'a>, _, _, _, _| &sig.decl,
-            |c: ClosureParts<'a>| c.decl,
-        )
-    }
-
-    pub fn span(self) -> Span {
-        self.handle(
-            |i: ItemFnParts<'_>| i.span,
-            |_, _, _: &'a hir::FnSig<'a>, _, _, span, _| span,
-            |c: ClosureParts<'_>| c.span,
-        )
-    }
-
-    pub fn id(self) -> hir::HirId {
-        self.handle(
-            |i: ItemFnParts<'_>| i.id,
-            |id, _, _: &'a hir::FnSig<'a>, _, _, _, _| id,
-            |c: ClosureParts<'_>| c.id,
-        )
-    }
-
-    pub fn constness(self) -> hir::Constness {
-        self.kind().header().map_or(hir::Constness::NotConst, |header| header.constness)
-    }
-
-    pub fn asyncness(self) -> hir::IsAsync {
-        self.kind().header().map_or(hir::IsAsync::NotAsync, |header| header.asyncness)
-    }
-
-    pub fn unsafety(self) -> hir::Unsafety {
-        self.kind().header().map_or(hir::Unsafety::Normal, |header| header.unsafety)
-    }
-
-    pub fn kind(self) -> FnKind<'a> {
-        let item = |p: ItemFnParts<'a>| -> FnKind<'a> {
-            FnKind::ItemFn(p.ident, p.generics, p.header, p.vis, p.attrs)
-        };
-        let closure = |c: ClosureParts<'a>| FnKind::Closure(c.attrs);
-        let method = |_, ident: Ident, sig: &'a hir::FnSig<'a>, vis, _, _, attrs| {
-            FnKind::Method(ident, sig, vis, attrs)
-        };
-        self.handle(item, method, closure)
-    }
-
-    fn handle<A, I, M, C>(self, item_fn: I, method: M, closure: C) -> A
-    where
-        I: FnOnce(ItemFnParts<'a>) -> A,
-        M: FnOnce(
-            hir::HirId,
-            Ident,
-            &'a hir::FnSig<'a>,
-            Option<&'a hir::Visibility<'a>>,
-            hir::BodyId,
-            Span,
-            &'a [Attribute],
-        ) -> A,
-        C: FnOnce(ClosureParts<'a>) -> A,
-    {
-        match self.node {
-            Node::Item(i) => match i.kind {
-                hir::ItemKind::Fn(ref sig, ref generics, block) => item_fn(ItemFnParts {
-                    id: i.hir_id,
-                    ident: i.ident,
-                    decl: &sig.decl,
-                    body: block,
-                    vis: &i.vis,
-                    span: i.span,
-                    attrs: &i.attrs,
-                    header: sig.header,
-                    generics,
-                }),
-                _ => bug!("item FnLikeNode that is not fn-like"),
-            },
-            Node::TraitItem(ti) => match ti.kind {
-                hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Provided(body)) => {
-                    method(ti.hir_id, ti.ident, sig, None, body, ti.span, &ti.attrs)
-                }
-                _ => bug!("trait method FnLikeNode that is not fn-like"),
-            },
-            Node::ImplItem(ii) => match ii.kind {
-                hir::ImplItemKind::Method(ref sig, body) => {
-                    method(ii.hir_id, ii.ident, sig, Some(&ii.vis), body, ii.span, &ii.attrs)
-                }
-                _ => bug!("impl method FnLikeNode that is not fn-like"),
-            },
-            Node::Expr(e) => match e.kind {
-                hir::ExprKind::Closure(_, ref decl, block, _fn_decl_span, _gen) => {
-                    closure(ClosureParts::new(&decl, block, e.hir_id, e.span, &e.attrs))
-                }
-                _ => bug!("expr FnLikeNode that is not fn-like"),
-            },
-            _ => bug!("other FnLikeNode that is not fn-like"),
-        }
-    }
-}
diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs
deleted file mode 100644
index bf1fc09649a..00000000000
--- a/src/librustc/hir/map/collector.rs
+++ /dev/null
@@ -1,603 +0,0 @@
-use crate::dep_graph::{DepGraph, DepKind, DepNode, DepNodeIndex};
-use crate::hir::map::definitions::{self, DefPathHash};
-use crate::hir::map::{Entry, HirEntryMap, Map};
-use crate::ich::StableHashingContext;
-use crate::middle::cstore::CrateStore;
-use rustc_data_structures::fingerprint::Fingerprint;
-use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
-use rustc_data_structures::svh::Svh;
-use rustc_hir as hir;
-use rustc_hir::def_id::CRATE_DEF_INDEX;
-use rustc_hir::def_id::{CrateNum, DefIndex, LOCAL_CRATE};
-use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
-use rustc_hir::*;
-use rustc_index::vec::IndexVec;
-use rustc_session::{CrateDisambiguator, Session};
-use rustc_span::source_map::SourceMap;
-use rustc_span::{Span, Symbol, DUMMY_SP};
-use syntax::ast::NodeId;
-
-use std::iter::repeat;
-
-/// A visitor that walks over the HIR and collects `Node`s into a HIR map.
-pub(super) struct NodeCollector<'a, 'hir> {
-    /// The crate
-    krate: &'hir Crate<'hir>,
-
-    /// Source map
-    source_map: &'a SourceMap,
-
-    /// The node map
-    map: HirEntryMap<'hir>,
-    /// The parent of this node
-    parent_node: hir::HirId,
-
-    // These fields keep track of the currently relevant DepNodes during
-    // the visitor's traversal.
-    current_dep_node_owner: DefIndex,
-    current_signature_dep_index: DepNodeIndex,
-    current_full_dep_index: DepNodeIndex,
-    currently_in_body: bool,
-
-    dep_graph: &'a DepGraph,
-    definitions: &'a definitions::Definitions,
-    hir_to_node_id: &'a FxHashMap<HirId, NodeId>,
-
-    hcx: StableHashingContext<'a>,
-
-    // We are collecting `DepNode::HirBody` hashes here so we can compute the
-    // crate hash from then later on.
-    hir_body_nodes: Vec<(DefPathHash, Fingerprint)>,
-}
-
-fn input_dep_node_and_hash(
-    dep_graph: &DepGraph,
-    hcx: &mut StableHashingContext<'_>,
-    dep_node: DepNode,
-    input: impl for<'a> HashStable<StableHashingContext<'a>>,
-) -> (DepNodeIndex, Fingerprint) {
-    let dep_node_index = dep_graph.input_task(dep_node, &mut *hcx, &input).1;
-
-    let hash = if dep_graph.is_fully_enabled() {
-        dep_graph.fingerprint_of(dep_node_index)
-    } else {
-        let mut stable_hasher = StableHasher::new();
-        input.hash_stable(hcx, &mut stable_hasher);
-        stable_hasher.finish()
-    };
-
-    (dep_node_index, hash)
-}
-
-fn alloc_hir_dep_nodes(
-    dep_graph: &DepGraph,
-    hcx: &mut StableHashingContext<'_>,
-    def_path_hash: DefPathHash,
-    item_like: impl for<'a> HashStable<StableHashingContext<'a>>,
-    hir_body_nodes: &mut Vec<(DefPathHash, Fingerprint)>,
-) -> (DepNodeIndex, DepNodeIndex) {
-    let sig = dep_graph
-        .input_task(
-            def_path_hash.to_dep_node(DepKind::Hir),
-            &mut *hcx,
-            HirItemLike { item_like: &item_like, hash_bodies: false },
-        )
-        .1;
-    let (full, hash) = input_dep_node_and_hash(
-        dep_graph,
-        hcx,
-        def_path_hash.to_dep_node(DepKind::HirBody),
-        HirItemLike { item_like: &item_like, hash_bodies: true },
-    );
-    hir_body_nodes.push((def_path_hash, hash));
-    (sig, full)
-}
-
-fn upstream_crates(cstore: &dyn CrateStore) -> Vec<(Symbol, Fingerprint, Svh)> {
-    let mut upstream_crates: Vec<_> = cstore
-        .crates_untracked()
-        .iter()
-        .map(|&cnum| {
-            let name = cstore.crate_name_untracked(cnum);
-            let disambiguator = cstore.crate_disambiguator_untracked(cnum).to_fingerprint();
-            let hash = cstore.crate_hash_untracked(cnum);
-            (name, disambiguator, hash)
-        })
-        .collect();
-    upstream_crates.sort_unstable_by_key(|&(name, dis, _)| (name.as_str(), dis));
-    upstream_crates
-}
-
-impl<'a, 'hir> NodeCollector<'a, 'hir> {
-    pub(super) fn root(
-        sess: &'a Session,
-        krate: &'hir Crate<'hir>,
-        dep_graph: &'a DepGraph,
-        definitions: &'a definitions::Definitions,
-        hir_to_node_id: &'a FxHashMap<HirId, NodeId>,
-        mut hcx: StableHashingContext<'a>,
-    ) -> NodeCollector<'a, 'hir> {
-        let root_mod_def_path_hash = definitions.def_path_hash(CRATE_DEF_INDEX);
-
-        let mut hir_body_nodes = Vec::new();
-
-        // Allocate `DepNode`s for the root module.
-        let (root_mod_sig_dep_index, root_mod_full_dep_index) = {
-            let Crate {
-                ref module,
-                // Crate attributes are not copied over to the root `Mod`, so hash
-                // them explicitly here.
-                ref attrs,
-                span,
-                // These fields are handled separately:
-                exported_macros: _,
-                non_exported_macro_attrs: _,
-                items: _,
-                trait_items: _,
-                impl_items: _,
-                bodies: _,
-                trait_impls: _,
-                body_ids: _,
-                modules: _,
-                proc_macros: _,
-            } = *krate;
-
-            alloc_hir_dep_nodes(
-                dep_graph,
-                &mut hcx,
-                root_mod_def_path_hash,
-                (module, attrs, span),
-                &mut hir_body_nodes,
-            )
-        };
-
-        {
-            dep_graph.input_task(
-                DepNode::new_no_params(DepKind::AllLocalTraitImpls),
-                &mut hcx,
-                &krate.trait_impls,
-            );
-        }
-
-        let mut collector = NodeCollector {
-            krate,
-            source_map: sess.source_map(),
-            map: IndexVec::from_elem_n(IndexVec::new(), definitions.def_index_count()),
-            parent_node: hir::CRATE_HIR_ID,
-            current_signature_dep_index: root_mod_sig_dep_index,
-            current_full_dep_index: root_mod_full_dep_index,
-            current_dep_node_owner: CRATE_DEF_INDEX,
-            currently_in_body: false,
-            dep_graph,
-            definitions,
-            hir_to_node_id,
-            hcx,
-            hir_body_nodes,
-        };
-        collector.insert_entry(
-            hir::CRATE_HIR_ID,
-            Entry {
-                parent: hir::CRATE_HIR_ID,
-                dep_node: root_mod_sig_dep_index,
-                node: Node::Crate,
-            },
-        );
-
-        collector
-    }
-
-    pub(super) fn finalize_and_compute_crate_hash(
-        mut self,
-        crate_disambiguator: CrateDisambiguator,
-        cstore: &dyn CrateStore,
-        commandline_args_hash: u64,
-    ) -> (HirEntryMap<'hir>, Svh) {
-        self.hir_body_nodes.sort_unstable_by_key(|bn| bn.0);
-
-        let node_hashes = self.hir_body_nodes.iter().fold(
-            Fingerprint::ZERO,
-            |combined_fingerprint, &(def_path_hash, fingerprint)| {
-                combined_fingerprint.combine(def_path_hash.0.combine(fingerprint))
-            },
-        );
-
-        let upstream_crates = upstream_crates(cstore);
-
-        // We hash the final, remapped names of all local source files so we
-        // don't have to include the path prefix remapping commandline args.
-        // If we included the full mapping in the SVH, we could only have
-        // reproducible builds by compiling from the same directory. So we just
-        // hash the result of the mapping instead of the mapping itself.
-        let mut source_file_names: Vec<_> = self
-            .source_map
-            .files()
-            .iter()
-            .filter(|source_file| CrateNum::from_u32(source_file.crate_of_origin) == LOCAL_CRATE)
-            .map(|source_file| source_file.name_hash)
-            .collect();
-
-        source_file_names.sort_unstable();
-
-        let crate_hash_input = (
-            ((node_hashes, upstream_crates), source_file_names),
-            (commandline_args_hash, crate_disambiguator.to_fingerprint()),
-        );
-
-        let mut stable_hasher = StableHasher::new();
-        crate_hash_input.hash_stable(&mut self.hcx, &mut stable_hasher);
-        let crate_hash: Fingerprint = stable_hasher.finish();
-
-        let svh = Svh::new(crate_hash.to_smaller_hash());
-        (self.map, svh)
-    }
-
-    fn insert_entry(&mut self, id: HirId, entry: Entry<'hir>) {
-        debug!("hir_map: {:?} => {:?}", id, entry);
-        let local_map = &mut self.map[id.owner];
-        let i = id.local_id.as_u32() as usize;
-        let len = local_map.len();
-        if i >= len {
-            local_map.extend(repeat(None).take(i - len + 1));
-        }
-        local_map[id.local_id] = Some(entry);
-    }
-
-    fn insert(&mut self, span: Span, hir_id: HirId, node: Node<'hir>) {
-        let entry = Entry {
-            parent: self.parent_node,
-            dep_node: if self.currently_in_body {
-                self.current_full_dep_index
-            } else {
-                self.current_signature_dep_index
-            },
-            node,
-        };
-
-        // Make sure that the DepNode of some node coincides with the HirId
-        // owner of that node.
-        if cfg!(debug_assertions) {
-            let node_id = self.hir_to_node_id[&hir_id];
-            assert_eq!(self.definitions.node_to_hir_id(node_id), hir_id);
-
-            if hir_id.owner != self.current_dep_node_owner {
-                let node_str = match self.definitions.opt_def_index(node_id) {
-                    Some(def_index) => self.definitions.def_path(def_index).to_string_no_crate(),
-                    None => format!("{:?}", node),
-                };
-
-                let forgot_str = if hir_id == hir::DUMMY_HIR_ID {
-                    format!("\nMaybe you forgot to lower the node id {:?}?", node_id)
-                } else {
-                    String::new()
-                };
-
-                span_bug!(
-                    span,
-                    "inconsistent DepNode at `{:?}` for `{}`: \
-                     current_dep_node_owner={} ({:?}), hir_id.owner={} ({:?}){}",
-                    self.source_map.span_to_string(span),
-                    node_str,
-                    self.definitions.def_path(self.current_dep_node_owner).to_string_no_crate(),
-                    self.current_dep_node_owner,
-                    self.definitions.def_path(hir_id.owner).to_string_no_crate(),
-                    hir_id.owner,
-                    forgot_str,
-                )
-            }
-        }
-
-        self.insert_entry(hir_id, entry);
-    }
-
-    fn with_parent<F: FnOnce(&mut Self)>(&mut self, parent_node_id: HirId, f: F) {
-        let parent_node = self.parent_node;
-        self.parent_node = parent_node_id;
-        f(self);
-        self.parent_node = parent_node;
-    }
-
-    fn with_dep_node_owner<
-        T: for<'b> HashStable<StableHashingContext<'b>>,
-        F: FnOnce(&mut Self),
-    >(
-        &mut self,
-        dep_node_owner: DefIndex,
-        item_like: &T,
-        f: F,
-    ) {
-        let prev_owner = self.current_dep_node_owner;
-        let prev_signature_dep_index = self.current_signature_dep_index;
-        let prev_full_dep_index = self.current_full_dep_index;
-        let prev_in_body = self.currently_in_body;
-
-        let def_path_hash = self.definitions.def_path_hash(dep_node_owner);
-
-        let (signature_dep_index, full_dep_index) = alloc_hir_dep_nodes(
-            self.dep_graph,
-            &mut self.hcx,
-            def_path_hash,
-            item_like,
-            &mut self.hir_body_nodes,
-        );
-        self.current_signature_dep_index = signature_dep_index;
-        self.current_full_dep_index = full_dep_index;
-
-        self.current_dep_node_owner = dep_node_owner;
-        self.currently_in_body = false;
-        f(self);
-        self.currently_in_body = prev_in_body;
-        self.current_dep_node_owner = prev_owner;
-        self.current_full_dep_index = prev_full_dep_index;
-        self.current_signature_dep_index = prev_signature_dep_index;
-    }
-}
-
-impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
-    type Map = Map<'hir>;
-
-    /// Because we want to track parent items and so forth, enable
-    /// deep walking so that we walk nested items in the context of
-    /// their outer items.
-
-    fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, Self::Map> {
-        panic!("`visit_nested_xxx` must be manually implemented in this visitor");
-    }
-
-    fn visit_nested_item(&mut self, item: ItemId) {
-        debug!("visit_nested_item: {:?}", item);
-        self.visit_item(self.krate.item(item.id));
-    }
-
-    fn visit_nested_trait_item(&mut self, item_id: TraitItemId) {
-        self.visit_trait_item(self.krate.trait_item(item_id));
-    }
-
-    fn visit_nested_impl_item(&mut self, item_id: ImplItemId) {
-        self.visit_impl_item(self.krate.impl_item(item_id));
-    }
-
-    fn visit_nested_body(&mut self, id: BodyId) {
-        let prev_in_body = self.currently_in_body;
-        self.currently_in_body = true;
-        self.visit_body(self.krate.body(id));
-        self.currently_in_body = prev_in_body;
-    }
-
-    fn visit_param(&mut self, param: &'hir Param<'hir>) {
-        let node = Node::Param(param);
-        self.insert(param.pat.span, param.hir_id, node);
-        self.with_parent(param.hir_id, |this| {
-            intravisit::walk_param(this, param);
-        });
-    }
-
-    fn visit_item(&mut self, i: &'hir Item<'hir>) {
-        debug!("visit_item: {:?}", i);
-        debug_assert_eq!(
-            i.hir_id.owner,
-            self.definitions.opt_def_index(self.hir_to_node_id[&i.hir_id]).unwrap()
-        );
-        self.with_dep_node_owner(i.hir_id.owner, i, |this| {
-            this.insert(i.span, i.hir_id, Node::Item(i));
-            this.with_parent(i.hir_id, |this| {
-                if let ItemKind::Struct(ref struct_def, _) = i.kind {
-                    // If this is a tuple or unit-like struct, register the constructor.
-                    if let Some(ctor_hir_id) = struct_def.ctor_hir_id() {
-                        this.insert(i.span, ctor_hir_id, Node::Ctor(struct_def));
-                    }
-                }
-                intravisit::walk_item(this, i);
-            });
-        });
-    }
-
-    fn visit_foreign_item(&mut self, foreign_item: &'hir ForeignItem<'hir>) {
-        self.insert(foreign_item.span, foreign_item.hir_id, Node::ForeignItem(foreign_item));
-
-        self.with_parent(foreign_item.hir_id, |this| {
-            intravisit::walk_foreign_item(this, foreign_item);
-        });
-    }
-
-    fn visit_generic_param(&mut self, param: &'hir GenericParam<'hir>) {
-        self.insert(param.span, param.hir_id, Node::GenericParam(param));
-        intravisit::walk_generic_param(self, param);
-    }
-
-    fn visit_trait_item(&mut self, ti: &'hir TraitItem<'hir>) {
-        debug_assert_eq!(
-            ti.hir_id.owner,
-            self.definitions.opt_def_index(self.hir_to_node_id[&ti.hir_id]).unwrap()
-        );
-        self.with_dep_node_owner(ti.hir_id.owner, ti, |this| {
-            this.insert(ti.span, ti.hir_id, Node::TraitItem(ti));
-
-            this.with_parent(ti.hir_id, |this| {
-                intravisit::walk_trait_item(this, ti);
-            });
-        });
-    }
-
-    fn visit_impl_item(&mut self, ii: &'hir ImplItem<'hir>) {
-        debug_assert_eq!(
-            ii.hir_id.owner,
-            self.definitions.opt_def_index(self.hir_to_node_id[&ii.hir_id]).unwrap()
-        );
-        self.with_dep_node_owner(ii.hir_id.owner, ii, |this| {
-            this.insert(ii.span, ii.hir_id, Node::ImplItem(ii));
-
-            this.with_parent(ii.hir_id, |this| {
-                intravisit::walk_impl_item(this, ii);
-            });
-        });
-    }
-
-    fn visit_pat(&mut self, pat: &'hir Pat<'hir>) {
-        let node =
-            if let PatKind::Binding(..) = pat.kind { Node::Binding(pat) } else { Node::Pat(pat) };
-        self.insert(pat.span, pat.hir_id, node);
-
-        self.with_parent(pat.hir_id, |this| {
-            intravisit::walk_pat(this, pat);
-        });
-    }
-
-    fn visit_arm(&mut self, arm: &'hir Arm<'hir>) {
-        let node = Node::Arm(arm);
-
-        self.insert(arm.span, arm.hir_id, node);
-
-        self.with_parent(arm.hir_id, |this| {
-            intravisit::walk_arm(this, arm);
-        });
-    }
-
-    fn visit_anon_const(&mut self, constant: &'hir AnonConst) {
-        self.insert(DUMMY_SP, constant.hir_id, Node::AnonConst(constant));
-
-        self.with_parent(constant.hir_id, |this| {
-            intravisit::walk_anon_const(this, constant);
-        });
-    }
-
-    fn visit_expr(&mut self, expr: &'hir Expr<'hir>) {
-        self.insert(expr.span, expr.hir_id, Node::Expr(expr));
-
-        self.with_parent(expr.hir_id, |this| {
-            intravisit::walk_expr(this, expr);
-        });
-    }
-
-    fn visit_stmt(&mut self, stmt: &'hir Stmt<'hir>) {
-        self.insert(stmt.span, stmt.hir_id, Node::Stmt(stmt));
-
-        self.with_parent(stmt.hir_id, |this| {
-            intravisit::walk_stmt(this, stmt);
-        });
-    }
-
-    fn visit_path_segment(&mut self, path_span: Span, path_segment: &'hir PathSegment<'hir>) {
-        if let Some(hir_id) = path_segment.hir_id {
-            self.insert(path_span, hir_id, Node::PathSegment(path_segment));
-        }
-        intravisit::walk_path_segment(self, path_span, path_segment);
-    }
-
-    fn visit_ty(&mut self, ty: &'hir Ty<'hir>) {
-        self.insert(ty.span, ty.hir_id, Node::Ty(ty));
-
-        self.with_parent(ty.hir_id, |this| {
-            intravisit::walk_ty(this, ty);
-        });
-    }
-
-    fn visit_trait_ref(&mut self, tr: &'hir TraitRef<'hir>) {
-        self.insert(tr.path.span, tr.hir_ref_id, Node::TraitRef(tr));
-
-        self.with_parent(tr.hir_ref_id, |this| {
-            intravisit::walk_trait_ref(this, tr);
-        });
-    }
-
-    fn visit_fn(
-        &mut self,
-        fk: intravisit::FnKind<'hir>,
-        fd: &'hir FnDecl<'hir>,
-        b: BodyId,
-        s: Span,
-        id: HirId,
-    ) {
-        assert_eq!(self.parent_node, id);
-        intravisit::walk_fn(self, fk, fd, b, s, id);
-    }
-
-    fn visit_block(&mut self, block: &'hir Block<'hir>) {
-        self.insert(block.span, block.hir_id, Node::Block(block));
-        self.with_parent(block.hir_id, |this| {
-            intravisit::walk_block(this, block);
-        });
-    }
-
-    fn visit_local(&mut self, l: &'hir Local<'hir>) {
-        self.insert(l.span, l.hir_id, Node::Local(l));
-        self.with_parent(l.hir_id, |this| intravisit::walk_local(this, l))
-    }
-
-    fn visit_lifetime(&mut self, lifetime: &'hir Lifetime) {
-        self.insert(lifetime.span, lifetime.hir_id, Node::Lifetime(lifetime));
-    }
-
-    fn visit_vis(&mut self, visibility: &'hir Visibility<'hir>) {
-        match visibility.node {
-            VisibilityKind::Public | VisibilityKind::Crate(_) | VisibilityKind::Inherited => {}
-            VisibilityKind::Restricted { hir_id, .. } => {
-                self.insert(visibility.span, hir_id, Node::Visibility(visibility));
-                self.with_parent(hir_id, |this| {
-                    intravisit::walk_vis(this, visibility);
-                });
-            }
-        }
-    }
-
-    fn visit_macro_def(&mut self, macro_def: &'hir MacroDef<'hir>) {
-        let node_id = self.hir_to_node_id[&macro_def.hir_id];
-        let def_index = self.definitions.opt_def_index(node_id).unwrap();
-
-        self.with_dep_node_owner(def_index, macro_def, |this| {
-            this.insert(macro_def.span, macro_def.hir_id, Node::MacroDef(macro_def));
-        });
-    }
-
-    fn visit_variant(&mut self, v: &'hir Variant<'hir>, g: &'hir Generics<'hir>, item_id: HirId) {
-        self.insert(v.span, v.id, Node::Variant(v));
-        self.with_parent(v.id, |this| {
-            // Register the constructor of this variant.
-            if let Some(ctor_hir_id) = v.data.ctor_hir_id() {
-                this.insert(v.span, ctor_hir_id, Node::Ctor(&v.data));
-            }
-            intravisit::walk_variant(this, v, g, item_id);
-        });
-    }
-
-    fn visit_struct_field(&mut self, field: &'hir StructField<'hir>) {
-        self.insert(field.span, field.hir_id, Node::Field(field));
-        self.with_parent(field.hir_id, |this| {
-            intravisit::walk_struct_field(this, field);
-        });
-    }
-
-    fn visit_trait_item_ref(&mut self, ii: &'hir TraitItemRef) {
-        // Do not visit the duplicate information in TraitItemRef. We want to
-        // map the actual nodes, not the duplicate ones in the *Ref.
-        let TraitItemRef { id, ident: _, kind: _, span: _, defaultness: _ } = *ii;
-
-        self.visit_nested_trait_item(id);
-    }
-
-    fn visit_impl_item_ref(&mut self, ii: &'hir ImplItemRef<'hir>) {
-        // Do not visit the duplicate information in ImplItemRef. We want to
-        // map the actual nodes, not the duplicate ones in the *Ref.
-        let ImplItemRef { id, ident: _, kind: _, span: _, vis: _, defaultness: _ } = *ii;
-
-        self.visit_nested_impl_item(id);
-    }
-}
-
-// This is a wrapper structure that allows determining if span values within
-// the wrapped item should be hashed or not.
-struct HirItemLike<T> {
-    item_like: T,
-    hash_bodies: bool,
-}
-
-impl<'hir, T> HashStable<StableHashingContext<'hir>> for HirItemLike<T>
-where
-    T: HashStable<StableHashingContext<'hir>>,
-{
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'hir>, hasher: &mut StableHasher) {
-        hcx.while_hashing_hir_bodies(self.hash_bodies, |hcx| {
-            self.item_like.hash_stable(hcx, hasher);
-        });
-    }
-}
diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs
deleted file mode 100644
index 048c1f026be..00000000000
--- a/src/librustc/hir/map/definitions.rs
+++ /dev/null
@@ -1,558 +0,0 @@
-//! For each definition, we track the following data. A definition
-//! here is defined somewhat circularly as "something with a `DefId`",
-//! but it generally corresponds to things like structs, enums, etc.
-//! There are also some rather random cases (like const initializer
-//! expressions) that are mostly just leftovers.
-
-use rustc_data_structures::fingerprint::Fingerprint;
-use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::stable_hasher::StableHasher;
-use rustc_hir as hir;
-use rustc_hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
-use rustc_index::vec::IndexVec;
-use rustc_session::CrateDisambiguator;
-use rustc_span::hygiene::ExpnId;
-use rustc_span::symbol::{sym, Symbol};
-use rustc_span::Span;
-use syntax::ast;
-use syntax::node_id::NodeMap;
-
-use std::borrow::Borrow;
-use std::fmt::Write;
-use std::hash::Hash;
-
-/// The `DefPathTable` maps `DefIndex`es to `DefKey`s and vice versa.
-/// Internally the `DefPathTable` holds a tree of `DefKey`s, where each `DefKey`
-/// stores the `DefIndex` of its parent.
-/// There is one `DefPathTable` for each crate.
-#[derive(Clone, Default, RustcDecodable, RustcEncodable)]
-pub struct DefPathTable {
-    index_to_key: IndexVec<DefIndex, DefKey>,
-    def_path_hashes: IndexVec<DefIndex, DefPathHash>,
-}
-
-impl DefPathTable {
-    fn allocate(&mut self, key: DefKey, def_path_hash: DefPathHash) -> DefIndex {
-        let index = {
-            let index = DefIndex::from(self.index_to_key.len());
-            debug!("DefPathTable::insert() - {:?} <-> {:?}", key, index);
-            self.index_to_key.push(key);
-            index
-        };
-        self.def_path_hashes.push(def_path_hash);
-        debug_assert!(self.def_path_hashes.len() == self.index_to_key.len());
-        index
-    }
-
-    pub fn next_id(&self) -> DefIndex {
-        DefIndex::from(self.index_to_key.len())
-    }
-
-    #[inline(always)]
-    pub fn def_key(&self, index: DefIndex) -> DefKey {
-        self.index_to_key[index]
-    }
-
-    #[inline(always)]
-    pub fn def_path_hash(&self, index: DefIndex) -> DefPathHash {
-        let hash = self.def_path_hashes[index];
-        debug!("def_path_hash({:?}) = {:?}", index, hash);
-        hash
-    }
-
-    pub fn add_def_path_hashes_to(&self, cnum: CrateNum, out: &mut FxHashMap<DefPathHash, DefId>) {
-        out.extend(self.def_path_hashes.iter().enumerate().map(|(index, &hash)| {
-            let def_id = DefId { krate: cnum, index: DefIndex::from(index) };
-            (hash, def_id)
-        }));
-    }
-
-    pub fn size(&self) -> usize {
-        self.index_to_key.len()
-    }
-}
-
-/// The definition table containing node definitions.
-/// It holds the `DefPathTable` for local `DefId`s/`DefPath`s and it also stores a
-/// mapping from `NodeId`s to local `DefId`s.
-#[derive(Clone, Default)]
-pub struct Definitions {
-    table: DefPathTable,
-    node_to_def_index: NodeMap<DefIndex>,
-    def_index_to_node: IndexVec<DefIndex, ast::NodeId>,
-    pub(super) node_to_hir_id: IndexVec<ast::NodeId, hir::HirId>,
-    /// If `ExpnId` is an ID of some macro expansion,
-    /// then `DefId` is the normal module (`mod`) in which the expanded macro was defined.
-    parent_modules_of_macro_defs: FxHashMap<ExpnId, DefId>,
-    /// Item with a given `DefIndex` was defined during macro expansion with ID `ExpnId`.
-    expansions_that_defined: FxHashMap<DefIndex, ExpnId>,
-    next_disambiguator: FxHashMap<(DefIndex, DefPathData), u32>,
-    def_index_to_span: FxHashMap<DefIndex, Span>,
-    /// When collecting definitions from an AST fragment produced by a macro invocation `ExpnId`
-    /// we know what parent node that fragment should be attached to thanks to this table.
-    invocation_parents: FxHashMap<ExpnId, DefIndex>,
-    /// Indices of unnamed struct or variant fields with unresolved attributes.
-    placeholder_field_indices: NodeMap<usize>,
-}
-
-/// A unique identifier that we can use to lookup a definition
-/// precisely. It combines the index of the definition's parent (if
-/// any) with a `DisambiguatedDefPathData`.
-#[derive(Copy, Clone, PartialEq, Debug, RustcEncodable, RustcDecodable)]
-pub struct DefKey {
-    /// The parent path.
-    pub parent: Option<DefIndex>,
-
-    /// The identifier of this node.
-    pub disambiguated_data: DisambiguatedDefPathData,
-}
-
-impl DefKey {
-    fn compute_stable_hash(&self, parent_hash: DefPathHash) -> DefPathHash {
-        let mut hasher = StableHasher::new();
-
-        // We hash a `0u8` here to disambiguate between regular `DefPath` hashes,
-        // and the special "root_parent" below.
-        0u8.hash(&mut hasher);
-        parent_hash.hash(&mut hasher);
-
-        let DisambiguatedDefPathData { ref data, disambiguator } = self.disambiguated_data;
-
-        ::std::mem::discriminant(data).hash(&mut hasher);
-        if let Some(name) = data.get_opt_name() {
-            // Get a stable hash by considering the symbol chars rather than
-            // the symbol index.
-            name.as_str().hash(&mut hasher);
-        }
-
-        disambiguator.hash(&mut hasher);
-
-        DefPathHash(hasher.finish())
-    }
-
-    fn root_parent_stable_hash(
-        crate_name: &str,
-        crate_disambiguator: CrateDisambiguator,
-    ) -> DefPathHash {
-        let mut hasher = StableHasher::new();
-        // Disambiguate this from a regular `DefPath` hash; see `compute_stable_hash()` above.
-        1u8.hash(&mut hasher);
-        crate_name.hash(&mut hasher);
-        crate_disambiguator.hash(&mut hasher);
-        DefPathHash(hasher.finish())
-    }
-}
-
-/// A pair of `DefPathData` and an integer disambiguator. The integer is
-/// normally `0`, but in the event that there are multiple defs with the
-/// same `parent` and `data`, we use this field to disambiguate
-/// between them. This introduces some artificial ordering dependency
-/// but means that if you have, e.g., two impls for the same type in
-/// the same module, they do get distinct `DefId`s.
-#[derive(Copy, Clone, PartialEq, Debug, RustcEncodable, RustcDecodable)]
-pub struct DisambiguatedDefPathData {
-    pub data: DefPathData,
-    pub disambiguator: u32,
-}
-
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
-pub struct DefPath {
-    /// The path leading from the crate root to the item.
-    pub data: Vec<DisambiguatedDefPathData>,
-
-    /// The crate root this path is relative to.
-    pub krate: CrateNum,
-}
-
-impl DefPath {
-    pub fn is_local(&self) -> bool {
-        self.krate == LOCAL_CRATE
-    }
-
-    pub fn make<FN>(krate: CrateNum, start_index: DefIndex, mut get_key: FN) -> DefPath
-    where
-        FN: FnMut(DefIndex) -> DefKey,
-    {
-        let mut data = vec![];
-        let mut index = Some(start_index);
-        loop {
-            debug!("DefPath::make: krate={:?} index={:?}", krate, index);
-            let p = index.unwrap();
-            let key = get_key(p);
-            debug!("DefPath::make: key={:?}", key);
-            match key.disambiguated_data.data {
-                DefPathData::CrateRoot => {
-                    assert!(key.parent.is_none());
-                    break;
-                }
-                _ => {
-                    data.push(key.disambiguated_data);
-                    index = key.parent;
-                }
-            }
-        }
-        data.reverse();
-        DefPath { data: data, krate: krate }
-    }
-
-    /// Returns a string representation of the `DefPath` without
-    /// the crate-prefix. This method is useful if you don't have
-    /// a `TyCtxt` available.
-    pub fn to_string_no_crate(&self) -> String {
-        let mut s = String::with_capacity(self.data.len() * 16);
-
-        for component in &self.data {
-            write!(s, "::{}[{}]", component.data.as_symbol(), component.disambiguator).unwrap();
-        }
-
-        s
-    }
-
-    /// Returns a filename-friendly string for the `DefPath`, with the
-    /// crate-prefix.
-    pub fn to_string_friendly<F>(&self, crate_imported_name: F) -> String
-    where
-        F: FnOnce(CrateNum) -> Symbol,
-    {
-        let crate_name_str = crate_imported_name(self.krate).as_str();
-        let mut s = String::with_capacity(crate_name_str.len() + self.data.len() * 16);
-
-        write!(s, "::{}", crate_name_str).unwrap();
-
-        for component in &self.data {
-            if component.disambiguator == 0 {
-                write!(s, "::{}", component.data.as_symbol()).unwrap();
-            } else {
-                write!(s, "{}[{}]", component.data.as_symbol(), component.disambiguator).unwrap();
-            }
-        }
-
-        s
-    }
-
-    /// Returns a filename-friendly string of the `DefPath`, without
-    /// the crate-prefix. This method is useful if you don't have
-    /// a `TyCtxt` available.
-    pub fn to_filename_friendly_no_crate(&self) -> String {
-        let mut s = String::with_capacity(self.data.len() * 16);
-
-        let mut opt_delimiter = None;
-        for component in &self.data {
-            opt_delimiter.map(|d| s.push(d));
-            opt_delimiter = Some('-');
-            if component.disambiguator == 0 {
-                write!(s, "{}", component.data.as_symbol()).unwrap();
-            } else {
-                write!(s, "{}[{}]", component.data.as_symbol(), component.disambiguator).unwrap();
-            }
-        }
-        s
-    }
-}
-
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
-pub enum DefPathData {
-    // Root: these should only be used for the root nodes, because
-    // they are treated specially by the `def_path` function.
-    /// The crate root (marker).
-    CrateRoot,
-    // Catch-all for random `DefId` things like `DUMMY_NODE_ID`.
-    Misc,
-
-    // Different kinds of items and item-like things:
-    /// An impl.
-    Impl,
-    /// Something in the type namespace.
-    TypeNs(Symbol),
-    /// Something in the value namespace.
-    ValueNs(Symbol),
-    /// Something in the macro namespace.
-    MacroNs(Symbol),
-    /// Something in the lifetime namespace.
-    LifetimeNs(Symbol),
-    /// A closure expression.
-    ClosureExpr,
-
-    // Subportions of items:
-    /// Implicit constructor for a unit or tuple-like struct or enum variant.
-    Ctor,
-    /// A constant expression (see `{ast,hir}::AnonConst`).
-    AnonConst,
-    /// An `impl Trait` type node.
-    ImplTrait,
-}
-
-#[derive(
-    Copy,
-    Clone,
-    Hash,
-    PartialEq,
-    Eq,
-    PartialOrd,
-    Ord,
-    Debug,
-    RustcEncodable,
-    RustcDecodable,
-    HashStable
-)]
-pub struct DefPathHash(pub Fingerprint);
-
-impl Borrow<Fingerprint> for DefPathHash {
-    #[inline]
-    fn borrow(&self) -> &Fingerprint {
-        &self.0
-    }
-}
-
-impl Definitions {
-    pub fn def_path_table(&self) -> &DefPathTable {
-        &self.table
-    }
-
-    /// Gets the number of definitions.
-    pub fn def_index_count(&self) -> usize {
-        self.table.index_to_key.len()
-    }
-
-    pub fn def_key(&self, index: DefIndex) -> DefKey {
-        self.table.def_key(index)
-    }
-
-    #[inline(always)]
-    pub fn def_path_hash(&self, index: DefIndex) -> DefPathHash {
-        self.table.def_path_hash(index)
-    }
-
-    /// Returns the path from the crate root to `index`. The root
-    /// nodes are not included in the path (i.e., this will be an
-    /// empty vector for the crate root). For an inlined item, this
-    /// will be the path of the item in the external crate (but the
-    /// path will begin with the path to the external crate).
-    pub fn def_path(&self, index: DefIndex) -> DefPath {
-        DefPath::make(LOCAL_CRATE, index, |p| self.def_key(p))
-    }
-
-    #[inline]
-    pub fn opt_def_index(&self, node: ast::NodeId) -> Option<DefIndex> {
-        self.node_to_def_index.get(&node).copied()
-    }
-
-    #[inline]
-    pub fn opt_local_def_id(&self, node: ast::NodeId) -> Option<DefId> {
-        self.opt_def_index(node).map(DefId::local)
-    }
-
-    #[inline]
-    pub fn local_def_id(&self, node: ast::NodeId) -> DefId {
-        self.opt_local_def_id(node).unwrap()
-    }
-
-    #[inline]
-    pub fn as_local_node_id(&self, def_id: DefId) -> Option<ast::NodeId> {
-        if def_id.krate == LOCAL_CRATE {
-            let node_id = self.def_index_to_node[def_id.index];
-            if node_id != ast::DUMMY_NODE_ID {
-                return Some(node_id);
-            }
-        }
-        None
-    }
-
-    #[inline]
-    pub fn as_local_hir_id(&self, def_id: DefId) -> Option<hir::HirId> {
-        if def_id.krate == LOCAL_CRATE {
-            let hir_id = self.def_index_to_hir_id(def_id.index);
-            if hir_id != hir::DUMMY_HIR_ID { Some(hir_id) } else { None }
-        } else {
-            None
-        }
-    }
-
-    #[inline]
-    pub fn node_to_hir_id(&self, node_id: ast::NodeId) -> hir::HirId {
-        self.node_to_hir_id[node_id]
-    }
-
-    #[inline]
-    pub fn def_index_to_hir_id(&self, def_index: DefIndex) -> hir::HirId {
-        let node_id = self.def_index_to_node[def_index];
-        self.node_to_hir_id[node_id]
-    }
-
-    /// Retrieves the span of the given `DefId` if `DefId` is in the local crate, the span exists
-    /// and it's not `DUMMY_SP`.
-    #[inline]
-    pub fn opt_span(&self, def_id: DefId) -> Option<Span> {
-        if def_id.krate == LOCAL_CRATE {
-            self.def_index_to_span.get(&def_id.index).copied()
-        } else {
-            None
-        }
-    }
-
-    /// Adds a root definition (no parent) and a few other reserved definitions.
-    pub fn create_root_def(
-        &mut self,
-        crate_name: &str,
-        crate_disambiguator: CrateDisambiguator,
-    ) -> DefIndex {
-        let key = DefKey {
-            parent: None,
-            disambiguated_data: DisambiguatedDefPathData {
-                data: DefPathData::CrateRoot,
-                disambiguator: 0,
-            },
-        };
-
-        let parent_hash = DefKey::root_parent_stable_hash(crate_name, crate_disambiguator);
-        let def_path_hash = key.compute_stable_hash(parent_hash);
-
-        // Create the definition.
-        let root_index = self.table.allocate(key, def_path_hash);
-        assert_eq!(root_index, CRATE_DEF_INDEX);
-        assert!(self.def_index_to_node.is_empty());
-        self.def_index_to_node.push(ast::CRATE_NODE_ID);
-        self.node_to_def_index.insert(ast::CRATE_NODE_ID, root_index);
-        self.set_invocation_parent(ExpnId::root(), root_index);
-
-        root_index
-    }
-
-    /// Adds a definition with a parent definition.
-    pub fn create_def_with_parent(
-        &mut self,
-        parent: DefIndex,
-        node_id: ast::NodeId,
-        data: DefPathData,
-        expn_id: ExpnId,
-        span: Span,
-    ) -> DefIndex {
-        debug!(
-            "create_def_with_parent(parent={:?}, node_id={:?}, data={:?})",
-            parent, node_id, data
-        );
-
-        assert!(
-            !self.node_to_def_index.contains_key(&node_id),
-            "adding a def'n for node-id {:?} and data {:?} but a previous def'n exists: {:?}",
-            node_id,
-            data,
-            self.table.def_key(self.node_to_def_index[&node_id])
-        );
-
-        // The root node must be created with `create_root_def()`.
-        assert!(data != DefPathData::CrateRoot);
-
-        // Find the next free disambiguator for this key.
-        let disambiguator = {
-            let next_disamb = self.next_disambiguator.entry((parent, data)).or_insert(0);
-            let disambiguator = *next_disamb;
-            *next_disamb = next_disamb.checked_add(1).expect("disambiguator overflow");
-            disambiguator
-        };
-
-        let key = DefKey {
-            parent: Some(parent),
-            disambiguated_data: DisambiguatedDefPathData { data, disambiguator },
-        };
-
-        let parent_hash = self.table.def_path_hash(parent);
-        let def_path_hash = key.compute_stable_hash(parent_hash);
-
-        debug!("create_def_with_parent: after disambiguation, key = {:?}", key);
-
-        // Create the definition.
-        let index = self.table.allocate(key, def_path_hash);
-        assert_eq!(index.index(), self.def_index_to_node.len());
-        self.def_index_to_node.push(node_id);
-
-        // Some things for which we allocate `DefIndex`es don't correspond to
-        // anything in the AST, so they don't have a `NodeId`. For these cases
-        // we don't need a mapping from `NodeId` to `DefIndex`.
-        if node_id != ast::DUMMY_NODE_ID {
-            debug!("create_def_with_parent: def_index_to_node[{:?} <-> {:?}", index, node_id);
-            self.node_to_def_index.insert(node_id, index);
-        }
-
-        if expn_id != ExpnId::root() {
-            self.expansions_that_defined.insert(index, expn_id);
-        }
-
-        // The span is added if it isn't dummy.
-        if !span.is_dummy() {
-            self.def_index_to_span.insert(index, span);
-        }
-
-        index
-    }
-
-    /// Initializes the `ast::NodeId` to `HirId` mapping once it has been generated during
-    /// AST to HIR lowering.
-    pub fn init_node_id_to_hir_id_mapping(&mut self, mapping: IndexVec<ast::NodeId, hir::HirId>) {
-        assert!(
-            self.node_to_hir_id.is_empty(),
-            "trying to initialize `NodeId` -> `HirId` mapping twice"
-        );
-        self.node_to_hir_id = mapping;
-    }
-
-    pub fn expansion_that_defined(&self, index: DefIndex) -> ExpnId {
-        self.expansions_that_defined.get(&index).copied().unwrap_or(ExpnId::root())
-    }
-
-    pub fn parent_module_of_macro_def(&self, expn_id: ExpnId) -> DefId {
-        self.parent_modules_of_macro_defs[&expn_id]
-    }
-
-    pub fn add_parent_module_of_macro_def(&mut self, expn_id: ExpnId, module: DefId) {
-        self.parent_modules_of_macro_defs.insert(expn_id, module);
-    }
-
-    pub fn invocation_parent(&self, invoc_id: ExpnId) -> DefIndex {
-        self.invocation_parents[&invoc_id]
-    }
-
-    pub fn set_invocation_parent(&mut self, invoc_id: ExpnId, parent: DefIndex) {
-        let old_parent = self.invocation_parents.insert(invoc_id, parent);
-        assert!(old_parent.is_none(), "parent `DefIndex` is reset for an invocation");
-    }
-
-    pub fn placeholder_field_index(&self, node_id: ast::NodeId) -> usize {
-        self.placeholder_field_indices[&node_id]
-    }
-
-    pub fn set_placeholder_field_index(&mut self, node_id: ast::NodeId, index: usize) {
-        let old_index = self.placeholder_field_indices.insert(node_id, index);
-        assert!(old_index.is_none(), "placeholder field index is reset for a node ID");
-    }
-}
-
-impl DefPathData {
-    pub fn get_opt_name(&self) -> Option<Symbol> {
-        use self::DefPathData::*;
-        match *self {
-            TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) => Some(name),
-
-            Impl | CrateRoot | Misc | ClosureExpr | Ctor | AnonConst | ImplTrait => None,
-        }
-    }
-
-    pub fn as_symbol(&self) -> Symbol {
-        use self::DefPathData::*;
-        match *self {
-            TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) => name,
-            // Note that this does not show up in user print-outs.
-            CrateRoot => sym::double_braced_crate,
-            Impl => sym::double_braced_impl,
-            Misc => sym::double_braced_misc,
-            ClosureExpr => sym::double_braced_closure,
-            Ctor => sym::double_braced_constructor,
-            AnonConst => sym::double_braced_constant,
-            ImplTrait => sym::double_braced_opaque,
-        }
-    }
-
-    pub fn to_string(&self) -> String {
-        self.as_symbol().to_string()
-    }
-}
diff --git a/src/librustc/hir/map/hir_id_validator.rs b/src/librustc/hir/map/hir_id_validator.rs
deleted file mode 100644
index a4f9193c0eb..00000000000
--- a/src/librustc/hir/map/hir_id_validator.rs
+++ /dev/null
@@ -1,175 +0,0 @@
-use crate::hir::map::Map;
-use rustc_data_structures::fx::FxHashSet;
-use rustc_data_structures::sync::{par_iter, Lock, ParallelIterator};
-use rustc_hir as hir;
-use rustc_hir::def_id::{DefId, DefIndex, CRATE_DEF_INDEX};
-use rustc_hir::intravisit;
-use rustc_hir::itemlikevisit::ItemLikeVisitor;
-use rustc_hir::{HirId, ItemLocalId};
-
-pub fn check_crate(hir_map: &Map<'_>, sess: &rustc_session::Session) {
-    hir_map.dep_graph.assert_ignored();
-
-    let errors = Lock::new(Vec::new());
-
-    par_iter(&hir_map.krate.modules).for_each(|(module_id, _)| {
-        let local_def_id = hir_map.local_def_id(*module_id);
-        hir_map.visit_item_likes_in_module(
-            local_def_id,
-            &mut OuterVisitor { hir_map, errors: &errors },
-        );
-    });
-
-    let errors = errors.into_inner();
-
-    if !errors.is_empty() {
-        let message = errors.iter().fold(String::new(), |s1, s2| s1 + "\n" + s2);
-        sess.delay_span_bug(rustc_span::DUMMY_SP, &message);
-    }
-}
-
-struct HirIdValidator<'a, 'hir> {
-    hir_map: &'a Map<'hir>,
-    owner_def_index: Option<DefIndex>,
-    hir_ids_seen: FxHashSet<ItemLocalId>,
-    errors: &'a Lock<Vec<String>>,
-}
-
-struct OuterVisitor<'a, 'hir> {
-    hir_map: &'a Map<'hir>,
-    errors: &'a Lock<Vec<String>>,
-}
-
-impl<'a, 'hir> OuterVisitor<'a, 'hir> {
-    fn new_inner_visitor(&self, hir_map: &'a Map<'hir>) -> HirIdValidator<'a, 'hir> {
-        HirIdValidator {
-            hir_map,
-            owner_def_index: None,
-            hir_ids_seen: Default::default(),
-            errors: self.errors,
-        }
-    }
-}
-
-impl<'a, 'hir> ItemLikeVisitor<'hir> for OuterVisitor<'a, 'hir> {
-    fn visit_item(&mut self, i: &'hir hir::Item<'hir>) {
-        let mut inner_visitor = self.new_inner_visitor(self.hir_map);
-        inner_visitor.check(i.hir_id, |this| intravisit::walk_item(this, i));
-    }
-
-    fn visit_trait_item(&mut self, i: &'hir hir::TraitItem<'hir>) {
-        let mut inner_visitor = self.new_inner_visitor(self.hir_map);
-        inner_visitor.check(i.hir_id, |this| intravisit::walk_trait_item(this, i));
-    }
-
-    fn visit_impl_item(&mut self, i: &'hir hir::ImplItem<'hir>) {
-        let mut inner_visitor = self.new_inner_visitor(self.hir_map);
-        inner_visitor.check(i.hir_id, |this| intravisit::walk_impl_item(this, i));
-    }
-}
-
-impl<'a, 'hir> HirIdValidator<'a, 'hir> {
-    #[cold]
-    #[inline(never)]
-    fn error(&self, f: impl FnOnce() -> String) {
-        self.errors.lock().push(f());
-    }
-
-    fn check<F: FnOnce(&mut HirIdValidator<'a, 'hir>)>(&mut self, hir_id: HirId, walk: F) {
-        assert!(self.owner_def_index.is_none());
-        let owner_def_index = self.hir_map.local_def_id(hir_id).index;
-        self.owner_def_index = Some(owner_def_index);
-        walk(self);
-
-        if owner_def_index == CRATE_DEF_INDEX {
-            return;
-        }
-
-        // There's always at least one entry for the owning item itself
-        let max = self
-            .hir_ids_seen
-            .iter()
-            .map(|local_id| local_id.as_usize())
-            .max()
-            .expect("owning item has no entry");
-
-        if max != self.hir_ids_seen.len() - 1 {
-            // Collect the missing ItemLocalIds
-            let missing: Vec<_> = (0..=max as u32)
-                .filter(|&i| !self.hir_ids_seen.contains(&ItemLocalId::from_u32(i)))
-                .collect();
-
-            // Try to map those to something more useful
-            let mut missing_items = Vec::with_capacity(missing.len());
-
-            for local_id in missing {
-                let hir_id =
-                    HirId { owner: owner_def_index, local_id: ItemLocalId::from_u32(local_id) };
-
-                trace!("missing hir id {:#?}", hir_id);
-
-                missing_items.push(format!(
-                    "[local_id: {}, node:{}]",
-                    local_id,
-                    self.hir_map.node_to_string(hir_id)
-                ));
-            }
-            self.error(|| {
-                format!(
-                    "ItemLocalIds not assigned densely in {}. \
-                Max ItemLocalId = {}, missing IDs = {:?}; seens IDs = {:?}",
-                    self.hir_map.def_path(DefId::local(owner_def_index)).to_string_no_crate(),
-                    max,
-                    missing_items,
-                    self.hir_ids_seen
-                        .iter()
-                        .map(|&local_id| HirId { owner: owner_def_index, local_id })
-                        .map(|h| format!("({:?} {})", h, self.hir_map.node_to_string(h)))
-                        .collect::<Vec<_>>()
-                )
-            });
-        }
-    }
-}
-
-impl<'a, 'hir> intravisit::Visitor<'hir> for HirIdValidator<'a, 'hir> {
-    type Map = Map<'hir>;
-
-    fn nested_visit_map<'this>(&'this mut self) -> intravisit::NestedVisitorMap<'this, Self::Map> {
-        intravisit::NestedVisitorMap::OnlyBodies(self.hir_map)
-    }
-
-    fn visit_id(&mut self, hir_id: HirId) {
-        let owner = self.owner_def_index.expect("no owner_def_index");
-
-        if hir_id == hir::DUMMY_HIR_ID {
-            self.error(|| {
-                format!(
-                    "HirIdValidator: HirId {:?} is invalid",
-                    self.hir_map.node_to_string(hir_id)
-                )
-            });
-            return;
-        }
-
-        if owner != hir_id.owner {
-            self.error(|| {
-                format!(
-                    "HirIdValidator: The recorded owner of {} is {} instead of {}",
-                    self.hir_map.node_to_string(hir_id),
-                    self.hir_map.def_path(DefId::local(hir_id.owner)).to_string_no_crate(),
-                    self.hir_map.def_path(DefId::local(owner)).to_string_no_crate()
-                )
-            });
-        }
-
-        self.hir_ids_seen.insert(hir_id.local_id);
-    }
-
-    fn visit_impl_item_ref(&mut self, _: &'hir hir::ImplItemRef<'hir>) {
-        // Explicitly do nothing here. ImplItemRefs contain hir::Visibility
-        // values that actually belong to an ImplItem instead of the ItemKind::Impl
-        // we are currently in. So for those it's correct that they have a
-        // different owner.
-    }
-}
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
deleted file mode 100644
index adda0cde24f..00000000000
--- a/src/librustc/hir/map/mod.rs
+++ /dev/null
@@ -1,1363 +0,0 @@
-use self::collector::NodeCollector;
-pub use self::definitions::{
-    DefKey, DefPath, DefPathData, DefPathHash, Definitions, DisambiguatedDefPathData,
-};
-
-use crate::dep_graph::{DepGraph, DepKind, DepNode, DepNodeIndex};
-use crate::middle::cstore::CrateStoreDyn;
-use crate::ty::query::Providers;
-use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::svh::Svh;
-use rustc_hir::def::{DefKind, Res};
-use rustc_hir::def_id::{DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX};
-use rustc_hir::intravisit;
-use rustc_hir::itemlikevisit::ItemLikeVisitor;
-use rustc_hir::print::Nested;
-use rustc_hir::*;
-use rustc_index::vec::IndexVec;
-use rustc_span::hygiene::MacroKind;
-use rustc_span::source_map::Spanned;
-use rustc_span::symbol::kw;
-use rustc_span::Span;
-use rustc_target::spec::abi::Abi;
-use syntax::ast::{self, Name, NodeId};
-
-pub mod blocks;
-mod collector;
-pub mod definitions;
-mod hir_id_validator;
-
-/// Represents an entry and its parent `HirId`.
-#[derive(Copy, Clone, Debug)]
-pub struct Entry<'hir> {
-    parent: HirId,
-    dep_node: DepNodeIndex,
-    node: Node<'hir>,
-}
-
-impl<'hir> Entry<'hir> {
-    fn parent_node(self) -> Option<HirId> {
-        match self.node {
-            Node::Crate | Node::MacroDef(_) => None,
-            _ => Some(self.parent),
-        }
-    }
-
-    fn fn_decl(&self) -> Option<&'hir FnDecl<'hir>> {
-        match self.node {
-            Node::Item(ref item) => match item.kind {
-                ItemKind::Fn(ref sig, _, _) => Some(&sig.decl),
-                _ => None,
-            },
-
-            Node::TraitItem(ref item) => match item.kind {
-                TraitItemKind::Method(ref sig, _) => Some(&sig.decl),
-                _ => None,
-            },
-
-            Node::ImplItem(ref item) => match item.kind {
-                ImplItemKind::Method(ref sig, _) => Some(&sig.decl),
-                _ => None,
-            },
-
-            Node::Expr(ref expr) => match expr.kind {
-                ExprKind::Closure(_, ref fn_decl, ..) => Some(fn_decl),
-                _ => None,
-            },
-
-            _ => None,
-        }
-    }
-
-    fn fn_sig(&self) -> Option<&'hir FnSig<'hir>> {
-        match &self.node {
-            Node::Item(item) => match &item.kind {
-                ItemKind::Fn(sig, _, _) => Some(sig),
-                _ => None,
-            },
-
-            Node::TraitItem(item) => match &item.kind {
-                TraitItemKind::Method(sig, _) => Some(sig),
-                _ => None,
-            },
-
-            Node::ImplItem(item) => match &item.kind {
-                ImplItemKind::Method(sig, _) => Some(sig),
-                _ => None,
-            },
-
-            _ => None,
-        }
-    }
-
-    fn associated_body(self) -> Option<BodyId> {
-        match self.node {
-            Node::Item(item) => match item.kind {
-                ItemKind::Const(_, body) | ItemKind::Static(.., body) | ItemKind::Fn(.., body) => {
-                    Some(body)
-                }
-                _ => None,
-            },
-
-            Node::TraitItem(item) => match item.kind {
-                TraitItemKind::Const(_, Some(body))
-                | TraitItemKind::Method(_, TraitMethod::Provided(body)) => Some(body),
-                _ => None,
-            },
-
-            Node::ImplItem(item) => match item.kind {
-                ImplItemKind::Const(_, body) | ImplItemKind::Method(_, body) => Some(body),
-                _ => None,
-            },
-
-            Node::AnonConst(constant) => Some(constant.body),
-
-            Node::Expr(expr) => match expr.kind {
-                ExprKind::Closure(.., body, _, _) => Some(body),
-                _ => None,
-            },
-
-            _ => None,
-        }
-    }
-
-    fn is_body_owner(self, hir_id: HirId) -> bool {
-        match self.associated_body() {
-            Some(b) => b.hir_id == hir_id,
-            None => false,
-        }
-    }
-}
-
-/// This type is effectively a `HashMap<HirId, Entry<'hir>>`,
-/// but it is implemented as 2 layers of arrays.
-/// - first we have `A = IndexVec<DefIndex, B>` mapping `DefIndex`s to an inner value
-/// - which is `B = IndexVec<ItemLocalId, Option<Entry<'hir>>` which gives you the `Entry`.
-pub(super) type HirEntryMap<'hir> = IndexVec<DefIndex, IndexVec<ItemLocalId, Option<Entry<'hir>>>>;
-
-/// Represents a mapping from `NodeId`s to AST elements and their parent `NodeId`s.
-#[derive(Clone)]
-pub struct Map<'hir> {
-    krate: &'hir Crate<'hir>,
-
-    pub dep_graph: DepGraph,
-
-    /// The SVH of the local crate.
-    pub crate_hash: Svh,
-
-    map: HirEntryMap<'hir>,
-
-    definitions: Definitions,
-
-    /// The reverse mapping of `node_to_hir_id`.
-    hir_to_node_id: FxHashMap<HirId, NodeId>,
-}
-
-struct ParentHirIterator<'map, 'hir> {
-    current_id: HirId,
-    map: &'map Map<'hir>,
-}
-
-impl<'map, 'hir> ParentHirIterator<'map, 'hir> {
-    fn new(current_id: HirId, map: &'map Map<'hir>) -> Self {
-        Self { current_id, map }
-    }
-}
-
-impl<'hir> Iterator for ParentHirIterator<'_, 'hir> {
-    type Item = (HirId, Node<'hir>);
-
-    fn next(&mut self) -> Option<Self::Item> {
-        if self.current_id == CRATE_HIR_ID {
-            return None;
-        }
-        loop {
-            // There are nodes that do not have entries, so we need to skip them.
-            let parent_id = self.map.get_parent_node(self.current_id);
-
-            if parent_id == self.current_id {
-                self.current_id = CRATE_HIR_ID;
-                return None;
-            }
-
-            self.current_id = parent_id;
-            if let Some(entry) = self.map.find_entry(parent_id) {
-                return Some((parent_id, entry.node));
-            }
-            // If this `HirId` doesn't have an `Entry`, skip it and look for its `parent_id`.
-        }
-    }
-}
-
-impl<'hir> Map<'hir> {
-    /// This is used internally in the dependency tracking system.
-    /// Use the `krate` method to ensure your dependency on the
-    /// crate is tracked.
-    pub fn untracked_krate(&self) -> &Crate<'hir> {
-        &self.krate
-    }
-
-    #[inline]
-    fn lookup(&self, id: HirId) -> Option<&Entry<'hir>> {
-        let local_map = self.map.get(id.owner)?;
-        local_map.get(id.local_id)?.as_ref()
-    }
-
-    /// Registers a read in the dependency graph of the AST node with
-    /// the given `id`. This needs to be called each time a public
-    /// function returns the HIR for a node -- in other words, when it
-    /// "reveals" the content of a node to the caller (who might not
-    /// otherwise have had access to those contents, and hence needs a
-    /// read recorded). If the function just returns a DefId or
-    /// HirId, no actual content was returned, so no read is needed.
-    pub fn read(&self, hir_id: HirId) {
-        if let Some(entry) = self.lookup(hir_id) {
-            self.dep_graph.read_index(entry.dep_node);
-        } else {
-            bug!("called `HirMap::read()` with invalid `HirId`: {:?}", hir_id)
-        }
-    }
-
-    #[inline]
-    pub fn definitions(&self) -> &Definitions {
-        &self.definitions
-    }
-
-    pub fn def_key(&self, def_id: DefId) -> DefKey {
-        assert!(def_id.is_local());
-        self.definitions.def_key(def_id.index)
-    }
-
-    pub fn def_path_from_hir_id(&self, id: HirId) -> Option<DefPath> {
-        self.opt_local_def_id(id).map(|def_id| self.def_path(def_id))
-    }
-
-    pub fn def_path(&self, def_id: DefId) -> DefPath {
-        assert!(def_id.is_local());
-        self.definitions.def_path(def_id.index)
-    }
-
-    #[inline]
-    pub fn local_def_id_from_node_id(&self, node: NodeId) -> DefId {
-        self.opt_local_def_id_from_node_id(node).unwrap_or_else(|| {
-            let hir_id = self.node_to_hir_id(node);
-            bug!(
-                "local_def_id_from_node_id: no entry for `{}`, which has a map of `{:?}`",
-                node,
-                self.find_entry(hir_id)
-            )
-        })
-    }
-
-    #[inline]
-    pub fn local_def_id(&self, hir_id: HirId) -> DefId {
-        self.opt_local_def_id(hir_id).unwrap_or_else(|| {
-            bug!(
-                "local_def_id: no entry for `{:?}`, which has a map of `{:?}`",
-                hir_id,
-                self.find_entry(hir_id)
-            )
-        })
-    }
-
-    #[inline]
-    pub fn opt_local_def_id(&self, hir_id: HirId) -> Option<DefId> {
-        let node_id = self.hir_to_node_id(hir_id);
-        self.definitions.opt_local_def_id(node_id)
-    }
-
-    #[inline]
-    pub fn opt_local_def_id_from_node_id(&self, node: NodeId) -> Option<DefId> {
-        self.definitions.opt_local_def_id(node)
-    }
-
-    #[inline]
-    pub fn as_local_node_id(&self, def_id: DefId) -> Option<NodeId> {
-        self.definitions.as_local_node_id(def_id)
-    }
-
-    #[inline]
-    pub fn as_local_hir_id(&self, def_id: DefId) -> Option<HirId> {
-        self.definitions.as_local_hir_id(def_id)
-    }
-
-    #[inline]
-    pub fn hir_to_node_id(&self, hir_id: HirId) -> NodeId {
-        self.hir_to_node_id[&hir_id]
-    }
-
-    #[inline]
-    pub fn node_to_hir_id(&self, node_id: NodeId) -> HirId {
-        self.definitions.node_to_hir_id(node_id)
-    }
-
-    #[inline]
-    pub fn def_index_to_hir_id(&self, def_index: DefIndex) -> HirId {
-        self.definitions.def_index_to_hir_id(def_index)
-    }
-
-    #[inline]
-    pub fn local_def_id_to_hir_id(&self, def_id: LocalDefId) -> HirId {
-        self.definitions.def_index_to_hir_id(def_id.to_def_id().index)
-    }
-
-    pub fn def_kind(&self, hir_id: HirId) -> Option<DefKind> {
-        let node = if let Some(node) = self.find(hir_id) { node } else { return None };
-
-        Some(match node {
-            Node::Item(item) => match item.kind {
-                ItemKind::Static(..) => DefKind::Static,
-                ItemKind::Const(..) => DefKind::Const,
-                ItemKind::Fn(..) => DefKind::Fn,
-                ItemKind::Mod(..) => DefKind::Mod,
-                ItemKind::OpaqueTy(..) => DefKind::OpaqueTy,
-                ItemKind::TyAlias(..) => DefKind::TyAlias,
-                ItemKind::Enum(..) => DefKind::Enum,
-                ItemKind::Struct(..) => DefKind::Struct,
-                ItemKind::Union(..) => DefKind::Union,
-                ItemKind::Trait(..) => DefKind::Trait,
-                ItemKind::TraitAlias(..) => DefKind::TraitAlias,
-                ItemKind::ExternCrate(_)
-                | ItemKind::Use(..)
-                | ItemKind::ForeignMod(..)
-                | ItemKind::GlobalAsm(..)
-                | ItemKind::Impl { .. } => return None,
-            },
-            Node::ForeignItem(item) => match item.kind {
-                ForeignItemKind::Fn(..) => DefKind::Fn,
-                ForeignItemKind::Static(..) => DefKind::Static,
-                ForeignItemKind::Type => DefKind::ForeignTy,
-            },
-            Node::TraitItem(item) => match item.kind {
-                TraitItemKind::Const(..) => DefKind::AssocConst,
-                TraitItemKind::Method(..) => DefKind::Method,
-                TraitItemKind::Type(..) => DefKind::AssocTy,
-            },
-            Node::ImplItem(item) => match item.kind {
-                ImplItemKind::Const(..) => DefKind::AssocConst,
-                ImplItemKind::Method(..) => DefKind::Method,
-                ImplItemKind::TyAlias(..) => DefKind::AssocTy,
-                ImplItemKind::OpaqueTy(..) => DefKind::AssocOpaqueTy,
-            },
-            Node::Variant(_) => DefKind::Variant,
-            Node::Ctor(variant_data) => {
-                // FIXME(eddyb) is this even possible, if we have a `Node::Ctor`?
-                if variant_data.ctor_hir_id().is_none() {
-                    return None;
-                }
-                let ctor_of = match self.find(self.get_parent_node(hir_id)) {
-                    Some(Node::Item(..)) => def::CtorOf::Struct,
-                    Some(Node::Variant(..)) => def::CtorOf::Variant,
-                    _ => unreachable!(),
-                };
-                DefKind::Ctor(ctor_of, def::CtorKind::from_hir(variant_data))
-            }
-            Node::AnonConst(_)
-            | Node::Field(_)
-            | Node::Expr(_)
-            | Node::Stmt(_)
-            | Node::PathSegment(_)
-            | Node::Ty(_)
-            | Node::TraitRef(_)
-            | Node::Pat(_)
-            | Node::Binding(_)
-            | Node::Local(_)
-            | Node::Param(_)
-            | Node::Arm(_)
-            | Node::Lifetime(_)
-            | Node::Visibility(_)
-            | Node::Block(_)
-            | Node::Crate => return None,
-            Node::MacroDef(_) => DefKind::Macro(MacroKind::Bang),
-            Node::GenericParam(param) => match param.kind {
-                GenericParamKind::Lifetime { .. } => return None,
-                GenericParamKind::Type { .. } => DefKind::TyParam,
-                GenericParamKind::Const { .. } => DefKind::ConstParam,
-            },
-        })
-    }
-
-    fn find_entry(&self, id: HirId) -> Option<Entry<'hir>> {
-        self.lookup(id).cloned()
-    }
-
-    pub fn item(&self, id: HirId) -> &'hir Item<'hir> {
-        self.read(id);
-
-        // N.B., intentionally bypass `self.krate()` so that we
-        // do not trigger a read of the whole krate here
-        self.krate.item(id)
-    }
-
-    pub fn trait_item(&self, id: TraitItemId) -> &'hir TraitItem<'hir> {
-        self.read(id.hir_id);
-
-        // N.B., intentionally bypass `self.krate()` so that we
-        // do not trigger a read of the whole krate here
-        self.krate.trait_item(id)
-    }
-
-    pub fn impl_item(&self, id: ImplItemId) -> &'hir ImplItem<'hir> {
-        self.read(id.hir_id);
-
-        // N.B., intentionally bypass `self.krate()` so that we
-        // do not trigger a read of the whole krate here
-        self.krate.impl_item(id)
-    }
-
-    pub fn body(&self, id: BodyId) -> &'hir Body<'hir> {
-        self.read(id.hir_id);
-
-        // N.B., intentionally bypass `self.krate()` so that we
-        // do not trigger a read of the whole krate here
-        self.krate.body(id)
-    }
-
-    pub fn fn_decl_by_hir_id(&self, hir_id: HirId) -> Option<&'hir FnDecl<'hir>> {
-        if let Some(entry) = self.find_entry(hir_id) {
-            entry.fn_decl()
-        } else {
-            bug!("no entry for hir_id `{}`", hir_id)
-        }
-    }
-
-    pub fn fn_sig_by_hir_id(&self, hir_id: HirId) -> Option<&'hir FnSig<'hir>> {
-        if let Some(entry) = self.find_entry(hir_id) {
-            entry.fn_sig()
-        } else {
-            bug!("no entry for hir_id `{}`", hir_id)
-        }
-    }
-
-    /// Returns the `HirId` that corresponds to the definition of
-    /// which this is the body of, i.e., a `fn`, `const` or `static`
-    /// item (possibly associated), a closure, or a `hir::AnonConst`.
-    pub fn body_owner(&self, BodyId { hir_id }: BodyId) -> HirId {
-        let parent = self.get_parent_node(hir_id);
-        assert!(self.lookup(parent).map_or(false, |e| e.is_body_owner(hir_id)));
-        parent
-    }
-
-    pub fn body_owner_def_id(&self, id: BodyId) -> DefId {
-        self.local_def_id(self.body_owner(id))
-    }
-
-    /// Given a `HirId`, returns the `BodyId` associated with it,
-    /// if the node is a body owner, otherwise returns `None`.
-    pub fn maybe_body_owned_by(&self, hir_id: HirId) -> Option<BodyId> {
-        if let Some(entry) = self.find_entry(hir_id) {
-            if self.dep_graph.is_fully_enabled() {
-                let hir_id_owner = hir_id.owner;
-                let def_path_hash = self.definitions.def_path_hash(hir_id_owner);
-                self.dep_graph.read(def_path_hash.to_dep_node(DepKind::HirBody));
-            }
-
-            entry.associated_body()
-        } else {
-            bug!("no entry for id `{}`", hir_id)
-        }
-    }
-
-    /// Given a body owner's id, returns the `BodyId` associated with it.
-    pub fn body_owned_by(&self, id: HirId) -> BodyId {
-        self.maybe_body_owned_by(id).unwrap_or_else(|| {
-            span_bug!(
-                self.span(id),
-                "body_owned_by: {} has no associated body",
-                self.node_to_string(id)
-            );
-        })
-    }
-
-    pub fn body_owner_kind(&self, id: HirId) -> BodyOwnerKind {
-        match self.get(id) {
-            Node::Item(&Item { kind: ItemKind::Const(..), .. })
-            | Node::TraitItem(&TraitItem { kind: TraitItemKind::Const(..), .. })
-            | Node::ImplItem(&ImplItem { kind: ImplItemKind::Const(..), .. })
-            | Node::AnonConst(_) => BodyOwnerKind::Const,
-            Node::Ctor(..)
-            | Node::Item(&Item { kind: ItemKind::Fn(..), .. })
-            | Node::TraitItem(&TraitItem { kind: TraitItemKind::Method(..), .. })
-            | Node::ImplItem(&ImplItem { kind: ImplItemKind::Method(..), .. }) => BodyOwnerKind::Fn,
-            Node::Item(&Item { kind: ItemKind::Static(_, m, _), .. }) => BodyOwnerKind::Static(m),
-            Node::Expr(&Expr { kind: ExprKind::Closure(..), .. }) => BodyOwnerKind::Closure,
-            node => bug!("{:#?} is not a body node", node),
-        }
-    }
-
-    pub fn ty_param_owner(&self, id: HirId) -> HirId {
-        match self.get(id) {
-            Node::Item(&Item { kind: ItemKind::Trait(..), .. })
-            | Node::Item(&Item { kind: ItemKind::TraitAlias(..), .. }) => id,
-            Node::GenericParam(_) => self.get_parent_node(id),
-            _ => bug!("ty_param_owner: {} not a type parameter", self.node_to_string(id)),
-        }
-    }
-
-    pub fn ty_param_name(&self, id: HirId) -> Name {
-        match self.get(id) {
-            Node::Item(&Item { kind: ItemKind::Trait(..), .. })
-            | Node::Item(&Item { kind: ItemKind::TraitAlias(..), .. }) => kw::SelfUpper,
-            Node::GenericParam(param) => param.name.ident().name,
-            _ => bug!("ty_param_name: {} not a type parameter", self.node_to_string(id)),
-        }
-    }
-
-    pub fn trait_impls(&self, trait_did: DefId) -> &'hir [HirId] {
-        self.dep_graph.read(DepNode::new_no_params(DepKind::AllLocalTraitImpls));
-
-        // N.B., intentionally bypass `self.krate()` so that we
-        // do not trigger a read of the whole krate here
-        self.krate.trait_impls.get(&trait_did).map_or(&[], |xs| &xs[..])
-    }
-
-    /// Gets the attributes on the crate. This is preferable to
-    /// invoking `krate.attrs` because it registers a tighter
-    /// dep-graph access.
-    pub fn krate_attrs(&self) -> &'hir [ast::Attribute] {
-        let def_path_hash = self.definitions.def_path_hash(CRATE_DEF_INDEX);
-
-        self.dep_graph.read(def_path_hash.to_dep_node(DepKind::Hir));
-        &self.krate.attrs
-    }
-
-    pub fn get_module(&self, module: DefId) -> (&'hir Mod<'hir>, Span, HirId) {
-        let hir_id = self.as_local_hir_id(module).unwrap();
-        self.read(hir_id);
-        match self.find_entry(hir_id).unwrap().node {
-            Node::Item(&Item { span, kind: ItemKind::Mod(ref m), .. }) => (m, span, hir_id),
-            Node::Crate => (&self.krate.module, self.krate.span, hir_id),
-            node => panic!("not a module: {:?}", node),
-        }
-    }
-
-    pub fn visit_item_likes_in_module<V>(&self, module: DefId, visitor: &mut V)
-    where
-        V: ItemLikeVisitor<'hir>,
-    {
-        let hir_id = self.as_local_hir_id(module).unwrap();
-
-        // Read the module so we'll be re-executed if new items
-        // appear immediately under in the module. If some new item appears
-        // in some nested item in the module, we'll be re-executed due to reads
-        // in the expect_* calls the loops below
-        self.read(hir_id);
-
-        let module = &self.krate.modules[&hir_id];
-
-        for id in &module.items {
-            visitor.visit_item(self.expect_item(*id));
-        }
-
-        for id in &module.trait_items {
-            visitor.visit_trait_item(self.expect_trait_item(id.hir_id));
-        }
-
-        for id in &module.impl_items {
-            visitor.visit_impl_item(self.expect_impl_item(id.hir_id));
-        }
-    }
-
-    /// Retrieves the `Node` corresponding to `id`, panicking if it cannot be found.
-    pub fn get(&self, id: HirId) -> Node<'hir> {
-        // read recorded by `find`
-        self.find(id).unwrap_or_else(|| bug!("couldn't find hir id {} in the HIR map", id))
-    }
-
-    pub fn get_if_local(&self, id: DefId) -> Option<Node<'hir>> {
-        self.as_local_hir_id(id).map(|id| self.get(id)) // read recorded by `get`
-    }
-
-    pub fn get_generics(&self, id: DefId) -> Option<&'hir Generics<'hir>> {
-        self.get_if_local(id).and_then(|node| match node {
-            Node::ImplItem(ref impl_item) => Some(&impl_item.generics),
-            Node::TraitItem(ref trait_item) => Some(&trait_item.generics),
-            Node::Item(ref item) => match item.kind {
-                ItemKind::Fn(_, ref generics, _)
-                | ItemKind::TyAlias(_, ref generics)
-                | ItemKind::Enum(_, ref generics)
-                | ItemKind::Struct(_, ref generics)
-                | ItemKind::Union(_, ref generics)
-                | ItemKind::Trait(_, _, ref generics, ..)
-                | ItemKind::TraitAlias(ref generics, _)
-                | ItemKind::Impl { ref generics, .. } => Some(generics),
-                _ => None,
-            },
-            _ => None,
-        })
-    }
-
-    /// Retrieves the `Node` corresponding to `id`, returning `None` if cannot be found.
-    pub fn find(&self, hir_id: HirId) -> Option<Node<'hir>> {
-        let result = self
-            .find_entry(hir_id)
-            .and_then(|entry| if let Node::Crate = entry.node { None } else { Some(entry.node) });
-        if result.is_some() {
-            self.read(hir_id);
-        }
-        result
-    }
-
-    /// Similar to `get_parent`; returns the parent HIR Id, or just `hir_id` if there
-    /// is no parent. Note that the parent may be `CRATE_HIR_ID`, which is not itself
-    /// present in the map, so passing the return value of `get_parent_node` to
-    /// `get` may in fact panic.
-    /// This function returns the immediate parent in the HIR, whereas `get_parent`
-    /// returns the enclosing item. Note that this might not be the actual parent
-    /// node in the HIR -- some kinds of nodes are not in the map and these will
-    /// never appear as the parent node. Thus, you can always walk the parent nodes
-    /// from a node to the root of the HIR (unless you get back the same ID here,
-    /// which can happen if the ID is not in the map itself or is just weird).
-    pub fn get_parent_node(&self, hir_id: HirId) -> HirId {
-        if self.dep_graph.is_fully_enabled() {
-            let hir_id_owner = hir_id.owner;
-            let def_path_hash = self.definitions.def_path_hash(hir_id_owner);
-            self.dep_graph.read(def_path_hash.to_dep_node(DepKind::HirBody));
-        }
-
-        self.find_entry(hir_id).and_then(|x| x.parent_node()).unwrap_or(hir_id)
-    }
-
-    /// Checks if the node is an argument. An argument is a local variable whose
-    /// immediate parent is an item or a closure.
-    pub fn is_argument(&self, id: HirId) -> bool {
-        match self.find(id) {
-            Some(Node::Binding(_)) => (),
-            _ => return false,
-        }
-        match self.find(self.get_parent_node(id)) {
-            Some(Node::Item(_)) | Some(Node::TraitItem(_)) | Some(Node::ImplItem(_)) => true,
-            Some(Node::Expr(e)) => match e.kind {
-                ExprKind::Closure(..) => true,
-                _ => false,
-            },
-            _ => false,
-        }
-    }
-
-    /// Whether the expression pointed at by `hir_id` belongs to a `const` evaluation context.
-    /// Used exclusively for diagnostics, to avoid suggestion function calls.
-    pub fn is_const_context(&self, hir_id: HirId) -> bool {
-        let parent_id = self.get_parent_item(hir_id);
-        match self.get(parent_id) {
-            Node::Item(&Item { kind: ItemKind::Const(..), .. })
-            | Node::TraitItem(&TraitItem { kind: TraitItemKind::Const(..), .. })
-            | Node::ImplItem(&ImplItem { kind: ImplItemKind::Const(..), .. })
-            | Node::AnonConst(_)
-            | Node::Item(&Item { kind: ItemKind::Static(..), .. }) => true,
-            Node::Item(&Item { kind: ItemKind::Fn(ref sig, ..), .. }) => {
-                sig.header.constness == Constness::Const
-            }
-            _ => false,
-        }
-    }
-
-    /// Wether `hir_id` corresponds to a `mod` or a crate.
-    pub fn is_hir_id_module(&self, hir_id: HirId) -> bool {
-        match self.lookup(hir_id) {
-            Some(Entry { node: Node::Item(Item { kind: ItemKind::Mod(_), .. }), .. })
-            | Some(Entry { node: Node::Crate, .. }) => true,
-            _ => false,
-        }
-    }
-
-    /// Retrieves the `HirId` for `id`'s enclosing method, unless there's a
-    /// `while` or `loop` before reaching it, as block tail returns are not
-    /// available in them.
-    ///
-    /// ```
-    /// fn foo(x: usize) -> bool {
-    ///     if x == 1 {
-    ///         true  // If `get_return_block` gets passed the `id` corresponding
-    ///     } else {  // to this, it will return `foo`'s `HirId`.
-    ///         false
-    ///     }
-    /// }
-    /// ```
-    ///
-    /// ```
-    /// fn foo(x: usize) -> bool {
-    ///     loop {
-    ///         true  // If `get_return_block` gets passed the `id` corresponding
-    ///     }         // to this, it will return `None`.
-    ///     false
-    /// }
-    /// ```
-    pub fn get_return_block(&self, id: HirId) -> Option<HirId> {
-        let mut iter = ParentHirIterator::new(id, &self).peekable();
-        let mut ignore_tail = false;
-        if let Some(entry) = self.find_entry(id) {
-            if let Node::Expr(Expr { kind: ExprKind::Ret(_), .. }) = entry.node {
-                // When dealing with `return` statements, we don't care about climbing only tail
-                // expressions.
-                ignore_tail = true;
-            }
-        }
-        while let Some((hir_id, node)) = iter.next() {
-            if let (Some((_, next_node)), false) = (iter.peek(), ignore_tail) {
-                match next_node {
-                    Node::Block(Block { expr: None, .. }) => return None,
-                    Node::Block(Block { expr: Some(expr), .. }) => {
-                        if hir_id != expr.hir_id {
-                            // The current node is not the tail expression of its parent.
-                            return None;
-                        }
-                    }
-                    _ => {}
-                }
-            }
-            match node {
-                Node::Item(_)
-                | Node::ForeignItem(_)
-                | Node::TraitItem(_)
-                | Node::Expr(Expr { kind: ExprKind::Closure(..), .. })
-                | Node::ImplItem(_) => return Some(hir_id),
-                Node::Expr(ref expr) => {
-                    match expr.kind {
-                        // Ignore `return`s on the first iteration
-                        ExprKind::Loop(..) | ExprKind::Ret(..) => return None,
-                        _ => {}
-                    }
-                }
-                Node::Local(_) => return None,
-                _ => {}
-            }
-        }
-        None
-    }
-
-    /// Retrieves the `HirId` for `id`'s parent item, or `id` itself if no
-    /// parent item is in this map. The "parent item" is the closest parent node
-    /// in the HIR which is recorded by the map and is an item, either an item
-    /// in a module, trait, or impl.
-    pub fn get_parent_item(&self, hir_id: HirId) -> HirId {
-        for (hir_id, node) in ParentHirIterator::new(hir_id, &self) {
-            match node {
-                Node::Crate
-                | Node::Item(_)
-                | Node::ForeignItem(_)
-                | Node::TraitItem(_)
-                | Node::ImplItem(_) => return hir_id,
-                _ => {}
-            }
-        }
-        hir_id
-    }
-
-    /// Returns the `DefId` of `id`'s nearest module parent, or `id` itself if no
-    /// module parent is in this map.
-    pub fn get_module_parent(&self, id: HirId) -> DefId {
-        self.local_def_id(self.get_module_parent_node(id))
-    }
-
-    /// Returns the `HirId` of `id`'s nearest module parent, or `id` itself if no
-    /// module parent is in this map.
-    pub fn get_module_parent_node(&self, hir_id: HirId) -> HirId {
-        for (hir_id, node) in ParentHirIterator::new(hir_id, &self) {
-            if let Node::Item(&Item { kind: ItemKind::Mod(_), .. }) = node {
-                return hir_id;
-            }
-        }
-        CRATE_HIR_ID
-    }
-
-    /// When on a match arm tail expression or on a match arm, give back the enclosing `match`
-    /// expression.
-    ///
-    /// Used by error reporting when there's a type error in a match arm caused by the `match`
-    /// expression needing to be unit.
-    pub fn get_match_if_cause(&self, hir_id: HirId) -> Option<&'hir Expr<'hir>> {
-        for (_, node) in ParentHirIterator::new(hir_id, &self) {
-            match node {
-                Node::Item(_) | Node::ForeignItem(_) | Node::TraitItem(_) | Node::ImplItem(_) => {
-                    break;
-                }
-                Node::Expr(expr) => match expr.kind {
-                    ExprKind::Match(_, _, _) => return Some(expr),
-                    _ => {}
-                },
-                Node::Stmt(stmt) => match stmt.kind {
-                    StmtKind::Local(_) => break,
-                    _ => {}
-                },
-                _ => {}
-            }
-        }
-        None
-    }
-
-    /// Returns the nearest enclosing scope. A scope is roughly an item or block.
-    pub fn get_enclosing_scope(&self, hir_id: HirId) -> Option<HirId> {
-        for (hir_id, node) in ParentHirIterator::new(hir_id, &self) {
-            if match node {
-                Node::Item(i) => match i.kind {
-                    ItemKind::Fn(..)
-                    | ItemKind::Mod(..)
-                    | ItemKind::Enum(..)
-                    | ItemKind::Struct(..)
-                    | ItemKind::Union(..)
-                    | ItemKind::Trait(..)
-                    | ItemKind::Impl { .. } => true,
-                    _ => false,
-                },
-                Node::ForeignItem(fi) => match fi.kind {
-                    ForeignItemKind::Fn(..) => true,
-                    _ => false,
-                },
-                Node::TraitItem(ti) => match ti.kind {
-                    TraitItemKind::Method(..) => true,
-                    _ => false,
-                },
-                Node::ImplItem(ii) => match ii.kind {
-                    ImplItemKind::Method(..) => true,
-                    _ => false,
-                },
-                Node::Block(_) => true,
-                _ => false,
-            } {
-                return Some(hir_id);
-            }
-        }
-        None
-    }
-
-    /// Returns the defining scope for an opaque type definition.
-    pub fn get_defining_scope(&self, id: HirId) -> HirId {
-        let mut scope = id;
-        loop {
-            scope = self.get_enclosing_scope(scope).unwrap_or(CRATE_HIR_ID);
-            if scope == CRATE_HIR_ID {
-                return CRATE_HIR_ID;
-            }
-            match self.get(scope) {
-                Node::Item(i) => match i.kind {
-                    ItemKind::OpaqueTy(OpaqueTy { impl_trait_fn: None, .. }) => {}
-                    _ => break,
-                },
-                Node::Block(_) => {}
-                _ => break,
-            }
-        }
-        scope
-    }
-
-    pub fn get_parent_did(&self, id: HirId) -> DefId {
-        self.local_def_id(self.get_parent_item(id))
-    }
-
-    pub fn get_foreign_abi(&self, hir_id: HirId) -> Abi {
-        let parent = self.get_parent_item(hir_id);
-        if let Some(entry) = self.find_entry(parent) {
-            if let Entry {
-                node: Node::Item(Item { kind: ItemKind::ForeignMod(ref nm), .. }), ..
-            } = entry
-            {
-                self.read(hir_id); // reveals some of the content of a node
-                return nm.abi;
-            }
-        }
-        bug!("expected foreign mod or inlined parent, found {}", self.node_to_string(parent))
-    }
-
-    pub fn expect_item(&self, id: HirId) -> &'hir Item<'hir> {
-        match self.find(id) {
-            // read recorded by `find`
-            Some(Node::Item(item)) => item,
-            _ => bug!("expected item, found {}", self.node_to_string(id)),
-        }
-    }
-
-    pub fn expect_impl_item(&self, id: HirId) -> &'hir ImplItem<'hir> {
-        match self.find(id) {
-            Some(Node::ImplItem(item)) => item,
-            _ => bug!("expected impl item, found {}", self.node_to_string(id)),
-        }
-    }
-
-    pub fn expect_trait_item(&self, id: HirId) -> &'hir TraitItem<'hir> {
-        match self.find(id) {
-            Some(Node::TraitItem(item)) => item,
-            _ => bug!("expected trait item, found {}", self.node_to_string(id)),
-        }
-    }
-
-    pub fn expect_variant_data(&self, id: HirId) -> &'hir VariantData<'hir> {
-        match self.find(id) {
-            Some(Node::Item(i)) => match i.kind {
-                ItemKind::Struct(ref struct_def, _) | ItemKind::Union(ref struct_def, _) => {
-                    struct_def
-                }
-                _ => bug!("struct ID bound to non-struct {}", self.node_to_string(id)),
-            },
-            Some(Node::Variant(variant)) => &variant.data,
-            Some(Node::Ctor(data)) => data,
-            _ => bug!("expected struct or variant, found {}", self.node_to_string(id)),
-        }
-    }
-
-    pub fn expect_variant(&self, id: HirId) -> &'hir Variant<'hir> {
-        match self.find(id) {
-            Some(Node::Variant(variant)) => variant,
-            _ => bug!("expected variant, found {}", self.node_to_string(id)),
-        }
-    }
-
-    pub fn expect_foreign_item(&self, id: HirId) -> &'hir ForeignItem<'hir> {
-        match self.find(id) {
-            Some(Node::ForeignItem(item)) => item,
-            _ => bug!("expected foreign item, found {}", self.node_to_string(id)),
-        }
-    }
-
-    pub fn expect_expr(&self, id: HirId) -> &'hir Expr<'hir> {
-        match self.find(id) {
-            // read recorded by find
-            Some(Node::Expr(expr)) => expr,
-            _ => bug!("expected expr, found {}", self.node_to_string(id)),
-        }
-    }
-
-    pub fn opt_name(&self, id: HirId) -> Option<Name> {
-        Some(match self.get(id) {
-            Node::Item(i) => i.ident.name,
-            Node::ForeignItem(fi) => fi.ident.name,
-            Node::ImplItem(ii) => ii.ident.name,
-            Node::TraitItem(ti) => ti.ident.name,
-            Node::Variant(v) => v.ident.name,
-            Node::Field(f) => f.ident.name,
-            Node::Lifetime(lt) => lt.name.ident().name,
-            Node::GenericParam(param) => param.name.ident().name,
-            Node::Binding(&Pat { kind: PatKind::Binding(_, _, l, _), .. }) => l.name,
-            Node::Ctor(..) => self.name(self.get_parent_item(id)),
-            _ => return None,
-        })
-    }
-
-    pub fn name(&self, id: HirId) -> Name {
-        match self.opt_name(id) {
-            Some(name) => name,
-            None => bug!("no name for {}", self.node_to_string(id)),
-        }
-    }
-
-    /// Given a node ID, gets a list of attributes associated with the AST
-    /// corresponding to the node-ID.
-    pub fn attrs(&self, id: HirId) -> &'hir [ast::Attribute] {
-        self.read(id); // reveals attributes on the node
-        let attrs = match self.find_entry(id).map(|entry| entry.node) {
-            Some(Node::Param(a)) => Some(&a.attrs[..]),
-            Some(Node::Local(l)) => Some(&l.attrs[..]),
-            Some(Node::Item(i)) => Some(&i.attrs[..]),
-            Some(Node::ForeignItem(fi)) => Some(&fi.attrs[..]),
-            Some(Node::TraitItem(ref ti)) => Some(&ti.attrs[..]),
-            Some(Node::ImplItem(ref ii)) => Some(&ii.attrs[..]),
-            Some(Node::Variant(ref v)) => Some(&v.attrs[..]),
-            Some(Node::Field(ref f)) => Some(&f.attrs[..]),
-            Some(Node::Expr(ref e)) => Some(&*e.attrs),
-            Some(Node::Stmt(ref s)) => Some(s.kind.attrs()),
-            Some(Node::Arm(ref a)) => Some(&*a.attrs),
-            Some(Node::GenericParam(param)) => Some(&param.attrs[..]),
-            // Unit/tuple structs/variants take the attributes straight from
-            // the struct/variant definition.
-            Some(Node::Ctor(..)) => return self.attrs(self.get_parent_item(id)),
-            Some(Node::Crate) => Some(&self.krate.attrs[..]),
-            _ => None,
-        };
-        attrs.unwrap_or(&[])
-    }
-
-    /// Returns an iterator that yields all the hir ids in the map.
-    fn all_ids<'a>(&'a self) -> impl Iterator<Item = HirId> + 'a {
-        // This code is a bit awkward because the map is implemented as 2 levels of arrays,
-        // see the comment on `HirEntryMap`.
-        // Iterate over all the indices and return a reference to
-        // local maps and their index given that they exist.
-        self.map.iter_enumerated().flat_map(move |(owner, local_map)| {
-            // Iterate over each valid entry in the local map.
-            local_map.iter_enumerated().filter_map(move |(i, entry)| {
-                entry.map(move |_| {
-                    // Reconstruct the `HirId` based on the 3 indices we used to find it.
-                    HirId { owner, local_id: i }
-                })
-            })
-        })
-    }
-
-    /// Returns an iterator that yields the node id's with paths that
-    /// match `parts`.  (Requires `parts` is non-empty.)
-    ///
-    /// For example, if given `parts` equal to `["bar", "quux"]`, then
-    /// the iterator will produce node id's for items with paths
-    /// such as `foo::bar::quux`, `bar::quux`, `other::bar::quux`, and
-    /// any other such items it can find in the map.
-    pub fn nodes_matching_suffix<'a>(
-        &'a self,
-        parts: &'a [String],
-    ) -> impl Iterator<Item = NodeId> + 'a {
-        let nodes = NodesMatchingSuffix {
-            map: self,
-            item_name: parts.last().unwrap(),
-            in_which: &parts[..parts.len() - 1],
-        };
-
-        self.all_ids()
-            .filter(move |hir| nodes.matches_suffix(*hir))
-            .map(move |hir| self.hir_to_node_id(hir))
-    }
-
-    pub fn span(&self, hir_id: HirId) -> Span {
-        self.read(hir_id); // reveals span from node
-        match self.find_entry(hir_id).map(|entry| entry.node) {
-            Some(Node::Param(param)) => param.span,
-            Some(Node::Item(item)) => item.span,
-            Some(Node::ForeignItem(foreign_item)) => foreign_item.span,
-            Some(Node::TraitItem(trait_method)) => trait_method.span,
-            Some(Node::ImplItem(impl_item)) => impl_item.span,
-            Some(Node::Variant(variant)) => variant.span,
-            Some(Node::Field(field)) => field.span,
-            Some(Node::AnonConst(constant)) => self.body(constant.body).value.span,
-            Some(Node::Expr(expr)) => expr.span,
-            Some(Node::Stmt(stmt)) => stmt.span,
-            Some(Node::PathSegment(seg)) => seg.ident.span,
-            Some(Node::Ty(ty)) => ty.span,
-            Some(Node::TraitRef(tr)) => tr.path.span,
-            Some(Node::Binding(pat)) => pat.span,
-            Some(Node::Pat(pat)) => pat.span,
-            Some(Node::Arm(arm)) => arm.span,
-            Some(Node::Block(block)) => block.span,
-            Some(Node::Ctor(..)) => match self.find(self.get_parent_node(hir_id)) {
-                Some(Node::Item(item)) => item.span,
-                Some(Node::Variant(variant)) => variant.span,
-                _ => unreachable!(),
-            },
-            Some(Node::Lifetime(lifetime)) => lifetime.span,
-            Some(Node::GenericParam(param)) => param.span,
-            Some(Node::Visibility(&Spanned {
-                node: VisibilityKind::Restricted { ref path, .. },
-                ..
-            })) => path.span,
-            Some(Node::Visibility(v)) => bug!("unexpected Visibility {:?}", v),
-            Some(Node::Local(local)) => local.span,
-            Some(Node::MacroDef(macro_def)) => macro_def.span,
-            Some(Node::Crate) => self.krate.span,
-            None => bug!("hir::map::Map::span: id not in map: {:?}", hir_id),
-        }
-    }
-
-    pub fn span_if_local(&self, id: DefId) -> Option<Span> {
-        self.as_local_hir_id(id).map(|id| self.span(id))
-    }
-
-    pub fn res_span(&self, res: Res) -> Option<Span> {
-        match res {
-            Res::Err => None,
-            Res::Local(id) => Some(self.span(id)),
-            res => self.span_if_local(res.opt_def_id()?),
-        }
-    }
-
-    pub fn node_to_string(&self, id: HirId) -> String {
-        hir_id_to_string(self, id, true)
-    }
-
-    pub fn hir_to_user_string(&self, id: HirId) -> String {
-        hir_id_to_string(self, id, false)
-    }
-
-    pub fn hir_to_pretty_string(&self, id: HirId) -> String {
-        print::to_string(self, |s| s.print_node(self.get(id)))
-    }
-}
-
-impl<'hir> intravisit::Map<'hir> for Map<'hir> {
-    fn body(&self, id: BodyId) -> &'hir Body<'hir> {
-        self.body(id)
-    }
-
-    fn item(&self, id: HirId) -> &'hir Item<'hir> {
-        self.item(id)
-    }
-
-    fn trait_item(&self, id: TraitItemId) -> &'hir TraitItem<'hir> {
-        self.trait_item(id)
-    }
-
-    fn impl_item(&self, id: ImplItemId) -> &'hir ImplItem<'hir> {
-        self.impl_item(id)
-    }
-}
-
-pub struct NodesMatchingSuffix<'a> {
-    map: &'a Map<'a>,
-    item_name: &'a String,
-    in_which: &'a [String],
-}
-
-impl<'a> NodesMatchingSuffix<'a> {
-    /// Returns `true` only if some suffix of the module path for parent
-    /// matches `self.in_which`.
-    ///
-    /// In other words: let `[x_0,x_1,...,x_k]` be `self.in_which`;
-    /// returns true if parent's path ends with the suffix
-    /// `x_0::x_1::...::x_k`.
-    fn suffix_matches(&self, parent: HirId) -> bool {
-        let mut cursor = parent;
-        for part in self.in_which.iter().rev() {
-            let (mod_id, mod_name) = match find_first_mod_parent(self.map, cursor) {
-                None => return false,
-                Some((node_id, name)) => (node_id, name),
-            };
-            if mod_name.as_str() != *part {
-                return false;
-            }
-            cursor = self.map.get_parent_item(mod_id);
-        }
-        return true;
-
-        // Finds the first mod in parent chain for `id`, along with
-        // that mod's name.
-        //
-        // If `id` itself is a mod named `m` with parent `p`, then
-        // returns `Some(id, m, p)`.  If `id` has no mod in its parent
-        // chain, then returns `None`.
-        fn find_first_mod_parent(map: &Map<'_>, mut id: HirId) -> Option<(HirId, Name)> {
-            loop {
-                if let Node::Item(item) = map.find(id)? {
-                    if item_is_mod(&item) {
-                        return Some((id, item.ident.name));
-                    }
-                }
-                let parent = map.get_parent_item(id);
-                if parent == id {
-                    return None;
-                }
-                id = parent;
-            }
-
-            fn item_is_mod(item: &Item<'_>) -> bool {
-                match item.kind {
-                    ItemKind::Mod(_) => true,
-                    _ => false,
-                }
-            }
-        }
-    }
-
-    // We are looking at some node `n` with a given name and parent
-    // id; do their names match what I am seeking?
-    fn matches_names(&self, parent_of_n: HirId, name: Name) -> bool {
-        name.as_str() == *self.item_name && self.suffix_matches(parent_of_n)
-    }
-
-    fn matches_suffix(&self, hir: HirId) -> bool {
-        let name = match self.map.find_entry(hir).map(|entry| entry.node) {
-            Some(Node::Item(n)) => n.name(),
-            Some(Node::ForeignItem(n)) => n.name(),
-            Some(Node::TraitItem(n)) => n.name(),
-            Some(Node::ImplItem(n)) => n.name(),
-            Some(Node::Variant(n)) => n.name(),
-            Some(Node::Field(n)) => n.name(),
-            _ => return false,
-        };
-        self.matches_names(self.map.get_parent_item(hir), name)
-    }
-}
-
-trait Named {
-    fn name(&self) -> Name;
-}
-
-impl<T: Named> Named for Spanned<T> {
-    fn name(&self) -> Name {
-        self.node.name()
-    }
-}
-
-impl Named for Item<'_> {
-    fn name(&self) -> Name {
-        self.ident.name
-    }
-}
-impl Named for ForeignItem<'_> {
-    fn name(&self) -> Name {
-        self.ident.name
-    }
-}
-impl Named for Variant<'_> {
-    fn name(&self) -> Name {
-        self.ident.name
-    }
-}
-impl Named for StructField<'_> {
-    fn name(&self) -> Name {
-        self.ident.name
-    }
-}
-impl Named for TraitItem<'_> {
-    fn name(&self) -> Name {
-        self.ident.name
-    }
-}
-impl Named for ImplItem<'_> {
-    fn name(&self) -> Name {
-        self.ident.name
-    }
-}
-
-pub fn map_crate<'hir>(
-    sess: &rustc_session::Session,
-    cstore: &CrateStoreDyn,
-    krate: &'hir Crate<'hir>,
-    dep_graph: DepGraph,
-    definitions: Definitions,
-) -> Map<'hir> {
-    let _prof_timer = sess.prof.generic_activity("build_hir_map");
-
-    // Build the reverse mapping of `node_to_hir_id`.
-    let hir_to_node_id = definitions
-        .node_to_hir_id
-        .iter_enumerated()
-        .map(|(node_id, &hir_id)| (hir_id, node_id))
-        .collect();
-
-    let (map, crate_hash) = {
-        let hcx = crate::ich::StableHashingContext::new(sess, krate, &definitions, cstore);
-
-        let mut collector =
-            NodeCollector::root(sess, krate, &dep_graph, &definitions, &hir_to_node_id, hcx);
-        intravisit::walk_crate(&mut collector, krate);
-
-        let crate_disambiguator = sess.local_crate_disambiguator();
-        let cmdline_args = sess.opts.dep_tracking_hash();
-        collector.finalize_and_compute_crate_hash(crate_disambiguator, cstore, cmdline_args)
-    };
-
-    let map = Map { krate, dep_graph, crate_hash, map, hir_to_node_id, definitions };
-
-    sess.time("validate_HIR_map", || {
-        hir_id_validator::check_crate(&map, sess);
-    });
-
-    map
-}
-
-/// Identical to the `PpAnn` implementation for `hir::Crate`,
-/// except it avoids creating a dependency on the whole crate.
-impl<'hir> print::PpAnn for Map<'hir> {
-    fn nested(&self, state: &mut print::State<'_>, nested: print::Nested) {
-        match nested {
-            Nested::Item(id) => state.print_item(self.expect_item(id.id)),
-            Nested::TraitItem(id) => state.print_trait_item(self.trait_item(id)),
-            Nested::ImplItem(id) => state.print_impl_item(self.impl_item(id)),
-            Nested::Body(id) => state.print_expr(&self.body(id).value),
-            Nested::BodyParamPat(id, i) => state.print_pat(&self.body(id).params[i].pat),
-        }
-    }
-}
-
-fn hir_id_to_string(map: &Map<'_>, id: HirId, include_id: bool) -> String {
-    let id_str = format!(" (hir_id={})", id);
-    let id_str = if include_id { &id_str[..] } else { "" };
-
-    let path_str = || {
-        // This functionality is used for debugging, try to use `TyCtxt` to get
-        // the user-friendly path, otherwise fall back to stringifying `DefPath`.
-        crate::ty::tls::with_opt(|tcx| {
-            if let Some(tcx) = tcx {
-                let def_id = map.local_def_id(id);
-                tcx.def_path_str(def_id)
-            } else if let Some(path) = map.def_path_from_hir_id(id) {
-                path.data
-                    .into_iter()
-                    .map(|elem| elem.data.to_string())
-                    .collect::<Vec<_>>()
-                    .join("::")
-            } else {
-                String::from("<missing path>")
-            }
-        })
-    };
-
-    match map.find(id) {
-        Some(Node::Item(item)) => {
-            let item_str = match item.kind {
-                ItemKind::ExternCrate(..) => "extern crate",
-                ItemKind::Use(..) => "use",
-                ItemKind::Static(..) => "static",
-                ItemKind::Const(..) => "const",
-                ItemKind::Fn(..) => "fn",
-                ItemKind::Mod(..) => "mod",
-                ItemKind::ForeignMod(..) => "foreign mod",
-                ItemKind::GlobalAsm(..) => "global asm",
-                ItemKind::TyAlias(..) => "ty",
-                ItemKind::OpaqueTy(..) => "opaque type",
-                ItemKind::Enum(..) => "enum",
-                ItemKind::Struct(..) => "struct",
-                ItemKind::Union(..) => "union",
-                ItemKind::Trait(..) => "trait",
-                ItemKind::TraitAlias(..) => "trait alias",
-                ItemKind::Impl { .. } => "impl",
-            };
-            format!("{} {}{}", item_str, path_str(), id_str)
-        }
-        Some(Node::ForeignItem(_)) => format!("foreign item {}{}", path_str(), id_str),
-        Some(Node::ImplItem(ii)) => match ii.kind {
-            ImplItemKind::Const(..) => {
-                format!("assoc const {} in {}{}", ii.ident, path_str(), id_str)
-            }
-            ImplItemKind::Method(..) => format!("method {} in {}{}", ii.ident, path_str(), id_str),
-            ImplItemKind::TyAlias(_) => {
-                format!("assoc type {} in {}{}", ii.ident, path_str(), id_str)
-            }
-            ImplItemKind::OpaqueTy(_) => {
-                format!("assoc opaque type {} in {}{}", ii.ident, path_str(), id_str)
-            }
-        },
-        Some(Node::TraitItem(ti)) => {
-            let kind = match ti.kind {
-                TraitItemKind::Const(..) => "assoc constant",
-                TraitItemKind::Method(..) => "trait method",
-                TraitItemKind::Type(..) => "assoc type",
-            };
-
-            format!("{} {} in {}{}", kind, ti.ident, path_str(), id_str)
-        }
-        Some(Node::Variant(ref variant)) => {
-            format!("variant {} in {}{}", variant.ident, path_str(), id_str)
-        }
-        Some(Node::Field(ref field)) => {
-            format!("field {} in {}{}", field.ident, path_str(), id_str)
-        }
-        Some(Node::AnonConst(_)) => format!("const {}{}", map.hir_to_pretty_string(id), id_str),
-        Some(Node::Expr(_)) => format!("expr {}{}", map.hir_to_pretty_string(id), id_str),
-        Some(Node::Stmt(_)) => format!("stmt {}{}", map.hir_to_pretty_string(id), id_str),
-        Some(Node::PathSegment(_)) => {
-            format!("path segment {}{}", map.hir_to_pretty_string(id), id_str)
-        }
-        Some(Node::Ty(_)) => format!("type {}{}", map.hir_to_pretty_string(id), id_str),
-        Some(Node::TraitRef(_)) => format!("trait_ref {}{}", map.hir_to_pretty_string(id), id_str),
-        Some(Node::Binding(_)) => format!("local {}{}", map.hir_to_pretty_string(id), id_str),
-        Some(Node::Pat(_)) => format!("pat {}{}", map.hir_to_pretty_string(id), id_str),
-        Some(Node::Param(_)) => format!("param {}{}", map.hir_to_pretty_string(id), id_str),
-        Some(Node::Arm(_)) => format!("arm {}{}", map.hir_to_pretty_string(id), id_str),
-        Some(Node::Block(_)) => format!("block {}{}", map.hir_to_pretty_string(id), id_str),
-        Some(Node::Local(_)) => format!("local {}{}", map.hir_to_pretty_string(id), id_str),
-        Some(Node::Ctor(..)) => format!("ctor {}{}", path_str(), id_str),
-        Some(Node::Lifetime(_)) => format!("lifetime {}{}", map.hir_to_pretty_string(id), id_str),
-        Some(Node::GenericParam(ref param)) => format!("generic_param {:?}{}", param, id_str),
-        Some(Node::Visibility(ref vis)) => format!("visibility {:?}{}", vis, id_str),
-        Some(Node::MacroDef(_)) => format!("macro {}{}", path_str(), id_str),
-        Some(Node::Crate) => String::from("root_crate"),
-        None => format!("unknown node{}", id_str),
-    }
-}
-
-pub fn provide(providers: &mut Providers<'_>) {
-    providers.def_kind = |tcx, def_id| {
-        if let Some(hir_id) = tcx.hir().as_local_hir_id(def_id) {
-            tcx.hir().def_kind(hir_id)
-        } else {
-            bug!("calling local def_kind query provider for upstream DefId: {:?}", def_id);
-        }
-    };
-}
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
deleted file mode 100644
index 7d48280661a..00000000000
--- a/src/librustc/hir/mod.rs
+++ /dev/null
@@ -1,53 +0,0 @@
-//! HIR datatypes. See the [rustc guide] for more info.
-//!
-//! [rustc guide]: https://rust-lang.github.io/rustc-guide/hir.html
-
-pub mod exports;
-pub mod map;
-
-use crate::ty::query::Providers;
-use crate::ty::TyCtxt;
-use rustc_hir::def_id::LOCAL_CRATE;
-use rustc_hir::print;
-use rustc_hir::Crate;
-use std::ops::Deref;
-
-/// A wrapper type which allows you to access HIR.
-#[derive(Clone)]
-pub struct Hir<'tcx> {
-    tcx: TyCtxt<'tcx>,
-    map: &'tcx map::Map<'tcx>,
-}
-
-impl<'tcx> Hir<'tcx> {
-    pub fn krate(&self) -> &'tcx Crate<'tcx> {
-        self.tcx.hir_crate(LOCAL_CRATE)
-    }
-}
-
-impl<'tcx> Deref for Hir<'tcx> {
-    type Target = &'tcx map::Map<'tcx>;
-
-    #[inline(always)]
-    fn deref(&self) -> &Self::Target {
-        &self.map
-    }
-}
-
-impl<'hir> print::PpAnn for Hir<'hir> {
-    fn nested(&self, state: &mut print::State<'_>, nested: print::Nested) {
-        self.map.nested(state, nested)
-    }
-}
-
-impl<'tcx> TyCtxt<'tcx> {
-    #[inline(always)]
-    pub fn hir(self) -> Hir<'tcx> {
-        Hir { tcx: self, map: &self.hir_map }
-    }
-}
-
-pub fn provide(providers: &mut Providers<'_>) {
-    providers.hir_crate = |tcx, _| tcx.hir_map.untracked_krate();
-    map::provide(providers);
-}
diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs
deleted file mode 100644
index 1a9c5d1f13f..00000000000
--- a/src/librustc/ich/hcx.rs
+++ /dev/null
@@ -1,281 +0,0 @@
-use crate::hir::map::definitions::Definitions;
-use crate::hir::map::DefPathHash;
-use crate::ich::{self, CachingSourceMapView};
-use crate::middle::cstore::CrateStore;
-use crate::session::Session;
-use crate::ty::{fast_reject, TyCtxt};
-
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
-use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
-use rustc_data_structures::sync::Lrc;
-use rustc_hir as hir;
-use rustc_hir::def_id::{DefId, DefIndex};
-use rustc_span::source_map::SourceMap;
-use rustc_span::symbol::Symbol;
-use rustc_span::{BytePos, SourceFile};
-use syntax::ast;
-
-use smallvec::SmallVec;
-use std::cmp::Ord;
-
-fn compute_ignored_attr_names() -> FxHashSet<Symbol> {
-    debug_assert!(ich::IGNORED_ATTRIBUTES.len() > 0);
-    ich::IGNORED_ATTRIBUTES.iter().map(|&s| s).collect()
-}
-
-/// This is the context state available during incr. comp. hashing. It contains
-/// enough information to transform `DefId`s and `HirId`s into stable `DefPath`s (i.e.,
-/// a reference to the `TyCtxt`) and it holds a few caches for speeding up various
-/// things (e.g., each `DefId`/`DefPath` is only hashed once).
-#[derive(Clone)]
-pub struct StableHashingContext<'a> {
-    sess: &'a Session,
-    definitions: &'a Definitions,
-    cstore: &'a dyn CrateStore,
-    pub(super) body_resolver: BodyResolver<'a>,
-    hash_spans: bool,
-    hash_bodies: bool,
-    pub(super) node_id_hashing_mode: NodeIdHashingMode,
-
-    // Very often, we are hashing something that does not need the
-    // `CachingSourceMapView`, so we initialize it lazily.
-    raw_source_map: &'a SourceMap,
-    caching_source_map: Option<CachingSourceMapView<'a>>,
-}
-
-#[derive(PartialEq, Eq, Clone, Copy)]
-pub enum NodeIdHashingMode {
-    Ignore,
-    HashDefPath,
-}
-
-/// The `BodyResolver` allows mapping a `BodyId` to the corresponding `hir::Body`.
-/// We could also just store a plain reference to the `hir::Crate` but we want
-/// to avoid that the crate is used to get untracked access to all of the HIR.
-#[derive(Clone, Copy)]
-pub(super) struct BodyResolver<'tcx>(&'tcx hir::Crate<'tcx>);
-
-impl<'tcx> BodyResolver<'tcx> {
-    /// Returns a reference to the `hir::Body` with the given `BodyId`.
-    /// **Does not do any tracking**; use carefully.
-    pub(super) fn body(self, id: hir::BodyId) -> &'tcx hir::Body<'tcx> {
-        self.0.body(id)
-    }
-}
-
-impl<'a> StableHashingContext<'a> {
-    /// The `krate` here is only used for mapping `BodyId`s to `Body`s.
-    /// Don't use it for anything else or you'll run the risk of
-    /// leaking data out of the tracking system.
-    #[inline]
-    pub fn new(
-        sess: &'a Session,
-        krate: &'a hir::Crate<'a>,
-        definitions: &'a Definitions,
-        cstore: &'a dyn CrateStore,
-    ) -> Self {
-        let hash_spans_initial = !sess.opts.debugging_opts.incremental_ignore_spans;
-
-        StableHashingContext {
-            sess,
-            body_resolver: BodyResolver(krate),
-            definitions,
-            cstore,
-            caching_source_map: None,
-            raw_source_map: sess.source_map(),
-            hash_spans: hash_spans_initial,
-            hash_bodies: true,
-            node_id_hashing_mode: NodeIdHashingMode::HashDefPath,
-        }
-    }
-
-    #[inline]
-    pub fn sess(&self) -> &'a Session {
-        self.sess
-    }
-
-    #[inline]
-    pub fn while_hashing_hir_bodies<F: FnOnce(&mut Self)>(&mut self, hash_bodies: bool, f: F) {
-        let prev_hash_bodies = self.hash_bodies;
-        self.hash_bodies = hash_bodies;
-        f(self);
-        self.hash_bodies = prev_hash_bodies;
-    }
-
-    #[inline]
-    pub fn while_hashing_spans<F: FnOnce(&mut Self)>(&mut self, hash_spans: bool, f: F) {
-        let prev_hash_spans = self.hash_spans;
-        self.hash_spans = hash_spans;
-        f(self);
-        self.hash_spans = prev_hash_spans;
-    }
-
-    #[inline]
-    pub fn with_node_id_hashing_mode<F: FnOnce(&mut Self)>(
-        &mut self,
-        mode: NodeIdHashingMode,
-        f: F,
-    ) {
-        let prev = self.node_id_hashing_mode;
-        self.node_id_hashing_mode = mode;
-        f(self);
-        self.node_id_hashing_mode = prev;
-    }
-
-    #[inline]
-    pub fn def_path_hash(&self, def_id: DefId) -> DefPathHash {
-        if def_id.is_local() {
-            self.definitions.def_path_hash(def_id.index)
-        } else {
-            self.cstore.def_path_hash(def_id)
-        }
-    }
-
-    #[inline]
-    pub fn local_def_path_hash(&self, def_index: DefIndex) -> DefPathHash {
-        self.definitions.def_path_hash(def_index)
-    }
-
-    #[inline]
-    pub fn node_to_hir_id(&self, node_id: ast::NodeId) -> hir::HirId {
-        self.definitions.node_to_hir_id(node_id)
-    }
-
-    #[inline]
-    pub fn hash_bodies(&self) -> bool {
-        self.hash_bodies
-    }
-
-    #[inline]
-    pub fn source_map(&mut self) -> &mut CachingSourceMapView<'a> {
-        match self.caching_source_map {
-            Some(ref mut sm) => sm,
-            ref mut none => {
-                *none = Some(CachingSourceMapView::new(self.raw_source_map));
-                none.as_mut().unwrap()
-            }
-        }
-    }
-
-    #[inline]
-    pub fn is_ignored_attr(&self, name: Symbol) -> bool {
-        thread_local! {
-            static IGNORED_ATTRIBUTES: FxHashSet<Symbol> = compute_ignored_attr_names();
-        }
-        IGNORED_ATTRIBUTES.with(|attrs| attrs.contains(&name))
-    }
-
-    pub fn hash_hir_item_like<F: FnOnce(&mut Self)>(&mut self, f: F) {
-        let prev_hash_node_ids = self.node_id_hashing_mode;
-        self.node_id_hashing_mode = NodeIdHashingMode::Ignore;
-
-        f(self);
-
-        self.node_id_hashing_mode = prev_hash_node_ids;
-    }
-}
-
-/// Something that can provide a stable hashing context.
-pub trait StableHashingContextProvider<'a> {
-    fn get_stable_hashing_context(&self) -> StableHashingContext<'a>;
-}
-
-impl<'a, 'b, T: StableHashingContextProvider<'a>> StableHashingContextProvider<'a> for &'b T {
-    fn get_stable_hashing_context(&self) -> StableHashingContext<'a> {
-        (**self).get_stable_hashing_context()
-    }
-}
-
-impl<'a, 'b, T: StableHashingContextProvider<'a>> StableHashingContextProvider<'a> for &'b mut T {
-    fn get_stable_hashing_context(&self) -> StableHashingContext<'a> {
-        (**self).get_stable_hashing_context()
-    }
-}
-
-impl StableHashingContextProvider<'tcx> for TyCtxt<'tcx> {
-    fn get_stable_hashing_context(&self) -> StableHashingContext<'tcx> {
-        (*self).create_stable_hashing_context()
-    }
-}
-
-impl<'a> StableHashingContextProvider<'a> for StableHashingContext<'a> {
-    fn get_stable_hashing_context(&self) -> StableHashingContext<'a> {
-        self.clone()
-    }
-}
-
-impl<'a> crate::dep_graph::DepGraphSafe for StableHashingContext<'a> {}
-
-impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::HirId {
-    type KeyType = (DefPathHash, hir::ItemLocalId);
-
-    #[inline]
-    fn to_stable_hash_key(
-        &self,
-        hcx: &StableHashingContext<'a>,
-    ) -> (DefPathHash, hir::ItemLocalId) {
-        let def_path_hash = hcx.local_def_path_hash(self.owner);
-        (def_path_hash, self.local_id)
-    }
-}
-
-impl<'a> HashStable<StableHashingContext<'a>> for ast::NodeId {
-    fn hash_stable(&self, _: &mut StableHashingContext<'a>, _: &mut StableHasher) {
-        panic!("Node IDs should not appear in incremental state");
-    }
-}
-
-impl<'a> rustc_span::HashStableContext for StableHashingContext<'a> {
-    fn hash_spans(&self) -> bool {
-        self.hash_spans
-    }
-
-    #[inline]
-    fn hash_def_id(&mut self, def_id: DefId, hasher: &mut StableHasher) {
-        let hcx = self;
-        hcx.def_path_hash(def_id).hash_stable(hcx, hasher);
-    }
-
-    fn byte_pos_to_line_and_col(
-        &mut self,
-        byte: BytePos,
-    ) -> Option<(Lrc<SourceFile>, usize, BytePos)> {
-        self.source_map().byte_pos_to_line_and_col(byte)
-    }
-}
-
-pub fn hash_stable_trait_impls<'a>(
-    hcx: &mut StableHashingContext<'a>,
-    hasher: &mut StableHasher,
-    blanket_impls: &[DefId],
-    non_blanket_impls: &FxHashMap<fast_reject::SimplifiedType, Vec<DefId>>,
-) {
-    {
-        let mut blanket_impls: SmallVec<[_; 8]> =
-            blanket_impls.iter().map(|&def_id| hcx.def_path_hash(def_id)).collect();
-
-        if blanket_impls.len() > 1 {
-            blanket_impls.sort_unstable();
-        }
-
-        blanket_impls.hash_stable(hcx, hasher);
-    }
-
-    {
-        let mut keys: SmallVec<[_; 8]> =
-            non_blanket_impls.keys().map(|k| (k, k.map_def(|d| hcx.def_path_hash(d)))).collect();
-        keys.sort_unstable_by(|&(_, ref k1), &(_, ref k2)| k1.cmp(k2));
-        keys.len().hash_stable(hcx, hasher);
-        for (key, ref stable_key) in keys {
-            stable_key.hash_stable(hcx, hasher);
-            let mut impls: SmallVec<[_; 8]> =
-                non_blanket_impls[key].iter().map(|&impl_id| hcx.def_path_hash(impl_id)).collect();
-
-            if impls.len() > 1 {
-                impls.sort_unstable();
-            }
-
-            impls.hash_stable(hcx, hasher);
-        }
-    }
-}
diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs
deleted file mode 100644
index eadc9ddeee6..00000000000
--- a/src/librustc/ich/impls_hir.rs
+++ /dev/null
@@ -1,289 +0,0 @@
-//! This module contains `HashStable` implementations for various HIR data
-//! types in no particular order.
-
-use crate::hir::map::DefPathHash;
-use crate::ich::{Fingerprint, NodeIdHashingMode, StableHashingContext};
-use rustc_attr as attr;
-use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
-use rustc_hir as hir;
-use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, CRATE_DEF_INDEX};
-use smallvec::SmallVec;
-use std::mem;
-
-impl<'ctx> rustc_hir::HashStableContext for StableHashingContext<'ctx> {
-    #[inline]
-    fn hash_hir_id(&mut self, hir_id: hir::HirId, hasher: &mut StableHasher) {
-        let hcx = self;
-        match hcx.node_id_hashing_mode {
-            NodeIdHashingMode::Ignore => {
-                // Don't do anything.
-            }
-            NodeIdHashingMode::HashDefPath => {
-                let hir::HirId { owner, local_id } = hir_id;
-
-                hcx.local_def_path_hash(owner).hash_stable(hcx, hasher);
-                local_id.hash_stable(hcx, hasher);
-            }
-        }
-    }
-
-    fn hash_body_id(&mut self, id: hir::BodyId, hasher: &mut StableHasher) {
-        let hcx = self;
-        if hcx.hash_bodies() {
-            hcx.body_resolver.body(id).hash_stable(hcx, hasher);
-        }
-    }
-
-    fn hash_reference_to_item(&mut self, id: hir::HirId, hasher: &mut StableHasher) {
-        let hcx = self;
-
-        hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
-            id.hash_stable(hcx, hasher);
-        })
-    }
-
-    fn hash_hir_mod(&mut self, module: &hir::Mod<'_>, hasher: &mut StableHasher) {
-        let hcx = self;
-        let hir::Mod { inner: ref inner_span, ref item_ids } = *module;
-
-        inner_span.hash_stable(hcx, hasher);
-
-        // Combining the `DefPathHash`s directly is faster than feeding them
-        // into the hasher. Because we use a commutative combine, we also don't
-        // have to sort the array.
-        let item_ids_hash = item_ids
-            .iter()
-            .map(|id| {
-                let (def_path_hash, local_id) = id.id.to_stable_hash_key(hcx);
-                debug_assert_eq!(local_id, hir::ItemLocalId::from_u32(0));
-                def_path_hash.0
-            })
-            .fold(Fingerprint::ZERO, |a, b| a.combine_commutative(b));
-
-        item_ids.len().hash_stable(hcx, hasher);
-        item_ids_hash.hash_stable(hcx, hasher);
-    }
-
-    fn hash_hir_expr(&mut self, expr: &hir::Expr<'_>, hasher: &mut StableHasher) {
-        self.while_hashing_hir_bodies(true, |hcx| {
-            let hir::Expr { hir_id: _, ref span, ref kind, ref attrs } = *expr;
-
-            span.hash_stable(hcx, hasher);
-            kind.hash_stable(hcx, hasher);
-            attrs.hash_stable(hcx, hasher);
-        })
-    }
-
-    fn hash_hir_ty(&mut self, ty: &hir::Ty<'_>, hasher: &mut StableHasher) {
-        self.while_hashing_hir_bodies(true, |hcx| {
-            let hir::Ty { hir_id: _, ref kind, ref span } = *ty;
-
-            kind.hash_stable(hcx, hasher);
-            span.hash_stable(hcx, hasher);
-        })
-    }
-
-    fn hash_hir_visibility_kind(
-        &mut self,
-        vis: &hir::VisibilityKind<'_>,
-        hasher: &mut StableHasher,
-    ) {
-        let hcx = self;
-        mem::discriminant(vis).hash_stable(hcx, hasher);
-        match *vis {
-            hir::VisibilityKind::Public | hir::VisibilityKind::Inherited => {
-                // No fields to hash.
-            }
-            hir::VisibilityKind::Crate(sugar) => {
-                sugar.hash_stable(hcx, hasher);
-            }
-            hir::VisibilityKind::Restricted { ref path, hir_id } => {
-                hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
-                    hir_id.hash_stable(hcx, hasher);
-                });
-                path.hash_stable(hcx, hasher);
-            }
-        }
-    }
-}
-
-impl<'a> ToStableHashKey<StableHashingContext<'a>> for DefId {
-    type KeyType = DefPathHash;
-
-    #[inline]
-    fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
-        hcx.def_path_hash(*self)
-    }
-}
-
-impl<'a> HashStable<StableHashingContext<'a>> for LocalDefId {
-    #[inline]
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        hcx.def_path_hash(self.to_def_id()).hash_stable(hcx, hasher);
-    }
-}
-
-impl<'a> ToStableHashKey<StableHashingContext<'a>> for LocalDefId {
-    type KeyType = DefPathHash;
-
-    #[inline]
-    fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
-        hcx.def_path_hash(self.to_def_id())
-    }
-}
-
-impl<'a> HashStable<StableHashingContext<'a>> for CrateNum {
-    #[inline]
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        hcx.def_path_hash(DefId { krate: *self, index: CRATE_DEF_INDEX }).hash_stable(hcx, hasher);
-    }
-}
-
-impl<'a> ToStableHashKey<StableHashingContext<'a>> for CrateNum {
-    type KeyType = DefPathHash;
-
-    #[inline]
-    fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
-        let def_id = DefId { krate: *self, index: CRATE_DEF_INDEX };
-        def_id.to_stable_hash_key(hcx)
-    }
-}
-
-impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::ItemLocalId {
-    type KeyType = hir::ItemLocalId;
-
-    #[inline]
-    fn to_stable_hash_key(&self, _: &StableHashingContext<'a>) -> hir::ItemLocalId {
-        *self
-    }
-}
-
-impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitItem<'_> {
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        let hir::TraitItem { hir_id: _, ident, ref attrs, ref generics, ref kind, span } = *self;
-
-        hcx.hash_hir_item_like(|hcx| {
-            ident.name.hash_stable(hcx, hasher);
-            attrs.hash_stable(hcx, hasher);
-            generics.hash_stable(hcx, hasher);
-            kind.hash_stable(hcx, hasher);
-            span.hash_stable(hcx, hasher);
-        });
-    }
-}
-
-impl<'a> HashStable<StableHashingContext<'a>> for hir::ImplItem<'_> {
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        let hir::ImplItem {
-            hir_id: _,
-            ident,
-            ref vis,
-            defaultness,
-            ref attrs,
-            ref generics,
-            ref kind,
-            span,
-        } = *self;
-
-        hcx.hash_hir_item_like(|hcx| {
-            ident.name.hash_stable(hcx, hasher);
-            vis.hash_stable(hcx, hasher);
-            defaultness.hash_stable(hcx, hasher);
-            attrs.hash_stable(hcx, hasher);
-            generics.hash_stable(hcx, hasher);
-            kind.hash_stable(hcx, hasher);
-            span.hash_stable(hcx, hasher);
-        });
-    }
-}
-
-impl<'a> HashStable<StableHashingContext<'a>> for hir::Item<'_> {
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        let hir::Item { ident, ref attrs, hir_id: _, ref kind, ref vis, span } = *self;
-
-        hcx.hash_hir_item_like(|hcx| {
-            ident.name.hash_stable(hcx, hasher);
-            attrs.hash_stable(hcx, hasher);
-            kind.hash_stable(hcx, hasher);
-            vis.hash_stable(hcx, hasher);
-            span.hash_stable(hcx, hasher);
-        });
-    }
-}
-
-impl<'a> HashStable<StableHashingContext<'a>> for hir::Body<'_> {
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        let hir::Body { params, value, generator_kind } = self;
-
-        hcx.with_node_id_hashing_mode(NodeIdHashingMode::Ignore, |hcx| {
-            params.hash_stable(hcx, hasher);
-            value.hash_stable(hcx, hasher);
-            generator_kind.hash_stable(hcx, hasher);
-        });
-    }
-}
-
-impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::BodyId {
-    type KeyType = (DefPathHash, hir::ItemLocalId);
-
-    #[inline]
-    fn to_stable_hash_key(
-        &self,
-        hcx: &StableHashingContext<'a>,
-    ) -> (DefPathHash, hir::ItemLocalId) {
-        let hir::BodyId { hir_id } = *self;
-        hir_id.to_stable_hash_key(hcx)
-    }
-}
-
-impl<'a> HashStable<StableHashingContext<'a>> for hir::def_id::DefIndex {
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        hcx.local_def_path_hash(*self).hash_stable(hcx, hasher);
-    }
-}
-
-impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::def_id::DefIndex {
-    type KeyType = DefPathHash;
-
-    #[inline]
-    fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
-        hcx.local_def_path_hash(*self)
-    }
-}
-
-impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitCandidate {
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
-            let hir::TraitCandidate { def_id, import_ids } = self;
-
-            def_id.hash_stable(hcx, hasher);
-            import_ids.hash_stable(hcx, hasher);
-        });
-    }
-}
-
-impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::TraitCandidate {
-    type KeyType = (DefPathHash, SmallVec<[(DefPathHash, hir::ItemLocalId); 1]>);
-
-    fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> Self::KeyType {
-        let hir::TraitCandidate { def_id, import_ids } = self;
-
-        let import_keys = import_ids
-            .iter()
-            .map(|hir_id| (hcx.local_def_path_hash(hir_id.owner), hir_id.local_id))
-            .collect();
-        (hcx.def_path_hash(*def_id), import_keys)
-    }
-}
-
-impl<'hir> HashStable<StableHashingContext<'hir>> for attr::InlineAttr {
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'hir>, hasher: &mut StableHasher) {
-        mem::discriminant(self).hash_stable(hcx, hasher);
-    }
-}
-
-impl<'hir> HashStable<StableHashingContext<'hir>> for attr::OptimizeAttr {
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'hir>, hasher: &mut StableHasher) {
-        mem::discriminant(self).hash_stable(hcx, hasher);
-    }
-}
diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs
deleted file mode 100644
index d1815d5e320..00000000000
--- a/src/librustc/ich/impls_syntax.rs
+++ /dev/null
@@ -1,151 +0,0 @@
-//! This module contains `HashStable` implementations for various data types
-//! from libsyntax in no particular order.
-
-use crate::ich::StableHashingContext;
-
-use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
-use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX};
-use rustc_span::SourceFile;
-use syntax::ast;
-
-use smallvec::SmallVec;
-
-impl<'ctx> rustc_target::HashStableContext for StableHashingContext<'ctx> {}
-
-impl<'a> HashStable<StableHashingContext<'a>> for [ast::Attribute] {
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        if self.len() == 0 {
-            self.len().hash_stable(hcx, hasher);
-            return;
-        }
-
-        // Some attributes are always ignored during hashing.
-        let filtered: SmallVec<[&ast::Attribute; 8]> = self
-            .iter()
-            .filter(|attr| {
-                !attr.is_doc_comment()
-                    && !attr.ident().map_or(false, |ident| hcx.is_ignored_attr(ident.name))
-            })
-            .collect();
-
-        filtered.len().hash_stable(hcx, hasher);
-        for attr in filtered {
-            attr.hash_stable(hcx, hasher);
-        }
-    }
-}
-
-impl<'ctx> syntax::HashStableContext for StableHashingContext<'ctx> {
-    fn hash_attr(&mut self, attr: &ast::Attribute, hasher: &mut StableHasher) {
-        // Make sure that these have been filtered out.
-        debug_assert!(!attr.ident().map_or(false, |ident| self.is_ignored_attr(ident.name)));
-        debug_assert!(!attr.is_doc_comment());
-
-        let ast::Attribute { kind, id: _, style, span } = attr;
-        if let ast::AttrKind::Normal(item) = kind {
-            item.hash_stable(self, hasher);
-            style.hash_stable(self, hasher);
-            span.hash_stable(self, hasher);
-        } else {
-            unreachable!();
-        }
-    }
-}
-
-impl<'a> HashStable<StableHashingContext<'a>> for SourceFile {
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        let SourceFile {
-            name: _, // We hash the smaller name_hash instead of this
-            name_hash,
-            name_was_remapped,
-            unmapped_path: _,
-            crate_of_origin,
-            // Do not hash the source as it is not encoded
-            src: _,
-            src_hash,
-            external_src: _,
-            start_pos,
-            end_pos: _,
-            ref lines,
-            ref multibyte_chars,
-            ref non_narrow_chars,
-            ref normalized_pos,
-        } = *self;
-
-        (name_hash as u64).hash_stable(hcx, hasher);
-        name_was_remapped.hash_stable(hcx, hasher);
-
-        DefId { krate: CrateNum::from_u32(crate_of_origin), index: CRATE_DEF_INDEX }
-            .hash_stable(hcx, hasher);
-
-        src_hash.hash_stable(hcx, hasher);
-
-        // We only hash the relative position within this source_file
-        lines.len().hash_stable(hcx, hasher);
-        for &line in lines.iter() {
-            stable_byte_pos(line, start_pos).hash_stable(hcx, hasher);
-        }
-
-        // We only hash the relative position within this source_file
-        multibyte_chars.len().hash_stable(hcx, hasher);
-        for &char_pos in multibyte_chars.iter() {
-            stable_multibyte_char(char_pos, start_pos).hash_stable(hcx, hasher);
-        }
-
-        non_narrow_chars.len().hash_stable(hcx, hasher);
-        for &char_pos in non_narrow_chars.iter() {
-            stable_non_narrow_char(char_pos, start_pos).hash_stable(hcx, hasher);
-        }
-
-        normalized_pos.len().hash_stable(hcx, hasher);
-        for &char_pos in normalized_pos.iter() {
-            stable_normalized_pos(char_pos, start_pos).hash_stable(hcx, hasher);
-        }
-    }
-}
-
-fn stable_byte_pos(pos: ::rustc_span::BytePos, source_file_start: ::rustc_span::BytePos) -> u32 {
-    pos.0 - source_file_start.0
-}
-
-fn stable_multibyte_char(
-    mbc: ::rustc_span::MultiByteChar,
-    source_file_start: ::rustc_span::BytePos,
-) -> (u32, u32) {
-    let ::rustc_span::MultiByteChar { pos, bytes } = mbc;
-
-    (pos.0 - source_file_start.0, bytes as u32)
-}
-
-fn stable_non_narrow_char(
-    swc: ::rustc_span::NonNarrowChar,
-    source_file_start: ::rustc_span::BytePos,
-) -> (u32, u32) {
-    let pos = swc.pos();
-    let width = swc.width();
-
-    (pos.0 - source_file_start.0, width as u32)
-}
-
-fn stable_normalized_pos(
-    np: ::rustc_span::NormalizedPos,
-    source_file_start: ::rustc_span::BytePos,
-) -> (u32, u32) {
-    let ::rustc_span::NormalizedPos { pos, diff } = np;
-
-    (pos.0 - source_file_start.0, diff)
-}
-
-impl<'tcx> HashStable<StableHashingContext<'tcx>> for rustc_feature::Features {
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'tcx>, hasher: &mut StableHasher) {
-        // Unfortunately we cannot exhaustively list fields here, since the
-        // struct is macro generated.
-        self.declared_lang_features.hash_stable(hcx, hasher);
-        self.declared_lib_features.hash_stable(hcx, hasher);
-
-        self.walk_feature_fields(|feature_name, value| {
-            feature_name.hash_stable(hcx, hasher);
-            value.hash_stable(hcx, hasher);
-        });
-    }
-}
diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs
deleted file mode 100644
index 844250f51a0..00000000000
--- a/src/librustc/ich/impls_ty.rs
+++ /dev/null
@@ -1,210 +0,0 @@
-//! This module contains `HashStable` implementations for various data types
-//! from rustc::ty in no particular order.
-
-use crate::ich::{Fingerprint, NodeIdHashingMode, StableHashingContext};
-use crate::middle::region;
-use crate::mir;
-use crate::ty;
-use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
-use std::cell::RefCell;
-use std::mem;
-
-impl<'a, 'tcx, T> HashStable<StableHashingContext<'a>> for &'tcx ty::List<T>
-where
-    T: HashStable<StableHashingContext<'a>>,
-{
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        thread_local! {
-            static CACHE: RefCell<FxHashMap<(usize, usize), Fingerprint>> =
-                RefCell::new(Default::default());
-        }
-
-        let hash = CACHE.with(|cache| {
-            let key = (self.as_ptr() as usize, self.len());
-            if let Some(&hash) = cache.borrow().get(&key) {
-                return hash;
-            }
-
-            let mut hasher = StableHasher::new();
-            (&self[..]).hash_stable(hcx, &mut hasher);
-
-            let hash: Fingerprint = hasher.finish();
-            cache.borrow_mut().insert(key, hash);
-            hash
-        });
-
-        hash.hash_stable(hcx, hasher);
-    }
-}
-
-impl<'a, 'tcx, T> ToStableHashKey<StableHashingContext<'a>> for &'tcx ty::List<T>
-where
-    T: HashStable<StableHashingContext<'a>>,
-{
-    type KeyType = Fingerprint;
-
-    #[inline]
-    fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> Fingerprint {
-        let mut hasher = StableHasher::new();
-        let mut hcx: StableHashingContext<'a> = hcx.clone();
-        self.hash_stable(&mut hcx, &mut hasher);
-        hasher.finish()
-    }
-}
-
-impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ty::subst::GenericArg<'tcx> {
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        self.unpack().hash_stable(hcx, hasher);
-    }
-}
-
-impl<'a> HashStable<StableHashingContext<'a>> for ty::RegionKind {
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        mem::discriminant(self).hash_stable(hcx, hasher);
-        match *self {
-            ty::ReErased | ty::ReStatic => {
-                // No variant fields to hash for these ...
-            }
-            ty::ReEmpty(universe) => {
-                universe.hash_stable(hcx, hasher);
-            }
-            ty::ReLateBound(db, ty::BrAnon(i)) => {
-                db.hash_stable(hcx, hasher);
-                i.hash_stable(hcx, hasher);
-            }
-            ty::ReLateBound(db, ty::BrNamed(def_id, name)) => {
-                db.hash_stable(hcx, hasher);
-                def_id.hash_stable(hcx, hasher);
-                name.hash_stable(hcx, hasher);
-            }
-            ty::ReLateBound(db, ty::BrEnv) => {
-                db.hash_stable(hcx, hasher);
-            }
-            ty::ReEarlyBound(ty::EarlyBoundRegion { def_id, index, name }) => {
-                def_id.hash_stable(hcx, hasher);
-                index.hash_stable(hcx, hasher);
-                name.hash_stable(hcx, hasher);
-            }
-            ty::ReScope(scope) => {
-                scope.hash_stable(hcx, hasher);
-            }
-            ty::ReFree(ref free_region) => {
-                free_region.hash_stable(hcx, hasher);
-            }
-            ty::ReClosureBound(vid) => {
-                vid.hash_stable(hcx, hasher);
-            }
-            ty::ReVar(..) | ty::RePlaceholder(..) => {
-                bug!("StableHasher: unexpected region {:?}", *self)
-            }
-        }
-    }
-}
-
-impl<'a> HashStable<StableHashingContext<'a>> for ty::RegionVid {
-    #[inline]
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        self.index().hash_stable(hcx, hasher);
-    }
-}
-
-impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ty::ConstVid<'tcx> {
-    #[inline]
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        self.index.hash_stable(hcx, hasher);
-    }
-}
-
-impl<'tcx> HashStable<StableHashingContext<'tcx>> for ty::BoundVar {
-    #[inline]
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'tcx>, hasher: &mut StableHasher) {
-        self.index().hash_stable(hcx, hasher);
-    }
-}
-
-impl<'a, T> HashStable<StableHashingContext<'a>> for ty::Binder<T>
-where
-    T: HashStable<StableHashingContext<'a>>,
-{
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        self.skip_binder().hash_stable(hcx, hasher);
-    }
-}
-
-// AllocIds get resolved to whatever they point to (to be stable)
-impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::AllocId {
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        ty::tls::with_opt(|tcx| {
-            trace!("hashing {:?}", *self);
-            let tcx = tcx.expect("can't hash AllocIds during hir lowering");
-            let alloc_kind = tcx.alloc_map.lock().get(*self);
-            alloc_kind.hash_stable(hcx, hasher);
-        });
-    }
-}
-
-// `Relocations` with default type parameters is a sorted map.
-impl<'a, Tag> HashStable<StableHashingContext<'a>> for mir::interpret::Relocations<Tag>
-where
-    Tag: HashStable<StableHashingContext<'a>>,
-{
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        self.len().hash_stable(hcx, hasher);
-        for reloc in self.iter() {
-            reloc.hash_stable(hcx, hasher);
-        }
-    }
-}
-
-impl<'a> ToStableHashKey<StableHashingContext<'a>> for region::Scope {
-    type KeyType = region::Scope;
-
-    #[inline]
-    fn to_stable_hash_key(&self, _: &StableHashingContext<'a>) -> region::Scope {
-        *self
-    }
-}
-
-impl<'a> HashStable<StableHashingContext<'a>> for ty::TyVid {
-    fn hash_stable(&self, _hcx: &mut StableHashingContext<'a>, _hasher: &mut StableHasher) {
-        // `TyVid` values are confined to an inference context and hence
-        // should not be hashed.
-        bug!("ty::TyKind::hash_stable() - can't hash a TyVid {:?}.", *self)
-    }
-}
-
-impl<'a> HashStable<StableHashingContext<'a>> for ty::IntVid {
-    fn hash_stable(&self, _hcx: &mut StableHashingContext<'a>, _hasher: &mut StableHasher) {
-        // `IntVid` values are confined to an inference context and hence
-        // should not be hashed.
-        bug!("ty::TyKind::hash_stable() - can't hash an IntVid {:?}.", *self)
-    }
-}
-
-impl<'a> HashStable<StableHashingContext<'a>> for ty::FloatVid {
-    fn hash_stable(&self, _hcx: &mut StableHashingContext<'a>, _hasher: &mut StableHasher) {
-        // `FloatVid` values are confined to an inference context and hence
-        // should not be hashed.
-        bug!("ty::TyKind::hash_stable() - can't hash a FloatVid {:?}.", *self)
-    }
-}
-
-impl<'a, T> HashStable<StableHashingContext<'a>> for ty::steal::Steal<T>
-where
-    T: HashStable<StableHashingContext<'a>>,
-{
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        self.borrow().hash_stable(hcx, hasher);
-    }
-}
-
-impl<'a> HashStable<StableHashingContext<'a>> for crate::middle::privacy::AccessLevels {
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
-            let crate::middle::privacy::AccessLevels { ref map } = *self;
-
-            map.hash_stable(hcx, hasher);
-        });
-    }
-}
diff --git a/src/librustc/ich/mod.rs b/src/librustc/ich/mod.rs
deleted file mode 100644
index 2c4618dcd42..00000000000
--- a/src/librustc/ich/mod.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-//! ICH - Incremental Compilation Hash
-
-pub use self::hcx::{
-    hash_stable_trait_impls, NodeIdHashingMode, StableHashingContext, StableHashingContextProvider,
-};
-crate use rustc_data_structures::fingerprint::Fingerprint;
-use rustc_span::symbol::{sym, Symbol};
-pub use rustc_span::CachingSourceMapView;
-
-mod hcx;
-
-mod impls_hir;
-mod impls_syntax;
-mod impls_ty;
-
-pub const IGNORED_ATTRIBUTES: &[Symbol] = &[
-    sym::cfg,
-    sym::rustc_if_this_changed,
-    sym::rustc_then_this_would_need,
-    sym::rustc_dirty,
-    sym::rustc_clean,
-    sym::rustc_partition_reused,
-    sym::rustc_partition_codegened,
-    sym::rustc_expected_cgu_reuse,
-];
diff --git a/src/librustc/infer/canonical.rs b/src/librustc/infer/canonical.rs
deleted file mode 100644
index 76d0d57e233..00000000000
--- a/src/librustc/infer/canonical.rs
+++ /dev/null
@@ -1,357 +0,0 @@
-//! **Canonicalization** is the key to constructing a query in the
-//! middle of type inference. Ordinarily, it is not possible to store
-//! types from type inference in query keys, because they contain
-//! references to inference variables whose lifetimes are too short
-//! and so forth. Canonicalizing a value T1 using `canonicalize_query`
-//! produces two things:
-//!
-//! - a value T2 where each unbound inference variable has been
-//!   replaced with a **canonical variable**;
-//! - a map M (of type `CanonicalVarValues`) from those canonical
-//!   variables back to the original.
-//!
-//! We can then do queries using T2. These will give back constraints
-//! on the canonical variables which can be translated, using the map
-//! M, into constraints in our source context. This process of
-//! translating the results back is done by the
-//! `instantiate_query_result` method.
-//!
-//! For a more detailed look at what is happening here, check
-//! out the [chapter in the rustc guide][c].
-//!
-//! [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html
-
-use crate::infer::MemberConstraint;
-use crate::ty::subst::GenericArg;
-use crate::ty::{self, BoundVar, List, Region, TyCtxt};
-use rustc_index::vec::IndexVec;
-use rustc_macros::HashStable;
-use rustc_serialize::UseSpecializedDecodable;
-use smallvec::SmallVec;
-use std::ops::Index;
-
-/// A "canonicalized" type `V` is one where all free inference
-/// variables have been rewritten to "canonical vars". These are
-/// numbered starting from 0 in order of first appearance.
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable)]
-#[derive(HashStable, TypeFoldable, Lift)]
-pub struct Canonical<'tcx, V> {
-    pub max_universe: ty::UniverseIndex,
-    pub variables: CanonicalVarInfos<'tcx>,
-    pub value: V,
-}
-
-pub type CanonicalVarInfos<'tcx> = &'tcx List<CanonicalVarInfo>;
-
-impl<'tcx> UseSpecializedDecodable for CanonicalVarInfos<'tcx> {}
-
-/// A set of values corresponding to the canonical variables from some
-/// `Canonical`. You can give these values to
-/// `canonical_value.substitute` to substitute them into the canonical
-/// value at the right places.
-///
-/// When you canonicalize a value `V`, you get back one of these
-/// vectors with the original values that were replaced by canonical
-/// variables. You will need to supply it later to instantiate the
-/// canonicalized query response.
-#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable)]
-#[derive(HashStable, TypeFoldable, Lift)]
-pub struct CanonicalVarValues<'tcx> {
-    pub var_values: IndexVec<BoundVar, GenericArg<'tcx>>,
-}
-
-/// When we canonicalize a value to form a query, we wind up replacing
-/// various parts of it with canonical variables. This struct stores
-/// those replaced bits to remember for when we process the query
-/// result.
-#[derive(Clone, Debug)]
-pub struct OriginalQueryValues<'tcx> {
-    /// Map from the universes that appear in the query to the
-    /// universes in the caller context. For the time being, we only
-    /// ever put ROOT values into the query, so this map is very
-    /// simple.
-    pub universe_map: SmallVec<[ty::UniverseIndex; 4]>,
-
-    /// This is equivalent to `CanonicalVarValues`, but using a
-    /// `SmallVec` yields a significant performance win.
-    pub var_values: SmallVec<[GenericArg<'tcx>; 8]>,
-}
-
-impl Default for OriginalQueryValues<'tcx> {
-    fn default() -> Self {
-        let mut universe_map = SmallVec::default();
-        universe_map.push(ty::UniverseIndex::ROOT);
-
-        Self { universe_map, var_values: SmallVec::default() }
-    }
-}
-
-/// Information about a canonical variable that is included with the
-/// canonical value. This is sufficient information for code to create
-/// a copy of the canonical value in some other inference context,
-/// with fresh inference variables replacing the canonical values.
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable, HashStable)]
-pub struct CanonicalVarInfo {
-    pub kind: CanonicalVarKind,
-}
-
-impl CanonicalVarInfo {
-    pub fn universe(&self) -> ty::UniverseIndex {
-        self.kind.universe()
-    }
-
-    pub fn is_existential(&self) -> bool {
-        match self.kind {
-            CanonicalVarKind::Ty(_) => true,
-            CanonicalVarKind::PlaceholderTy(_) => false,
-            CanonicalVarKind::Region(_) => true,
-            CanonicalVarKind::PlaceholderRegion(..) => false,
-            CanonicalVarKind::Const(_) => true,
-            CanonicalVarKind::PlaceholderConst(_) => false,
-        }
-    }
-}
-
-/// Describes the "kind" of the canonical variable. This is a "kind"
-/// in the type-theory sense of the term -- i.e., a "meta" type system
-/// that analyzes type-like values.
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable, HashStable)]
-pub enum CanonicalVarKind {
-    /// Some kind of type inference variable.
-    Ty(CanonicalTyVarKind),
-
-    /// A "placeholder" that represents "any type".
-    PlaceholderTy(ty::PlaceholderType),
-
-    /// Region variable `'?R`.
-    Region(ty::UniverseIndex),
-
-    /// A "placeholder" that represents "any region". Created when you
-    /// are solving a goal like `for<'a> T: Foo<'a>` to represent the
-    /// bound region `'a`.
-    PlaceholderRegion(ty::PlaceholderRegion),
-
-    /// Some kind of const inference variable.
-    Const(ty::UniverseIndex),
-
-    /// A "placeholder" that represents "any const".
-    PlaceholderConst(ty::PlaceholderConst),
-}
-
-impl CanonicalVarKind {
-    pub fn universe(self) -> ty::UniverseIndex {
-        match self {
-            CanonicalVarKind::Ty(kind) => match kind {
-                CanonicalTyVarKind::General(ui) => ui,
-                CanonicalTyVarKind::Float | CanonicalTyVarKind::Int => ty::UniverseIndex::ROOT,
-            },
-
-            CanonicalVarKind::PlaceholderTy(placeholder) => placeholder.universe,
-            CanonicalVarKind::Region(ui) => ui,
-            CanonicalVarKind::PlaceholderRegion(placeholder) => placeholder.universe,
-            CanonicalVarKind::Const(ui) => ui,
-            CanonicalVarKind::PlaceholderConst(placeholder) => placeholder.universe,
-        }
-    }
-}
-
-/// Rust actually has more than one category of type variables;
-/// notably, the type variables we create for literals (e.g., 22 or
-/// 22.) can only be instantiated with integral/float types (e.g.,
-/// usize or f32). In order to faithfully reproduce a type, we need to
-/// know what set of types a given type variable can be unified with.
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable, HashStable)]
-pub enum CanonicalTyVarKind {
-    /// General type variable `?T` that can be unified with arbitrary types.
-    General(ty::UniverseIndex),
-
-    /// Integral type variable `?I` (that can only be unified with integral types).
-    Int,
-
-    /// Floating-point type variable `?F` (that can only be unified with float types).
-    Float,
-}
-
-/// After we execute a query with a canonicalized key, we get back a
-/// `Canonical<QueryResponse<..>>`. You can use
-/// `instantiate_query_result` to access the data in this result.
-#[derive(Clone, Debug, HashStable, TypeFoldable, Lift)]
-pub struct QueryResponse<'tcx, R> {
-    pub var_values: CanonicalVarValues<'tcx>,
-    pub region_constraints: QueryRegionConstraints<'tcx>,
-    pub certainty: Certainty,
-    pub value: R,
-}
-
-#[derive(Clone, Debug, Default, HashStable, TypeFoldable, Lift)]
-pub struct QueryRegionConstraints<'tcx> {
-    pub outlives: Vec<QueryOutlivesConstraint<'tcx>>,
-    pub member_constraints: Vec<MemberConstraint<'tcx>>,
-}
-
-impl QueryRegionConstraints<'_> {
-    /// Represents an empty (trivially true) set of region
-    /// constraints.
-    pub fn is_empty(&self) -> bool {
-        self.outlives.is_empty() && self.member_constraints.is_empty()
-    }
-}
-
-pub type Canonicalized<'tcx, V> = Canonical<'tcx, V>;
-
-pub type CanonicalizedQueryResponse<'tcx, T> = &'tcx Canonical<'tcx, QueryResponse<'tcx, T>>;
-
-/// Indicates whether or not we were able to prove the query to be
-/// true.
-#[derive(Copy, Clone, Debug, HashStable)]
-pub enum Certainty {
-    /// The query is known to be true, presuming that you apply the
-    /// given `var_values` and the region-constraints are satisfied.
-    Proven,
-
-    /// The query is not known to be true, but also not known to be
-    /// false. The `var_values` represent *either* values that must
-    /// hold in order for the query to be true, or helpful tips that
-    /// *might* make it true. Currently rustc's trait solver cannot
-    /// distinguish the two (e.g., due to our preference for where
-    /// clauses over impls).
-    ///
-    /// After some unifiations and things have been done, it makes
-    /// sense to try and prove again -- of course, at that point, the
-    /// canonical form will be different, making this a distinct
-    /// query.
-    Ambiguous,
-}
-
-impl Certainty {
-    pub fn is_proven(&self) -> bool {
-        match self {
-            Certainty::Proven => true,
-            Certainty::Ambiguous => false,
-        }
-    }
-
-    pub fn is_ambiguous(&self) -> bool {
-        !self.is_proven()
-    }
-}
-
-impl<'tcx, R> QueryResponse<'tcx, R> {
-    pub fn is_proven(&self) -> bool {
-        self.certainty.is_proven()
-    }
-
-    pub fn is_ambiguous(&self) -> bool {
-        !self.is_proven()
-    }
-}
-
-impl<'tcx, R> Canonical<'tcx, QueryResponse<'tcx, R>> {
-    pub fn is_proven(&self) -> bool {
-        self.value.is_proven()
-    }
-
-    pub fn is_ambiguous(&self) -> bool {
-        !self.is_proven()
-    }
-}
-
-impl<'tcx, V> Canonical<'tcx, V> {
-    /// Allows you to map the `value` of a canonical while keeping the
-    /// same set of bound variables.
-    ///
-    /// **WARNING:** This function is very easy to mis-use, hence the
-    /// name!  In particular, the new value `W` must use all **the
-    /// same type/region variables** in **precisely the same order**
-    /// as the original! (The ordering is defined by the
-    /// `TypeFoldable` implementation of the type in question.)
-    ///
-    /// An example of a **correct** use of this:
-    ///
-    /// ```rust,ignore (not real code)
-    /// let a: Canonical<'_, T> = ...;
-    /// let b: Canonical<'_, (T,)> = a.unchecked_map(|v| (v, ));
-    /// ```
-    ///
-    /// An example of an **incorrect** use of this:
-    ///
-    /// ```rust,ignore (not real code)
-    /// let a: Canonical<'tcx, T> = ...;
-    /// let ty: Ty<'tcx> = ...;
-    /// let b: Canonical<'tcx, (T, Ty<'tcx>)> = a.unchecked_map(|v| (v, ty));
-    /// ```
-    pub fn unchecked_map<W>(self, map_op: impl FnOnce(V) -> W) -> Canonical<'tcx, W> {
-        let Canonical { max_universe, variables, value } = self;
-        Canonical { max_universe, variables, value: map_op(value) }
-    }
-}
-
-pub type QueryOutlivesConstraint<'tcx> =
-    ty::Binder<ty::OutlivesPredicate<GenericArg<'tcx>, Region<'tcx>>>;
-
-CloneTypeFoldableAndLiftImpls! {
-    crate::infer::canonical::Certainty,
-    crate::infer::canonical::CanonicalVarInfo,
-    crate::infer::canonical::CanonicalVarKind,
-}
-
-CloneTypeFoldableImpls! {
-    for <'tcx> {
-        crate::infer::canonical::CanonicalVarInfos<'tcx>,
-    }
-}
-
-impl<'tcx> CanonicalVarValues<'tcx> {
-    pub fn len(&self) -> usize {
-        self.var_values.len()
-    }
-
-    /// Makes an identity substitution from this one: each bound var
-    /// is matched to the same bound var, preserving the original kinds.
-    /// For example, if we have:
-    /// `self.var_values == [Type(u32), Lifetime('a), Type(u64)]`
-    /// we'll return a substitution `subst` with:
-    /// `subst.var_values == [Type(^0), Lifetime(^1), Type(^2)]`.
-    pub fn make_identity(&self, tcx: TyCtxt<'tcx>) -> Self {
-        use crate::ty::subst::GenericArgKind;
-
-        CanonicalVarValues {
-            var_values: self
-                .var_values
-                .iter()
-                .zip(0..)
-                .map(|(kind, i)| match kind.unpack() {
-                    GenericArgKind::Type(..) => {
-                        tcx.mk_ty(ty::Bound(ty::INNERMOST, ty::BoundVar::from_u32(i).into())).into()
-                    }
-                    GenericArgKind::Lifetime(..) => tcx
-                        .mk_region(ty::ReLateBound(ty::INNERMOST, ty::BoundRegion::BrAnon(i)))
-                        .into(),
-                    GenericArgKind::Const(ct) => tcx
-                        .mk_const(ty::Const {
-                            ty: ct.ty,
-                            val: ty::ConstKind::Bound(ty::INNERMOST, ty::BoundVar::from_u32(i)),
-                        })
-                        .into(),
-                })
-                .collect(),
-        }
-    }
-}
-
-impl<'a, 'tcx> IntoIterator for &'a CanonicalVarValues<'tcx> {
-    type Item = GenericArg<'tcx>;
-    type IntoIter = ::std::iter::Cloned<::std::slice::Iter<'a, GenericArg<'tcx>>>;
-
-    fn into_iter(self) -> Self::IntoIter {
-        self.var_values.iter().cloned()
-    }
-}
-
-impl<'tcx> Index<BoundVar> for CanonicalVarValues<'tcx> {
-    type Output = GenericArg<'tcx>;
-
-    fn index(&self, value: BoundVar) -> &GenericArg<'tcx> {
-        &self.var_values[value]
-    }
-}
diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs
deleted file mode 100644
index 497d3811f28..00000000000
--- a/src/librustc/infer/mod.rs
+++ /dev/null
@@ -1,32 +0,0 @@
-pub mod canonical;
-pub mod unify_key;
-
-use crate::ty::Region;
-use crate::ty::Ty;
-use rustc_data_structures::sync::Lrc;
-use rustc_hir::def_id::DefId;
-use rustc_span::Span;
-
-/// Requires that `region` must be equal to one of the regions in `choice_regions`.
-/// We often denote this using the syntax:
-///
-/// ```
-/// R0 member of [O1..On]
-/// ```
-#[derive(Debug, Clone, HashStable, TypeFoldable, Lift)]
-pub struct MemberConstraint<'tcx> {
-    /// The `DefId` of the opaque type causing this constraint: used for error reporting.
-    pub opaque_type_def_id: DefId,
-
-    /// The span where the hidden type was instantiated.
-    pub definition_span: Span,
-
-    /// The hidden type in which `member_region` appears: used for error reporting.
-    pub hidden_ty: Ty<'tcx>,
-
-    /// The region `R0`.
-    pub member_region: Region<'tcx>,
-
-    /// The options `O1..On`.
-    pub choice_regions: Lrc<Vec<Region<'tcx>>>,
-}
diff --git a/src/librustc/infer/unify_key.rs b/src/librustc/infer/unify_key.rs
deleted file mode 100644
index e205453a48c..00000000000
--- a/src/librustc/infer/unify_key.rs
+++ /dev/null
@@ -1,227 +0,0 @@
-use crate::ty::{self, FloatVarValue, InferConst, IntVarValue, Ty, TyCtxt};
-use rustc_data_structures::unify::InPlace;
-use rustc_data_structures::unify::{EqUnifyValue, NoError, UnificationTable, UnifyKey, UnifyValue};
-use rustc_span::symbol::Symbol;
-use rustc_span::{Span, DUMMY_SP};
-
-use std::cmp;
-use std::marker::PhantomData;
-
-pub trait ToType {
-    fn to_type<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx>;
-}
-
-/// Raw `TyVid` are used as the unification key for `sub_relations`;
-/// they carry no values.
-impl UnifyKey for ty::TyVid {
-    type Value = ();
-    fn index(&self) -> u32 {
-        self.index
-    }
-    fn from_index(i: u32) -> ty::TyVid {
-        ty::TyVid { index: i }
-    }
-    fn tag() -> &'static str {
-        "TyVid"
-    }
-}
-
-impl UnifyKey for ty::IntVid {
-    type Value = Option<IntVarValue>;
-    fn index(&self) -> u32 {
-        self.index
-    }
-    fn from_index(i: u32) -> ty::IntVid {
-        ty::IntVid { index: i }
-    }
-    fn tag() -> &'static str {
-        "IntVid"
-    }
-}
-
-impl EqUnifyValue for IntVarValue {}
-
-#[derive(PartialEq, Copy, Clone, Debug)]
-pub struct RegionVidKey {
-    /// The minimum region vid in the unification set. This is needed
-    /// to have a canonical name for a type to prevent infinite
-    /// recursion.
-    pub min_vid: ty::RegionVid,
-}
-
-impl UnifyValue for RegionVidKey {
-    type Error = NoError;
-
-    fn unify_values(value1: &Self, value2: &Self) -> Result<Self, NoError> {
-        let min_vid = if value1.min_vid.index() < value2.min_vid.index() {
-            value1.min_vid
-        } else {
-            value2.min_vid
-        };
-
-        Ok(RegionVidKey { min_vid })
-    }
-}
-
-impl UnifyKey for ty::RegionVid {
-    type Value = RegionVidKey;
-    fn index(&self) -> u32 {
-        u32::from(*self)
-    }
-    fn from_index(i: u32) -> ty::RegionVid {
-        ty::RegionVid::from(i)
-    }
-    fn tag() -> &'static str {
-        "RegionVid"
-    }
-}
-
-impl ToType for IntVarValue {
-    fn to_type<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
-        match *self {
-            ty::IntType(i) => tcx.mk_mach_int(i),
-            ty::UintType(i) => tcx.mk_mach_uint(i),
-        }
-    }
-}
-
-// Floating point type keys
-
-impl UnifyKey for ty::FloatVid {
-    type Value = Option<FloatVarValue>;
-    fn index(&self) -> u32 {
-        self.index
-    }
-    fn from_index(i: u32) -> ty::FloatVid {
-        ty::FloatVid { index: i }
-    }
-    fn tag() -> &'static str {
-        "FloatVid"
-    }
-}
-
-impl EqUnifyValue for FloatVarValue {}
-
-impl ToType for FloatVarValue {
-    fn to_type<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
-        tcx.mk_mach_float(self.0)
-    }
-}
-
-// Generic consts.
-
-#[derive(Copy, Clone, Debug)]
-pub struct ConstVariableOrigin {
-    pub kind: ConstVariableOriginKind,
-    pub span: Span,
-}
-
-/// Reasons to create a const inference variable
-#[derive(Copy, Clone, Debug)]
-pub enum ConstVariableOriginKind {
-    MiscVariable,
-    ConstInference,
-    ConstParameterDefinition(Symbol),
-    SubstitutionPlaceholder,
-}
-
-#[derive(Copy, Clone, Debug)]
-pub enum ConstVariableValue<'tcx> {
-    Known { value: &'tcx ty::Const<'tcx> },
-    Unknown { universe: ty::UniverseIndex },
-}
-
-impl<'tcx> ConstVariableValue<'tcx> {
-    /// If this value is known, returns the const it is known to be.
-    /// Otherwise, `None`.
-    pub fn known(&self) -> Option<&'tcx ty::Const<'tcx>> {
-        match *self {
-            ConstVariableValue::Unknown { .. } => None,
-            ConstVariableValue::Known { value } => Some(value),
-        }
-    }
-
-    pub fn is_unknown(&self) -> bool {
-        match *self {
-            ConstVariableValue::Unknown { .. } => true,
-            ConstVariableValue::Known { .. } => false,
-        }
-    }
-}
-
-#[derive(Copy, Clone, Debug)]
-pub struct ConstVarValue<'tcx> {
-    pub origin: ConstVariableOrigin,
-    pub val: ConstVariableValue<'tcx>,
-}
-
-impl<'tcx> UnifyKey for ty::ConstVid<'tcx> {
-    type Value = ConstVarValue<'tcx>;
-    fn index(&self) -> u32 {
-        self.index
-    }
-    fn from_index(i: u32) -> Self {
-        ty::ConstVid { index: i, phantom: PhantomData }
-    }
-    fn tag() -> &'static str {
-        "ConstVid"
-    }
-}
-
-impl<'tcx> UnifyValue for ConstVarValue<'tcx> {
-    type Error = (&'tcx ty::Const<'tcx>, &'tcx ty::Const<'tcx>);
-
-    fn unify_values(value1: &Self, value2: &Self) -> Result<Self, Self::Error> {
-        let val = match (value1.val, value2.val) {
-            (ConstVariableValue::Known { .. }, ConstVariableValue::Known { .. }) => {
-                bug!("equating two const variables, both of which have known values")
-            }
-
-            // If one side is known, prefer that one.
-            (ConstVariableValue::Known { .. }, ConstVariableValue::Unknown { .. }) => {
-                Ok(value1.val)
-            }
-            (ConstVariableValue::Unknown { .. }, ConstVariableValue::Known { .. }) => {
-                Ok(value2.val)
-            }
-
-            // If both sides are *unknown*, it hardly matters, does it?
-            (
-                ConstVariableValue::Unknown { universe: universe1 },
-                ConstVariableValue::Unknown { universe: universe2 },
-            ) => {
-                // If we unify two unbound variables, ?T and ?U, then whatever
-                // value they wind up taking (which must be the same value) must
-                // be nameable by both universes. Therefore, the resulting
-                // universe is the minimum of the two universes, because that is
-                // the one which contains the fewest names in scope.
-                let universe = cmp::min(universe1, universe2);
-                Ok(ConstVariableValue::Unknown { universe })
-            }
-        }?;
-
-        Ok(ConstVarValue {
-            origin: ConstVariableOrigin {
-                kind: ConstVariableOriginKind::ConstInference,
-                span: DUMMY_SP,
-            },
-            val,
-        })
-    }
-}
-
-impl<'tcx> EqUnifyValue for &'tcx ty::Const<'tcx> {}
-
-pub fn replace_if_possible(
-    table: &mut UnificationTable<InPlace<ty::ConstVid<'tcx>>>,
-    c: &'tcx ty::Const<'tcx>,
-) -> &'tcx ty::Const<'tcx> {
-    if let ty::Const { val: ty::ConstKind::Infer(InferConst::Var(vid)), .. } = c {
-        match table.probe_value(*vid).val.known() {
-            Some(c) => c,
-            None => c,
-        }
-    } else {
-        c
-    }
-}
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
deleted file mode 100644
index 055d70effc6..00000000000
--- a/src/librustc/lib.rs
+++ /dev/null
@@ -1,93 +0,0 @@
-//! The "main crate" of the Rust compiler. This crate contains common
-//! type definitions that are used by the other crates in the rustc
-//! "family". Some prominent examples (note that each of these modules
-//! has their own README with further details).
-//!
-//! - **HIR.** The "high-level (H) intermediate representation (IR)" is
-//!   defined in the `hir` module.
-//! - **MIR.** The "mid-level (M) intermediate representation (IR)" is
-//!   defined in the `mir` module. This module contains only the
-//!   *definition* of the MIR; the passes that transform and operate
-//!   on MIR are found in `librustc_mir` crate.
-//! - **Types.** The internal representation of types used in rustc is
-//!   defined in the `ty` module. This includes the **type context**
-//!   (or `tcx`), which is the central context during most of
-//!   compilation, containing the interners and other things.
-//!
-//! For more information about how rustc works, see the [rustc guide].
-//!
-//! [rustc guide]: https://rust-lang.github.io/rustc-guide/
-//!
-//! # Note
-//!
-//! This API is completely unstable and subject to change.
-
-#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
-#![feature(bool_to_option)]
-#![feature(box_patterns)]
-#![feature(box_syntax)]
-#![feature(const_transmute)]
-#![feature(core_intrinsics)]
-#![feature(drain_filter)]
-#![feature(never_type)]
-#![feature(exhaustive_patterns)]
-#![feature(marker_trait_attr)]
-#![feature(extern_types)]
-#![feature(nll)]
-#![feature(option_expect_none)]
-#![feature(range_is_empty)]
-#![feature(specialization)]
-#![feature(trusted_len)]
-#![feature(vec_remove_item)]
-#![feature(stmt_expr_attributes)]
-#![feature(test)]
-#![feature(in_band_lifetimes)]
-#![feature(crate_visibility_modifier)]
-#![feature(associated_type_bounds)]
-#![feature(rustc_attrs)]
-#![feature(hash_raw_entry)]
-#![feature(int_error_matching)]
-#![recursion_limit = "512"]
-
-#[macro_use]
-extern crate bitflags;
-#[macro_use]
-extern crate scoped_tls;
-#[macro_use]
-extern crate rustc_macros;
-#[macro_use]
-extern crate rustc_data_structures;
-#[macro_use]
-extern crate log;
-#[macro_use]
-extern crate smallvec;
-
-#[cfg(test)]
-mod tests;
-
-#[macro_use]
-mod macros;
-
-#[macro_use]
-pub mod query;
-
-#[macro_use]
-pub mod arena;
-pub mod dep_graph;
-pub mod hir;
-pub mod ich;
-pub mod infer;
-pub mod lint;
-pub mod middle;
-pub mod mir;
-pub use rustc_session as session;
-pub mod traits;
-pub mod ty;
-
-pub mod util {
-    pub mod bug;
-    pub mod common;
-}
-
-// Allows macros to refer to this crate as `::rustc`
-extern crate self as rustc;
diff --git a/src/librustc/lint.rs b/src/librustc/lint.rs
deleted file mode 100644
index 004835b230a..00000000000
--- a/src/librustc/lint.rs
+++ /dev/null
@@ -1,401 +0,0 @@
-use std::cmp;
-
-use crate::ich::StableHashingContext;
-use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
-use rustc_errors::{pluralize, Applicability, DiagnosticBuilder, DiagnosticId};
-use rustc_hir::HirId;
-pub use rustc_session::lint::{builtin, Level, Lint, LintId, LintPass};
-use rustc_session::{DiagnosticMessageId, Session};
-use rustc_span::hygiene::MacroKind;
-use rustc_span::source_map::{DesugaringKind, ExpnKind, MultiSpan};
-use rustc_span::{Span, Symbol};
-
-/// How a lint level was set.
-#[derive(Clone, Copy, PartialEq, Eq, HashStable)]
-pub enum LintSource {
-    /// Lint is at the default level as declared
-    /// in rustc or a plugin.
-    Default,
-
-    /// Lint level was set by an attribute.
-    Node(Symbol, Span, Option<Symbol> /* RFC 2383 reason */),
-
-    /// Lint level was set by a command-line flag.
-    CommandLine(Symbol),
-}
-
-pub type LevelSource = (Level, LintSource);
-
-pub struct LintLevelSets {
-    pub list: Vec<LintSet>,
-    pub lint_cap: Level,
-}
-
-pub enum LintSet {
-    CommandLine {
-        // -A,-W,-D flags, a `Symbol` for the flag itself and `Level` for which
-        // flag.
-        specs: FxHashMap<LintId, LevelSource>,
-    },
-
-    Node {
-        specs: FxHashMap<LintId, LevelSource>,
-        parent: u32,
-    },
-}
-
-impl LintLevelSets {
-    pub fn new() -> Self {
-        LintLevelSets { list: Vec::new(), lint_cap: Level::Forbid }
-    }
-
-    pub fn get_lint_level(
-        &self,
-        lint: &'static Lint,
-        idx: u32,
-        aux: Option<&FxHashMap<LintId, LevelSource>>,
-        sess: &Session,
-    ) -> LevelSource {
-        let (level, mut src) = self.get_lint_id_level(LintId::of(lint), idx, aux);
-
-        // If `level` is none then we actually assume the default level for this
-        // lint.
-        let mut level = level.unwrap_or_else(|| lint.default_level(sess.edition()));
-
-        // If we're about to issue a warning, check at the last minute for any
-        // directives against the warnings "lint". If, for example, there's an
-        // `allow(warnings)` in scope then we want to respect that instead.
-        if level == Level::Warn {
-            let (warnings_level, warnings_src) =
-                self.get_lint_id_level(LintId::of(builtin::WARNINGS), idx, aux);
-            if let Some(configured_warning_level) = warnings_level {
-                if configured_warning_level != Level::Warn {
-                    level = configured_warning_level;
-                    src = warnings_src;
-                }
-            }
-        }
-
-        // Ensure that we never exceed the `--cap-lints` argument.
-        level = cmp::min(level, self.lint_cap);
-
-        if let Some(driver_level) = sess.driver_lint_caps.get(&LintId::of(lint)) {
-            // Ensure that we never exceed driver level.
-            level = cmp::min(*driver_level, level);
-        }
-
-        return (level, src);
-    }
-
-    pub fn get_lint_id_level(
-        &self,
-        id: LintId,
-        mut idx: u32,
-        aux: Option<&FxHashMap<LintId, LevelSource>>,
-    ) -> (Option<Level>, LintSource) {
-        if let Some(specs) = aux {
-            if let Some(&(level, src)) = specs.get(&id) {
-                return (Some(level), src);
-            }
-        }
-        loop {
-            match self.list[idx as usize] {
-                LintSet::CommandLine { ref specs } => {
-                    if let Some(&(level, src)) = specs.get(&id) {
-                        return (Some(level), src);
-                    }
-                    return (None, LintSource::Default);
-                }
-                LintSet::Node { ref specs, parent } => {
-                    if let Some(&(level, src)) = specs.get(&id) {
-                        return (Some(level), src);
-                    }
-                    idx = parent;
-                }
-            }
-        }
-    }
-}
-
-pub struct LintLevelMap {
-    pub sets: LintLevelSets,
-    pub id_to_set: FxHashMap<HirId, u32>,
-}
-
-impl LintLevelMap {
-    /// If the `id` was previously registered with `register_id` when building
-    /// this `LintLevelMap` this returns the corresponding lint level and source
-    /// of the lint level for the lint provided.
-    ///
-    /// If the `id` was not previously registered, returns `None`. If `None` is
-    /// returned then the parent of `id` should be acquired and this function
-    /// should be called again.
-    pub fn level_and_source(
-        &self,
-        lint: &'static Lint,
-        id: HirId,
-        session: &Session,
-    ) -> Option<LevelSource> {
-        self.id_to_set.get(&id).map(|idx| self.sets.get_lint_level(lint, *idx, None, session))
-    }
-}
-
-impl<'a> HashStable<StableHashingContext<'a>> for LintLevelMap {
-    #[inline]
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        let LintLevelMap { ref sets, ref id_to_set } = *self;
-
-        id_to_set.hash_stable(hcx, hasher);
-
-        let LintLevelSets { ref list, lint_cap } = *sets;
-
-        lint_cap.hash_stable(hcx, hasher);
-
-        hcx.while_hashing_spans(true, |hcx| {
-            list.len().hash_stable(hcx, hasher);
-
-            // We are working under the assumption here that the list of
-            // lint-sets is built in a deterministic order.
-            for lint_set in list {
-                ::std::mem::discriminant(lint_set).hash_stable(hcx, hasher);
-
-                match *lint_set {
-                    LintSet::CommandLine { ref specs } => {
-                        specs.hash_stable(hcx, hasher);
-                    }
-                    LintSet::Node { ref specs, parent } => {
-                        specs.hash_stable(hcx, hasher);
-                        parent.hash_stable(hcx, hasher);
-                    }
-                }
-            }
-        })
-    }
-}
-
-pub struct LintDiagnosticBuilder<'a>(DiagnosticBuilder<'a>);
-
-impl<'a> LintDiagnosticBuilder<'a> {
-    /// Return the inner DiagnosticBuilder, first setting the primary message to `msg`.
-    pub fn build(mut self, msg: &str) -> DiagnosticBuilder<'a> {
-        self.0.set_primary_message(msg);
-        self.0
-    }
-
-    /// Create a LintDiagnosticBuilder from some existing DiagnosticBuilder.
-    pub fn new(err: DiagnosticBuilder<'a>) -> LintDiagnosticBuilder<'a> {
-        LintDiagnosticBuilder(err)
-    }
-}
-
-pub fn struct_lint_level<'s, 'd>(
-    sess: &'s Session,
-    lint: &'static Lint,
-    level: Level,
-    src: LintSource,
-    span: Option<MultiSpan>,
-    decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a>) + 'd,
-) {
-    // Avoid codegen bloat from monomorphization by immediately doing dyn dispatch of `decorate` to
-    // the "real" work.
-    fn struct_lint_level_impl(
-        sess: &'s Session,
-        lint: &'static Lint,
-        level: Level,
-        src: LintSource,
-        span: Option<MultiSpan>,
-        decorate: Box<dyn for<'b> FnOnce(LintDiagnosticBuilder<'b>) + 'd>,
-    ) {
-        let mut err = match (level, span) {
-            (Level::Allow, _) => {
-                return;
-            }
-            (Level::Warn, Some(span)) => sess.struct_span_warn(span, ""),
-            (Level::Warn, None) => sess.struct_warn(""),
-            (Level::Deny, Some(span)) | (Level::Forbid, Some(span)) => {
-                sess.struct_span_err(span, "")
-            }
-            (Level::Deny, None) | (Level::Forbid, None) => sess.struct_err(""),
-        };
-
-        // Check for future incompatibility lints and issue a stronger warning.
-        let lint_id = LintId::of(lint);
-        let future_incompatible = lint.future_incompatible;
-
-        // If this code originates in a foreign macro, aka something that this crate
-        // did not itself author, then it's likely that there's nothing this crate
-        // can do about it. We probably want to skip the lint entirely.
-        if err.span.primary_spans().iter().any(|s| in_external_macro(sess, *s)) {
-            // Any suggestions made here are likely to be incorrect, so anything we
-            // emit shouldn't be automatically fixed by rustfix.
-            err.allow_suggestions(false);
-
-            // If this is a future incompatible lint it'll become a hard error, so
-            // we have to emit *something*. Also allow lints to whitelist themselves
-            // on a case-by-case basis for emission in a foreign macro.
-            if future_incompatible.is_none() && !lint.report_in_external_macro {
-                err.cancel();
-                // Don't continue further, since we don't want to have
-                // `diag_span_note_once` called for a diagnostic that isn't emitted.
-                return;
-            }
-        }
-
-        let name = lint.name_lower();
-        match src {
-            LintSource::Default => {
-                sess.diag_note_once(
-                    &mut err,
-                    DiagnosticMessageId::from(lint),
-                    &format!("`#[{}({})]` on by default", level.as_str(), name),
-                );
-            }
-            LintSource::CommandLine(lint_flag_val) => {
-                let flag = match level {
-                    Level::Warn => "-W",
-                    Level::Deny => "-D",
-                    Level::Forbid => "-F",
-                    Level::Allow => panic!(),
-                };
-                let hyphen_case_lint_name = name.replace("_", "-");
-                if lint_flag_val.as_str() == name {
-                    sess.diag_note_once(
-                        &mut err,
-                        DiagnosticMessageId::from(lint),
-                        &format!(
-                            "requested on the command line with `{} {}`",
-                            flag, hyphen_case_lint_name
-                        ),
-                    );
-                } else {
-                    let hyphen_case_flag_val = lint_flag_val.as_str().replace("_", "-");
-                    sess.diag_note_once(
-                        &mut err,
-                        DiagnosticMessageId::from(lint),
-                        &format!(
-                            "`{} {}` implied by `{} {}`",
-                            flag, hyphen_case_lint_name, flag, hyphen_case_flag_val
-                        ),
-                    );
-                }
-            }
-            LintSource::Node(lint_attr_name, src, reason) => {
-                if let Some(rationale) = reason {
-                    err.note(&rationale.as_str());
-                }
-                sess.diag_span_note_once(
-                    &mut err,
-                    DiagnosticMessageId::from(lint),
-                    src,
-                    "the lint level is defined here",
-                );
-                if lint_attr_name.as_str() != name {
-                    let level_str = level.as_str();
-                    sess.diag_note_once(
-                        &mut err,
-                        DiagnosticMessageId::from(lint),
-                        &format!(
-                            "`#[{}({})]` implied by `#[{}({})]`",
-                            level_str, name, level_str, lint_attr_name
-                        ),
-                    );
-                }
-            }
-        }
-
-        err.code(DiagnosticId::Lint(name));
-
-        if let Some(future_incompatible) = future_incompatible {
-            const STANDARD_MESSAGE: &str = "this was previously accepted by the compiler but is being phased out; \
-                 it will become a hard error";
-
-            let explanation = if lint_id == LintId::of(builtin::UNSTABLE_NAME_COLLISIONS) {
-                "once this method is added to the standard library, \
-                 the ambiguity may cause an error or change in behavior!"
-                    .to_owned()
-            } else if lint_id == LintId::of(builtin::MUTABLE_BORROW_RESERVATION_CONFLICT) {
-                "this borrowing pattern was not meant to be accepted, \
-                 and may become a hard error in the future"
-                    .to_owned()
-            } else if let Some(edition) = future_incompatible.edition {
-                format!("{} in the {} edition!", STANDARD_MESSAGE, edition)
-            } else {
-                format!("{} in a future release!", STANDARD_MESSAGE)
-            };
-            let citation = format!("for more information, see {}", future_incompatible.reference);
-            err.warn(&explanation);
-            err.note(&citation);
-        }
-
-        // Finally, run `decorate`. This function is also responsible for emitting the diagnostic.
-        decorate(LintDiagnosticBuilder::new(err));
-    }
-    struct_lint_level_impl(sess, lint, level, src, span, Box::new(decorate))
-}
-
-/// Returns whether `span` originates in a foreign crate's external macro.
-///
-/// This is used to test whether a lint should not even begin to figure out whether it should
-/// be reported on the current node.
-pub fn in_external_macro(sess: &Session, span: Span) -> bool {
-    let expn_data = span.ctxt().outer_expn_data();
-    match expn_data.kind {
-        ExpnKind::Root | ExpnKind::Desugaring(DesugaringKind::ForLoop) => false,
-        ExpnKind::AstPass(_) | ExpnKind::Desugaring(_) => true, // well, it's "external"
-        ExpnKind::Macro(MacroKind::Bang, _) => {
-            if expn_data.def_site.is_dummy() {
-                // Dummy span for the `def_site` means it's an external macro.
-                return true;
-            }
-            match sess.source_map().span_to_snippet(expn_data.def_site) {
-                Ok(code) => !code.starts_with("macro_rules"),
-                // No snippet means external macro or compiler-builtin expansion.
-                Err(_) => true,
-            }
-        }
-        ExpnKind::Macro(..) => true, // definitely a plugin
-    }
-}
-
-pub fn add_elided_lifetime_in_path_suggestion(
-    sess: &Session,
-    db: &mut DiagnosticBuilder<'_>,
-    n: usize,
-    path_span: Span,
-    incl_angl_brckt: bool,
-    insertion_span: Span,
-    anon_lts: String,
-) {
-    let (replace_span, suggestion) = if incl_angl_brckt {
-        (insertion_span, anon_lts)
-    } else {
-        // When possible, prefer a suggestion that replaces the whole
-        // `Path<T>` expression with `Path<'_, T>`, rather than inserting `'_, `
-        // at a point (which makes for an ugly/confusing label)
-        if let Ok(snippet) = sess.source_map().span_to_snippet(path_span) {
-            // But our spans can get out of whack due to macros; if the place we think
-            // we want to insert `'_` isn't even within the path expression's span, we
-            // should bail out of making any suggestion rather than panicking on a
-            // subtract-with-overflow or string-slice-out-out-bounds (!)
-            // FIXME: can we do better?
-            if insertion_span.lo().0 < path_span.lo().0 {
-                return;
-            }
-            let insertion_index = (insertion_span.lo().0 - path_span.lo().0) as usize;
-            if insertion_index > snippet.len() {
-                return;
-            }
-            let (before, after) = snippet.split_at(insertion_index);
-            (path_span, format!("{}{}{}", before, anon_lts, after))
-        } else {
-            (insertion_span, anon_lts)
-        }
-    };
-    db.span_suggestion(
-        replace_span,
-        &format!("indicate the anonymous lifetime{}", pluralize!(n)),
-        suggestion,
-        Applicability::MachineApplicable,
-    );
-}
diff --git a/src/librustc/macros.rs b/src/librustc/macros.rs
deleted file mode 100644
index 88ddd96eec8..00000000000
--- a/src/librustc/macros.rs
+++ /dev/null
@@ -1,216 +0,0 @@
-#[macro_export]
-macro_rules! bug {
-    () => ( bug!("impossible case reached") );
-    ($($message:tt)*) => ({
-        $crate::util::bug::bug_fmt(file!(), line!(), format_args!($($message)*))
-    })
-}
-
-#[macro_export]
-macro_rules! span_bug {
-    ($span:expr, $($message:tt)*) => ({
-        $crate::util::bug::span_bug_fmt(file!(), line!(), $span, format_args!($($message)*))
-    })
-}
-
-///////////////////////////////////////////////////////////////////////////
-// Lift and TypeFoldable macros
-//
-// When possible, use one of these (relatively) convenient macros to write
-// the impls for you.
-
-#[macro_export]
-macro_rules! CloneLiftImpls {
-    (for <$tcx:lifetime> { $($ty:ty,)+ }) => {
-        $(
-            impl<$tcx> $crate::ty::Lift<$tcx> for $ty {
-                type Lifted = Self;
-                fn lift_to_tcx(&self, _: $crate::ty::TyCtxt<$tcx>) -> Option<Self> {
-                    Some(Clone::clone(self))
-                }
-            }
-        )+
-    };
-
-    ($($ty:ty,)+) => {
-        CloneLiftImpls! {
-            for <'tcx> {
-                $($ty,)+
-            }
-        }
-    };
-}
-
-/// Used for types that are `Copy` and which **do not care arena
-/// allocated data** (i.e., don't need to be folded).
-#[macro_export]
-macro_rules! CloneTypeFoldableImpls {
-    (for <$tcx:lifetime> { $($ty:ty,)+ }) => {
-        $(
-            impl<$tcx> $crate::ty::fold::TypeFoldable<$tcx> for $ty {
-                fn super_fold_with<F: $crate::ty::fold::TypeFolder<$tcx>>(
-                    &self,
-                    _: &mut F
-                ) -> $ty {
-                    Clone::clone(self)
-                }
-
-                fn super_visit_with<F: $crate::ty::fold::TypeVisitor<$tcx>>(
-                    &self,
-                    _: &mut F)
-                    -> bool
-                {
-                    false
-                }
-            }
-        )+
-    };
-
-    ($($ty:ty,)+) => {
-        CloneTypeFoldableImpls! {
-            for <'tcx> {
-                $($ty,)+
-            }
-        }
-    };
-}
-
-#[macro_export]
-macro_rules! CloneTypeFoldableAndLiftImpls {
-    ($($t:tt)*) => {
-        CloneTypeFoldableImpls! { $($t)* }
-        CloneLiftImpls! { $($t)* }
-    }
-}
-
-#[macro_export]
-macro_rules! EnumTypeFoldableImpl {
-    (impl<$($p:tt),*> TypeFoldable<$tcx:tt> for $s:path {
-        $($variants:tt)*
-    } $(where $($wc:tt)*)*) => {
-        impl<$($p),*> $crate::ty::fold::TypeFoldable<$tcx> for $s
-            $(where $($wc)*)*
-        {
-            fn super_fold_with<V: $crate::ty::fold::TypeFolder<$tcx>>(
-                &self,
-                folder: &mut V,
-            ) -> Self {
-                EnumTypeFoldableImpl!(@FoldVariants(self, folder) input($($variants)*) output())
-            }
-
-            fn super_visit_with<V: $crate::ty::fold::TypeVisitor<$tcx>>(
-                &self,
-                visitor: &mut V,
-            ) -> bool {
-                EnumTypeFoldableImpl!(@VisitVariants(self, visitor) input($($variants)*) output())
-            }
-        }
-    };
-
-    (@FoldVariants($this:expr, $folder:expr) input() output($($output:tt)*)) => {
-        match $this {
-            $($output)*
-        }
-    };
-
-    (@FoldVariants($this:expr, $folder:expr)
-     input( ($variant:path) ( $($variant_arg:ident),* ) , $($input:tt)*)
-     output( $($output:tt)*) ) => {
-        EnumTypeFoldableImpl!(
-            @FoldVariants($this, $folder)
-                input($($input)*)
-                output(
-                    $variant ( $($variant_arg),* ) => {
-                        $variant (
-                            $($crate::ty::fold::TypeFoldable::fold_with($variant_arg, $folder)),*
-                        )
-                    }
-                    $($output)*
-                )
-        )
-    };
-
-    (@FoldVariants($this:expr, $folder:expr)
-     input( ($variant:path) { $($variant_arg:ident),* $(,)? } , $($input:tt)*)
-     output( $($output:tt)*) ) => {
-        EnumTypeFoldableImpl!(
-            @FoldVariants($this, $folder)
-                input($($input)*)
-                output(
-                    $variant { $($variant_arg),* } => {
-                        $variant {
-                            $($variant_arg: $crate::ty::fold::TypeFoldable::fold_with(
-                                $variant_arg, $folder
-                            )),* }
-                    }
-                    $($output)*
-                )
-        )
-    };
-
-    (@FoldVariants($this:expr, $folder:expr)
-     input( ($variant:path), $($input:tt)*)
-     output( $($output:tt)*) ) => {
-        EnumTypeFoldableImpl!(
-            @FoldVariants($this, $folder)
-                input($($input)*)
-                output(
-                    $variant => { $variant }
-                    $($output)*
-                )
-        )
-    };
-
-    (@VisitVariants($this:expr, $visitor:expr) input() output($($output:tt)*)) => {
-        match $this {
-            $($output)*
-        }
-    };
-
-    (@VisitVariants($this:expr, $visitor:expr)
-     input( ($variant:path) ( $($variant_arg:ident),* ) , $($input:tt)*)
-     output( $($output:tt)*) ) => {
-        EnumTypeFoldableImpl!(
-            @VisitVariants($this, $visitor)
-                input($($input)*)
-                output(
-                    $variant ( $($variant_arg),* ) => {
-                        false $(|| $crate::ty::fold::TypeFoldable::visit_with(
-                            $variant_arg, $visitor
-                        ))*
-                    }
-                    $($output)*
-                )
-        )
-    };
-
-    (@VisitVariants($this:expr, $visitor:expr)
-     input( ($variant:path) { $($variant_arg:ident),* $(,)? } , $($input:tt)*)
-     output( $($output:tt)*) ) => {
-        EnumTypeFoldableImpl!(
-            @VisitVariants($this, $visitor)
-                input($($input)*)
-                output(
-                    $variant { $($variant_arg),* } => {
-                        false $(|| $crate::ty::fold::TypeFoldable::visit_with(
-                            $variant_arg, $visitor
-                        ))*
-                    }
-                    $($output)*
-                )
-        )
-    };
-
-    (@VisitVariants($this:expr, $visitor:expr)
-     input( ($variant:path), $($input:tt)*)
-     output( $($output:tt)*) ) => {
-        EnumTypeFoldableImpl!(
-            @VisitVariants($this, $visitor)
-                input($($input)*)
-                output(
-                    $variant => { false }
-                    $($output)*
-                )
-        )
-    };
-}
diff --git a/src/librustc/middle/codegen_fn_attrs.rs b/src/librustc/middle/codegen_fn_attrs.rs
deleted file mode 100644
index 82adcfddc28..00000000000
--- a/src/librustc/middle/codegen_fn_attrs.rs
+++ /dev/null
@@ -1,124 +0,0 @@
-use crate::mir::mono::Linkage;
-use rustc_attr::{InlineAttr, OptimizeAttr};
-use rustc_span::symbol::Symbol;
-
-#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
-pub struct CodegenFnAttrs {
-    pub flags: CodegenFnAttrFlags,
-    /// Parsed representation of the `#[inline]` attribute
-    pub inline: InlineAttr,
-    /// Parsed representation of the `#[optimize]` attribute
-    pub optimize: OptimizeAttr,
-    /// The `#[export_name = "..."]` attribute, indicating a custom symbol a
-    /// function should be exported under
-    pub export_name: Option<Symbol>,
-    /// The `#[link_name = "..."]` attribute, indicating a custom symbol an
-    /// imported function should be imported as. Note that `export_name`
-    /// probably isn't set when this is set, this is for foreign items while
-    /// `#[export_name]` is for Rust-defined functions.
-    pub link_name: Option<Symbol>,
-    /// The `#[link_ordinal = "..."]` attribute, indicating an ordinal an
-    /// imported function has in the dynamic library. Note that this must not
-    /// be set when `link_name` is set. This is for foreign items with the
-    /// "raw-dylib" kind.
-    pub link_ordinal: Option<usize>,
-    /// The `#[target_feature(enable = "...")]` attribute and the enabled
-    /// features (only enabled features are supported right now).
-    pub target_features: Vec<Symbol>,
-    /// The `#[linkage = "..."]` attribute and the value we found.
-    pub linkage: Option<Linkage>,
-    /// The `#[link_section = "..."]` attribute, or what executable section this
-    /// should be placed in.
-    pub link_section: Option<Symbol>,
-}
-
-bitflags! {
-    #[derive(RustcEncodable, RustcDecodable, HashStable)]
-    pub struct CodegenFnAttrFlags: u32 {
-        /// `#[cold]`: a hint to LLVM that this function, when called, is never on
-        /// the hot path.
-        const COLD                      = 1 << 0;
-        /// `#[rustc_allocator]`: a hint to LLVM that the pointer returned from this
-        /// function is never null.
-        const ALLOCATOR                 = 1 << 1;
-        /// `#[unwind]`: an indicator that this function may unwind despite what
-        /// its ABI signature may otherwise imply.
-        const UNWIND                    = 1 << 2;
-        /// `#[rust_allocator_nounwind]`, an indicator that an imported FFI
-        /// function will never unwind. Probably obsolete by recent changes with
-        /// #[unwind], but hasn't been removed/migrated yet
-        const RUSTC_ALLOCATOR_NOUNWIND  = 1 << 3;
-        /// `#[naked]`: an indicator to LLVM that no function prologue/epilogue
-        /// should be generated.
-        const NAKED                     = 1 << 4;
-        /// `#[no_mangle]`: an indicator that the function's name should be the same
-        /// as its symbol.
-        const NO_MANGLE                 = 1 << 5;
-        /// `#[rustc_std_internal_symbol]`: an indicator that this symbol is a
-        /// "weird symbol" for the standard library in that it has slightly
-        /// different linkage, visibility, and reachability rules.
-        const RUSTC_STD_INTERNAL_SYMBOL = 1 << 6;
-        /// `#[no_debug]`: an indicator that no debugging information should be
-        /// generated for this function by LLVM.
-        const NO_DEBUG                  = 1 << 7;
-        /// `#[thread_local]`: indicates a static is actually a thread local
-        /// piece of memory
-        const THREAD_LOCAL              = 1 << 8;
-        /// `#[used]`: indicates that LLVM can't eliminate this function (but the
-        /// linker can!).
-        const USED                      = 1 << 9;
-        /// `#[ffi_returns_twice]`, indicates that an extern function can return
-        /// multiple times
-        const FFI_RETURNS_TWICE         = 1 << 10;
-        /// `#[track_caller]`: allow access to the caller location
-        const TRACK_CALLER              = 1 << 11;
-        /// `#[no_sanitize(address)]`: disables address sanitizer instrumentation
-        const NO_SANITIZE_ADDRESS = 1 << 12;
-        /// `#[no_sanitize(memory)]`: disables memory sanitizer instrumentation
-        const NO_SANITIZE_MEMORY  = 1 << 13;
-        /// `#[no_sanitize(thread)]`: disables thread sanitizer instrumentation
-        const NO_SANITIZE_THREAD  = 1 << 14;
-        /// All `#[no_sanitize(...)]` attributes.
-        const NO_SANITIZE_ANY = Self::NO_SANITIZE_ADDRESS.bits | Self::NO_SANITIZE_MEMORY.bits | Self::NO_SANITIZE_THREAD.bits;
-    }
-}
-
-impl CodegenFnAttrs {
-    pub fn new() -> CodegenFnAttrs {
-        CodegenFnAttrs {
-            flags: CodegenFnAttrFlags::empty(),
-            inline: InlineAttr::None,
-            optimize: OptimizeAttr::None,
-            export_name: None,
-            link_name: None,
-            link_ordinal: None,
-            target_features: vec![],
-            linkage: None,
-            link_section: None,
-        }
-    }
-
-    /// Returns `true` if `#[inline]` or `#[inline(always)]` is present.
-    pub fn requests_inline(&self) -> bool {
-        match self.inline {
-            InlineAttr::Hint | InlineAttr::Always => true,
-            InlineAttr::None | InlineAttr::Never => false,
-        }
-    }
-
-    /// Returns `true` if it looks like this symbol needs to be exported, for example:
-    ///
-    /// * `#[no_mangle]` is present
-    /// * `#[export_name(...)]` is present
-    /// * `#[linkage]` is present
-    pub fn contains_extern_indicator(&self) -> bool {
-        self.flags.contains(CodegenFnAttrFlags::NO_MANGLE)
-            || self.export_name.is_some()
-            || match self.linkage {
-                // These are private, so make sure we don't try to consider
-                // them external.
-                None | Some(Linkage::Internal) | Some(Linkage::Private) => false,
-                Some(_) => true,
-            }
-    }
-}
diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs
deleted file mode 100644
index 0e7ff3a3393..00000000000
--- a/src/librustc/middle/cstore.rs
+++ /dev/null
@@ -1,265 +0,0 @@
-//! the rustc crate store interface. This also includes types that
-//! are *mostly* used as a part of that interface, but these should
-//! probably get a better home if someone can find one.
-
-use crate::hir::map as hir_map;
-use crate::hir::map::definitions::{DefKey, DefPathTable};
-use crate::session::search_paths::PathKind;
-use crate::session::CrateDisambiguator;
-use crate::ty::TyCtxt;
-
-use rustc_data_structures::svh::Svh;
-use rustc_data_structures::sync::{self, MetadataRef};
-use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
-use rustc_macros::HashStable;
-use rustc_span::symbol::Symbol;
-use rustc_span::Span;
-use rustc_target::spec::Target;
-use std::any::Any;
-use std::path::{Path, PathBuf};
-use syntax::ast;
-use syntax::expand::allocator::AllocatorKind;
-
-pub use self::NativeLibraryKind::*;
-pub use rustc_session::utils::NativeLibraryKind;
-
-// lonely orphan structs and enums looking for a better home
-
-/// Where a crate came from on the local filesystem. One of these three options
-/// must be non-None.
-#[derive(PartialEq, Clone, Debug, HashStable, RustcEncodable, RustcDecodable)]
-pub struct CrateSource {
-    pub dylib: Option<(PathBuf, PathKind)>,
-    pub rlib: Option<(PathBuf, PathKind)>,
-    pub rmeta: Option<(PathBuf, PathKind)>,
-}
-
-impl CrateSource {
-    pub fn paths(&self) -> impl Iterator<Item = &PathBuf> {
-        self.dylib.iter().chain(self.rlib.iter()).chain(self.rmeta.iter()).map(|p| &p.0)
-    }
-}
-
-#[derive(
-    RustcEncodable,
-    RustcDecodable,
-    Copy,
-    Clone,
-    Ord,
-    PartialOrd,
-    Eq,
-    PartialEq,
-    Debug,
-    HashStable
-)]
-pub enum DepKind {
-    /// A dependency that is only used for its macros, none of which are visible from other crates.
-    /// These are included in the metadata only as placeholders and are ignored when decoding.
-    UnexportedMacrosOnly,
-    /// A dependency that is only used for its macros.
-    MacrosOnly,
-    /// A dependency that is always injected into the dependency list and so
-    /// doesn't need to be linked to an rlib, e.g., the injected allocator.
-    Implicit,
-    /// A dependency that is required by an rlib version of this crate.
-    /// Ordinary `extern crate`s result in `Explicit` dependencies.
-    Explicit,
-}
-
-impl DepKind {
-    pub fn macros_only(self) -> bool {
-        match self {
-            DepKind::UnexportedMacrosOnly | DepKind::MacrosOnly => true,
-            DepKind::Implicit | DepKind::Explicit => false,
-        }
-    }
-}
-
-#[derive(PartialEq, Clone, Debug, RustcEncodable, RustcDecodable)]
-pub enum LibSource {
-    Some(PathBuf),
-    MetadataOnly,
-    None,
-}
-
-impl LibSource {
-    pub fn is_some(&self) -> bool {
-        if let LibSource::Some(_) = *self { true } else { false }
-    }
-
-    pub fn option(&self) -> Option<PathBuf> {
-        match *self {
-            LibSource::Some(ref p) => Some(p.clone()),
-            LibSource::MetadataOnly | LibSource::None => None,
-        }
-    }
-}
-
-#[derive(Copy, Debug, PartialEq, Clone, RustcEncodable, RustcDecodable, HashStable)]
-pub enum LinkagePreference {
-    RequireDynamic,
-    RequireStatic,
-}
-
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
-pub struct NativeLibrary {
-    pub kind: NativeLibraryKind,
-    pub name: Option<Symbol>,
-    pub cfg: Option<ast::MetaItem>,
-    pub foreign_module: Option<DefId>,
-    pub wasm_import_module: Option<Symbol>,
-}
-
-#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
-pub struct ForeignModule {
-    pub foreign_items: Vec<DefId>,
-    pub def_id: DefId,
-}
-
-#[derive(Copy, Clone, Debug, HashStable)]
-pub struct ExternCrate {
-    pub src: ExternCrateSource,
-
-    /// span of the extern crate that caused this to be loaded
-    pub span: Span,
-
-    /// Number of links to reach the extern;
-    /// used to select the extern with the shortest path
-    pub path_len: usize,
-
-    /// Crate that depends on this crate
-    pub dependency_of: CrateNum,
-}
-
-impl ExternCrate {
-    /// If true, then this crate is the crate named by the extern
-    /// crate referenced above. If false, then this crate is a dep
-    /// of the crate.
-    pub fn is_direct(&self) -> bool {
-        self.dependency_of == LOCAL_CRATE
-    }
-
-    pub fn rank(&self) -> impl PartialOrd {
-        // Prefer:
-        // - direct extern crate to indirect
-        // - shorter paths to longer
-        (self.is_direct(), !self.path_len)
-    }
-}
-
-#[derive(Copy, Clone, Debug, HashStable)]
-pub enum ExternCrateSource {
-    /// Crate is loaded by `extern crate`.
-    Extern(
-        /// def_id of the item in the current crate that caused
-        /// this crate to be loaded; note that there could be multiple
-        /// such ids
-        DefId,
-    ),
-    /// Crate is implicitly loaded by a path resolving through extern prelude.
-    Path,
-}
-
-#[derive(RustcEncodable, RustcDecodable)]
-pub struct EncodedMetadata {
-    pub raw_data: Vec<u8>,
-}
-
-impl EncodedMetadata {
-    pub fn new() -> EncodedMetadata {
-        EncodedMetadata { raw_data: Vec::new() }
-    }
-}
-
-/// The backend's way to give the crate store access to the metadata in a library.
-/// Note that it returns the raw metadata bytes stored in the library file, whether
-/// it is compressed, uncompressed, some weird mix, etc.
-/// rmeta files are backend independent and not handled here.
-///
-/// At the time of this writing, there is only one backend and one way to store
-/// metadata in library -- this trait just serves to decouple rustc_metadata from
-/// the archive reader, which depends on LLVM.
-pub trait MetadataLoader {
-    fn get_rlib_metadata(&self, target: &Target, filename: &Path) -> Result<MetadataRef, String>;
-    fn get_dylib_metadata(&self, target: &Target, filename: &Path) -> 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
-/// functionality should be driven through queries instead!
-///
-/// If you find a method on this trait named `{name}_untracked` it signifies
-/// that it's *not* tracked for dependency information throughout compilation
-/// (it'd break incremental compilation) and should only be called pre-HIR (e.g.
-/// during resolve)
-pub trait CrateStore {
-    fn as_any(&self) -> &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) -> &DefPathTable;
-
-    // "queries" used in resolve that aren't tracked for incremental compilation
-    fn crate_name_untracked(&self, cnum: CrateNum) -> Symbol;
-    fn crate_is_private_dep_untracked(&self, cnum: CrateNum) -> bool;
-    fn crate_disambiguator_untracked(&self, cnum: CrateNum) -> CrateDisambiguator;
-    fn crate_hash_untracked(&self, cnum: CrateNum) -> Svh;
-
-    // This is basically a 1-based range of ints, which is a little
-    // silly - I may fix that.
-    fn crates_untracked(&self) -> Vec<CrateNum>;
-
-    // utility functions
-    fn encode_metadata(&self, tcx: TyCtxt<'_>) -> EncodedMetadata;
-    fn metadata_encoding_version(&self) -> &[u8];
-    fn allocator_kind(&self) -> Option<AllocatorKind>;
-}
-
-pub type CrateStoreDyn = dyn CrateStore + sync::Sync;
-
-// This method is used when generating the command line to pass through to
-// system linker. The linker expects undefined symbols on the left of the
-// command line to be defined in libraries on the right, not the other way
-// around. For more info, see some comments in the add_used_library function
-// below.
-//
-// In order to get this left-to-right dependency ordering, we perform a
-// topological sort of all crates putting the leaves at the right-most
-// positions.
-pub fn used_crates(tcx: TyCtxt<'_>, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)> {
-    let mut libs = tcx
-        .crates()
-        .iter()
-        .cloned()
-        .filter_map(|cnum| {
-            if tcx.dep_kind(cnum).macros_only() {
-                return None;
-            }
-            let source = tcx.used_crate_source(cnum);
-            let path = match prefer {
-                LinkagePreference::RequireDynamic => source.dylib.clone().map(|p| p.0),
-                LinkagePreference::RequireStatic => source.rlib.clone().map(|p| p.0),
-            };
-            let path = match path {
-                Some(p) => LibSource::Some(p),
-                None => {
-                    if source.rmeta.is_some() {
-                        LibSource::MetadataOnly
-                    } else {
-                        LibSource::None
-                    }
-                }
-            };
-            Some((cnum, path))
-        })
-        .collect::<Vec<_>>();
-    let mut ordering = tcx.postorder_cnums(LOCAL_CRATE).to_owned();
-    ordering.reverse();
-    libs.sort_by_cached_key(|&(a, _)| ordering.iter().position(|x| *x == a));
-    libs
-}
diff --git a/src/librustc/middle/dependency_format.rs b/src/librustc/middle/dependency_format.rs
deleted file mode 100644
index 6ece51fe866..00000000000
--- a/src/librustc/middle/dependency_format.rs
+++ /dev/null
@@ -1,28 +0,0 @@
-//! Type definitions for learning about the dependency formats of all upstream
-//! crates (rlibs/dylibs/oh my).
-//!
-//! For all the gory details, see the provider of the `dependency_formats`
-//! query.
-
-use crate::session::config;
-
-/// A list of dependencies for a certain crate type.
-///
-/// The length of this vector is the same as the number of external crates used.
-/// The value is None if the crate does not need to be linked (it was found
-/// statically in another dylib), or Some(kind) if it needs to be linked as
-/// `kind` (either static or dynamic).
-pub type DependencyList = Vec<Linkage>;
-
-/// A mapping of all required dependencies for a particular flavor of output.
-///
-/// This is local to the tcx, and is generally relevant to one session.
-pub type Dependencies = Vec<(config::CrateType, DependencyList)>;
-
-#[derive(Copy, Clone, PartialEq, Debug, HashStable, RustcEncodable, RustcDecodable)]
-pub enum Linkage {
-    NotLinked,
-    IncludedFromDylib,
-    Static,
-    Dynamic,
-}
diff --git a/src/librustc/middle/exported_symbols.rs b/src/librustc/middle/exported_symbols.rs
deleted file mode 100644
index 1f4318fa537..00000000000
--- a/src/librustc/middle/exported_symbols.rs
+++ /dev/null
@@ -1,55 +0,0 @@
-use crate::ty::subst::SubstsRef;
-use crate::ty::{self, Ty, TyCtxt};
-use rustc_hir::def_id::{DefId, LOCAL_CRATE};
-use rustc_macros::HashStable;
-
-/// The SymbolExportLevel of a symbols specifies from which kinds of crates
-/// the symbol will be exported. `C` symbols will be exported from any
-/// kind of crate, including cdylibs which export very few things.
-/// `Rust` will only be exported if the crate produced is a Rust
-/// dylib.
-#[derive(Eq, PartialEq, Debug, Copy, Clone, RustcEncodable, RustcDecodable, HashStable)]
-pub enum SymbolExportLevel {
-    C,
-    Rust,
-}
-
-impl SymbolExportLevel {
-    pub fn is_below_threshold(self, threshold: SymbolExportLevel) -> bool {
-        threshold == SymbolExportLevel::Rust // export everything from Rust dylibs
-          || self == SymbolExportLevel::C
-    }
-}
-
-#[derive(Eq, PartialEq, Debug, Copy, Clone, RustcEncodable, RustcDecodable, HashStable)]
-pub enum ExportedSymbol<'tcx> {
-    NonGeneric(DefId),
-    Generic(DefId, SubstsRef<'tcx>),
-    DropGlue(Ty<'tcx>),
-    NoDefId(ty::SymbolName),
-}
-
-impl<'tcx> ExportedSymbol<'tcx> {
-    /// This is the symbol name of an instance if it is instantiated in the
-    /// local crate.
-    pub fn symbol_name_for_local_instance(&self, tcx: TyCtxt<'tcx>) -> ty::SymbolName {
-        match *self {
-            ExportedSymbol::NonGeneric(def_id) => tcx.symbol_name(ty::Instance::mono(tcx, def_id)),
-            ExportedSymbol::Generic(def_id, substs) => {
-                tcx.symbol_name(ty::Instance::new(def_id, substs))
-            }
-            ExportedSymbol::DropGlue(ty) => {
-                tcx.symbol_name(ty::Instance::resolve_drop_in_place(tcx, ty))
-            }
-            ExportedSymbol::NoDefId(symbol_name) => symbol_name,
-        }
-    }
-}
-
-pub fn metadata_symbol_name(tcx: TyCtxt<'_>) -> String {
-    format!(
-        "rust_metadata_{}_{}",
-        tcx.original_crate_name(LOCAL_CRATE),
-        tcx.crate_disambiguator(LOCAL_CRATE).to_fingerprint().to_hex()
-    )
-}
diff --git a/src/librustc/middle/free_region.rs b/src/librustc/middle/free_region.rs
deleted file mode 100644
index 62ccd946744..00000000000
--- a/src/librustc/middle/free_region.rs
+++ /dev/null
@@ -1,44 +0,0 @@
-//! This module handles the relationships between "free regions", i.e., lifetime parameters.
-//! Ordinarily, free regions are unrelated to one another, but they can be related via implied
-//! or explicit bounds. In that case, we track the bounds using the `TransitiveRelation` type,
-//! and use that to decide when one free region outlives another, and so forth.
-
-use crate::middle::region;
-use crate::ty::free_region_map::FreeRegionMap;
-use crate::ty::{Region, TyCtxt};
-use rustc_hir::def_id::DefId;
-
-/// Combines a `region::ScopeTree` (which governs relationships between
-/// scopes) and a `FreeRegionMap` (which governs relationships between
-/// free regions) to yield a complete relation between concrete
-/// regions.
-///
-/// This stuff is a bit convoluted and should be refactored, but as we
-/// transition to NLL, it'll all go away anyhow.
-pub struct RegionRelations<'a, 'tcx> {
-    pub tcx: TyCtxt<'tcx>,
-
-    /// The context used to fetch the region maps.
-    pub context: DefId,
-
-    /// The region maps for the given context.
-    pub region_scope_tree: &'a region::ScopeTree,
-
-    /// Free-region relationships.
-    pub free_regions: &'a FreeRegionMap<'tcx>,
-}
-
-impl<'a, 'tcx> RegionRelations<'a, 'tcx> {
-    pub fn new(
-        tcx: TyCtxt<'tcx>,
-        context: DefId,
-        region_scope_tree: &'a region::ScopeTree,
-        free_regions: &'a FreeRegionMap<'tcx>,
-    ) -> Self {
-        Self { tcx, context, region_scope_tree, free_regions }
-    }
-
-    pub fn lub_free_regions(&self, r_a: Region<'tcx>, r_b: Region<'tcx>) -> Region<'tcx> {
-        self.free_regions.lub_free_regions(self.tcx, r_a, r_b)
-    }
-}
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
deleted file mode 100644
index c8e284be6fc..00000000000
--- a/src/librustc/middle/lang_items.rs
+++ /dev/null
@@ -1,65 +0,0 @@
-//! Detecting language items.
-//!
-//! Language items are items that represent concepts intrinsic to the language
-//! itself. Examples are:
-//!
-//! * Traits that specify "kinds"; e.g., `Sync`, `Send`.
-//! * Traits that represent operators; e.g., `Add`, `Sub`, `Index`.
-//! * Functions called by the compiler itself.
-
-pub use self::LangItem::*;
-
-use crate::ty::{self, TyCtxt};
-
-use rustc_hir::def_id::DefId;
-use rustc_span::Span;
-use rustc_target::spec::PanicStrategy;
-
-pub use rustc_hir::weak_lang_items::link_name;
-pub use rustc_hir::{LangItem, LanguageItems};
-
-impl<'tcx> TyCtxt<'tcx> {
-    /// Returns the `DefId` for a given `LangItem`.
-    /// If not found, fatally aborts compilation.
-    pub fn require_lang_item(&self, lang_item: LangItem, span: Option<Span>) -> DefId {
-        self.lang_items().require(lang_item).unwrap_or_else(|msg| {
-            if let Some(span) = span {
-                self.sess.span_fatal(span, &msg)
-            } else {
-                self.sess.fatal(&msg)
-            }
-        })
-    }
-
-    pub fn fn_trait_kind_from_lang_item(&self, id: DefId) -> Option<ty::ClosureKind> {
-        let items = self.lang_items();
-        match Some(id) {
-            x if x == items.fn_trait() => Some(ty::ClosureKind::Fn),
-            x if x == items.fn_mut_trait() => Some(ty::ClosureKind::FnMut),
-            x if x == items.fn_once_trait() => Some(ty::ClosureKind::FnOnce),
-            _ => None,
-        }
-    }
-
-    pub fn is_weak_lang_item(&self, item_def_id: DefId) -> bool {
-        self.lang_items().is_weak_lang_item(item_def_id)
-    }
-}
-
-/// Returns `true` if the specified `lang_item` doesn't actually need to be
-/// present for this compilation.
-///
-/// Not all lang items are always required for each compilation, particularly in
-/// the case of panic=abort. In these situations some lang items are injected by
-/// crates and don't actually need to be defined in libstd.
-pub fn whitelisted(tcx: TyCtxt<'_>, lang_item: LangItem) -> bool {
-    // If we're not compiling with unwinding, we won't actually need these
-    // symbols. Other panic runtimes ensure that the relevant symbols are
-    // available to link things together, but they're never exercised.
-    if tcx.sess.panic_strategy() != PanicStrategy::Unwind {
-        return lang_item == LangItem::EhPersonalityLangItem
-            || lang_item == LangItem::EhUnwindResumeLangItem;
-    }
-
-    false
-}
diff --git a/src/librustc/middle/mod.rs b/src/librustc/middle/mod.rs
deleted file mode 100644
index b20f2cf3a85..00000000000
--- a/src/librustc/middle/mod.rs
+++ /dev/null
@@ -1,35 +0,0 @@
-pub mod codegen_fn_attrs;
-pub mod cstore;
-pub mod dependency_format;
-pub mod exported_symbols;
-pub mod free_region;
-pub mod lang_items;
-pub mod lib_features {
-    use rustc_data_structures::fx::{FxHashMap, FxHashSet};
-    use rustc_span::symbol::Symbol;
-
-    #[derive(HashStable)]
-    pub struct LibFeatures {
-        // A map from feature to stabilisation version.
-        pub stable: FxHashMap<Symbol, Symbol>,
-        pub unstable: FxHashSet<Symbol>,
-    }
-
-    impl LibFeatures {
-        pub fn to_vec(&self) -> Vec<(Symbol, Option<Symbol>)> {
-            let mut all_features: Vec<_> = self
-                .stable
-                .iter()
-                .map(|(f, s)| (*f, Some(*s)))
-                .chain(self.unstable.iter().map(|f| (*f, None)))
-                .collect();
-            all_features.sort_unstable_by_key(|f| f.0.as_str());
-            all_features
-        }
-    }
-}
-pub mod privacy;
-pub mod recursion_limit;
-pub mod region;
-pub mod resolve_lifetime;
-pub mod stability;
diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs
deleted file mode 100644
index 4756e83b5e9..00000000000
--- a/src/librustc/middle/privacy.rs
+++ /dev/null
@@ -1,65 +0,0 @@
-//! A pass that checks to make sure private fields and methods aren't used
-//! outside their scopes. This pass will also generate a set of exported items
-//! which are available for use externally when compiled as a library.
-
-use rustc_data_structures::fx::FxHashMap;
-use rustc_hir::def_id::DefIdSet;
-use rustc_hir::HirId;
-use rustc_macros::HashStable;
-use std::fmt;
-use std::hash::Hash;
-
-// Accessibility levels, sorted in ascending order
-#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, HashStable)]
-pub enum AccessLevel {
-    /// Superset of `AccessLevel::Reachable` used to mark impl Trait items.
-    ReachableFromImplTrait,
-    /// Exported items + items participating in various kinds of public interfaces,
-    /// but not directly nameable. For example, if function `fn f() -> T {...}` is
-    /// public, then type `T` is reachable. Its values can be obtained by other crates
-    /// even if the type itself is not nameable.
-    Reachable,
-    /// Public items + items accessible to other crates with help of `pub use` re-exports
-    Exported,
-    /// Items accessible to other crates directly, without help of re-exports
-    Public,
-}
-
-// Accessibility levels for reachable HIR nodes
-#[derive(Clone)]
-pub struct AccessLevels<Id = HirId> {
-    pub map: FxHashMap<Id, AccessLevel>,
-}
-
-impl<Id: Hash + Eq> AccessLevels<Id> {
-    /// See `AccessLevel::Reachable`.
-    pub fn is_reachable(&self, id: Id) -> bool {
-        self.map.get(&id) >= Some(&AccessLevel::Reachable)
-    }
-
-    /// See `AccessLevel::Exported`.
-    pub fn is_exported(&self, id: Id) -> bool {
-        self.map.get(&id) >= Some(&AccessLevel::Exported)
-    }
-
-    /// See `AccessLevel::Public`.
-    pub fn is_public(&self, id: Id) -> bool {
-        self.map.get(&id) >= Some(&AccessLevel::Public)
-    }
-}
-
-impl<Id: Hash + Eq> Default for AccessLevels<Id> {
-    fn default() -> Self {
-        AccessLevels { map: Default::default() }
-    }
-}
-
-impl<Id: Hash + Eq + fmt::Debug> fmt::Debug for AccessLevels<Id> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        fmt::Debug::fmt(&self.map, f)
-    }
-}
-
-/// A set containing all exported definitions from external crates.
-/// The set does not contain any entries from local crates.
-pub type ExternalExports = DefIdSet;
diff --git a/src/librustc/middle/recursion_limit.rs b/src/librustc/middle/recursion_limit.rs
deleted file mode 100644
index be530da5910..00000000000
--- a/src/librustc/middle/recursion_limit.rs
+++ /dev/null
@@ -1,67 +0,0 @@
-// Recursion limit.
-//
-// There are various parts of the compiler that must impose arbitrary limits
-// on how deeply they recurse to prevent stack overflow. Users can override
-// this via an attribute on the crate like `#![recursion_limit="22"]`. This pass
-// just peeks and looks for that attribute.
-
-use crate::session::Session;
-use core::num::IntErrorKind;
-use rustc::bug;
-use rustc_span::symbol::{sym, Symbol};
-use syntax::ast;
-
-use rustc_data_structures::sync::Once;
-
-pub fn update_limits(sess: &Session, krate: &ast::Crate) {
-    update_limit(sess, krate, &sess.recursion_limit, sym::recursion_limit, 128);
-    update_limit(sess, krate, &sess.type_length_limit, sym::type_length_limit, 1048576);
-}
-
-fn update_limit(
-    sess: &Session,
-    krate: &ast::Crate,
-    limit: &Once<usize>,
-    name: Symbol,
-    default: usize,
-) {
-    for attr in &krate.attrs {
-        if !attr.check_name(name) {
-            continue;
-        }
-
-        if let Some(s) = attr.value_str() {
-            match s.as_str().parse() {
-                Ok(n) => {
-                    limit.set(n);
-                    return;
-                }
-                Err(e) => {
-                    let mut err = sess.struct_span_err(
-                        attr.span,
-                        "`recursion_limit` must be a non-negative integer",
-                    );
-
-                    let value_span = attr
-                        .meta()
-                        .and_then(|meta| meta.name_value_literal().cloned())
-                        .map(|lit| lit.span)
-                        .unwrap_or(attr.span);
-
-                    let error_str = match e.kind() {
-                        IntErrorKind::Overflow => "`recursion_limit` is too large",
-                        IntErrorKind::Empty => "`recursion_limit` must be a non-negative integer",
-                        IntErrorKind::InvalidDigit => "not a valid integer",
-                        IntErrorKind::Underflow => bug!("`recursion_limit` should never underflow"),
-                        IntErrorKind::Zero => bug!("zero is a valid `recursion_limit`"),
-                        kind => bug!("unimplemented IntErrorKind variant: {:?}", kind),
-                    };
-
-                    err.span_label(value_span, error_str);
-                    err.emit();
-                }
-            }
-        }
-    }
-    limit.set(default);
-}
diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs
deleted file mode 100644
index 9e9c8bd8464..00000000000
--- a/src/librustc/middle/region.rs
+++ /dev/null
@@ -1,669 +0,0 @@
-//! This file declares the `ScopeTree` type, which describes
-//! the parent links in the region hierarchy.
-//!
-//! For more information about how MIR-based region-checking works,
-//! see the [rustc guide].
-//!
-//! [rustc guide]: https://rust-lang.github.io/rustc-guide/mir/borrowck.html
-
-use crate::ich::{NodeIdHashingMode, StableHashingContext};
-use crate::ty::{self, DefIdTree, TyCtxt};
-use rustc_hir as hir;
-use rustc_hir::def_id::DefId;
-use rustc_hir::Node;
-
-use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
-use rustc_macros::HashStable;
-use rustc_span::{Span, DUMMY_SP};
-
-use std::fmt;
-
-/// Represents a statically-describable scope that can be used to
-/// bound the lifetime/region for values.
-///
-/// `Node(node_id)`: Any AST node that has any scope at all has the
-/// `Node(node_id)` scope. Other variants represent special cases not
-/// immediately derivable from the abstract syntax tree structure.
-///
-/// `DestructionScope(node_id)` represents the scope of destructors
-/// implicitly-attached to `node_id` that run immediately after the
-/// expression for `node_id` itself. Not every AST node carries a
-/// `DestructionScope`, but those that are `terminating_scopes` do;
-/// see discussion with `ScopeTree`.
-///
-/// `Remainder { block, statement_index }` represents
-/// the scope of user code running immediately after the initializer
-/// expression for the indexed statement, until the end of the block.
-///
-/// So: the following code can be broken down into the scopes beneath:
-///
-/// ```text
-/// let a = f().g( 'b: { let x = d(); let y = d(); x.h(y)  }   ) ;
-///
-///                                                              +-+ (D12.)
-///                                                        +-+       (D11.)
-///                                              +---------+         (R10.)
-///                                              +-+                  (D9.)
-///                                   +----------+                    (M8.)
-///                                 +----------------------+          (R7.)
-///                                 +-+                               (D6.)
-///                      +----------+                                 (M5.)
-///                    +-----------------------------------+          (M4.)
-///         +--------------------------------------------------+      (M3.)
-///         +--+                                                      (M2.)
-/// +-----------------------------------------------------------+     (M1.)
-///
-///  (M1.): Node scope of the whole `let a = ...;` statement.
-///  (M2.): Node scope of the `f()` expression.
-///  (M3.): Node scope of the `f().g(..)` expression.
-///  (M4.): Node scope of the block labeled `'b:`.
-///  (M5.): Node scope of the `let x = d();` statement
-///  (D6.): DestructionScope for temporaries created during M5.
-///  (R7.): Remainder scope for block `'b:`, stmt 0 (let x = ...).
-///  (M8.): Node scope of the `let y = d();` statement.
-///  (D9.): DestructionScope for temporaries created during M8.
-/// (R10.): Remainder scope for block `'b:`, stmt 1 (let y = ...).
-/// (D11.): DestructionScope for temporaries and bindings from block `'b:`.
-/// (D12.): DestructionScope for temporaries created during M1 (e.g., f()).
-/// ```
-///
-/// Note that while the above picture shows the destruction scopes
-/// as following their corresponding node scopes, in the internal
-/// data structures of the compiler the destruction scopes are
-/// represented as enclosing parents. This is sound because we use the
-/// enclosing parent relationship just to ensure that referenced
-/// values live long enough; phrased another way, the starting point
-/// of each range is not really the important thing in the above
-/// picture, but rather the ending point.
-//
-// FIXME(pnkfelix): this currently derives `PartialOrd` and `Ord` to
-// placate the same deriving in `ty::FreeRegion`, but we may want to
-// actually attach a more meaningful ordering to scopes than the one
-// generated via deriving here.
-#[derive(
-    Clone,
-    PartialEq,
-    PartialOrd,
-    Eq,
-    Ord,
-    Hash,
-    Copy,
-    RustcEncodable,
-    RustcDecodable,
-    HashStable
-)]
-pub struct Scope {
-    pub id: hir::ItemLocalId,
-    pub data: ScopeData,
-}
-
-impl fmt::Debug for Scope {
-    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match self.data {
-            ScopeData::Node => write!(fmt, "Node({:?})", self.id),
-            ScopeData::CallSite => write!(fmt, "CallSite({:?})", self.id),
-            ScopeData::Arguments => write!(fmt, "Arguments({:?})", self.id),
-            ScopeData::Destruction => write!(fmt, "Destruction({:?})", self.id),
-            ScopeData::Remainder(fsi) => write!(
-                fmt,
-                "Remainder {{ block: {:?}, first_statement_index: {}}}",
-                self.id,
-                fsi.as_u32(),
-            ),
-        }
-    }
-}
-
-#[derive(
-    Clone,
-    PartialEq,
-    PartialOrd,
-    Eq,
-    Ord,
-    Hash,
-    Debug,
-    Copy,
-    RustcEncodable,
-    RustcDecodable,
-    HashStable
-)]
-pub enum ScopeData {
-    Node,
-
-    /// Scope of the call-site for a function or closure
-    /// (outlives the arguments as well as the body).
-    CallSite,
-
-    /// Scope of arguments passed to a function or closure
-    /// (they outlive its body).
-    Arguments,
-
-    /// Scope of destructors for temporaries of node-id.
-    Destruction,
-
-    /// Scope following a `let id = expr;` binding in a block.
-    Remainder(FirstStatementIndex),
-}
-
-rustc_index::newtype_index! {
-    /// Represents a subscope of `block` for a binding that is introduced
-    /// by `block.stmts[first_statement_index]`. Such subscopes represent
-    /// a suffix of the block. Note that each subscope does not include
-    /// the initializer expression, if any, for the statement indexed by
-    /// `first_statement_index`.
-    ///
-    /// For example, given `{ let (a, b) = EXPR_1; let c = EXPR_2; ... }`:
-    ///
-    /// * The subscope with `first_statement_index == 0` is scope of both
-    ///   `a` and `b`; it does not include EXPR_1, but does include
-    ///   everything after that first `let`. (If you want a scope that
-    ///   includes EXPR_1 as well, then do not use `Scope::Remainder`,
-    ///   but instead another `Scope` that encompasses the whole block,
-    ///   e.g., `Scope::Node`.
-    ///
-    /// * The subscope with `first_statement_index == 1` is scope of `c`,
-    ///   and thus does not include EXPR_2, but covers the `...`.
-    pub struct FirstStatementIndex {
-        derive [HashStable]
-    }
-}
-
-// compilation error if size of `ScopeData` is not the same as a `u32`
-static_assert_size!(ScopeData, 4);
-
-impl Scope {
-    /// Returns a item-local ID associated with this scope.
-    ///
-    /// N.B., likely to be replaced as API is refined; e.g., pnkfelix
-    /// anticipates `fn entry_node_id` and `fn each_exit_node_id`.
-    pub fn item_local_id(&self) -> hir::ItemLocalId {
-        self.id
-    }
-
-    pub fn hir_id(&self, scope_tree: &ScopeTree) -> hir::HirId {
-        match scope_tree.root_body {
-            Some(hir_id) => hir::HirId { owner: hir_id.owner, local_id: self.item_local_id() },
-            None => hir::DUMMY_HIR_ID,
-        }
-    }
-
-    /// Returns the span of this `Scope`. Note that in general the
-    /// returned span may not correspond to the span of any `NodeId` in
-    /// the AST.
-    pub fn span(&self, tcx: TyCtxt<'_>, scope_tree: &ScopeTree) -> Span {
-        let hir_id = self.hir_id(scope_tree);
-        if hir_id == hir::DUMMY_HIR_ID {
-            return DUMMY_SP;
-        }
-        let span = tcx.hir().span(hir_id);
-        if let ScopeData::Remainder(first_statement_index) = self.data {
-            if let Node::Block(ref blk) = tcx.hir().get(hir_id) {
-                // Want span for scope starting after the
-                // indexed statement and ending at end of
-                // `blk`; reuse span of `blk` and shift `lo`
-                // forward to end of indexed statement.
-                //
-                // (This is the special case aluded to in the
-                // doc-comment for this method)
-
-                let stmt_span = blk.stmts[first_statement_index.index()].span;
-
-                // To avoid issues with macro-generated spans, the span
-                // of the statement must be nested in that of the block.
-                if span.lo() <= stmt_span.lo() && stmt_span.lo() <= span.hi() {
-                    return Span::new(stmt_span.lo(), span.hi(), span.ctxt());
-                }
-            }
-        }
-        span
-    }
-}
-
-pub type ScopeDepth = u32;
-
-/// The region scope tree encodes information about region relationships.
-#[derive(Default, Debug)]
-pub struct ScopeTree {
-    /// If not empty, this body is the root of this region hierarchy.
-    pub root_body: Option<hir::HirId>,
-
-    /// The parent of the root body owner, if the latter is an
-    /// an associated const or method, as impls/traits can also
-    /// have lifetime parameters free in this body.
-    pub root_parent: Option<hir::HirId>,
-
-    /// Maps from a scope ID to the enclosing scope id;
-    /// this is usually corresponding to the lexical nesting, though
-    /// in the case of closures the parent scope is the innermost
-    /// conditional expression or repeating block. (Note that the
-    /// enclosing scope ID for the block associated with a closure is
-    /// the closure itself.)
-    pub parent_map: FxHashMap<Scope, (Scope, ScopeDepth)>,
-
-    /// Maps from a variable or binding ID to the block in which that
-    /// variable is declared.
-    var_map: FxHashMap<hir::ItemLocalId, Scope>,
-
-    /// Maps from a `NodeId` to the associated destruction scope (if any).
-    destruction_scopes: FxHashMap<hir::ItemLocalId, Scope>,
-
-    /// `rvalue_scopes` includes entries for those expressions whose
-    /// cleanup scope is larger than the default. The map goes from the
-    /// expression ID to the cleanup scope id. For rvalues not present in
-    /// this table, the appropriate cleanup scope is the innermost
-    /// enclosing statement, conditional expression, or repeating
-    /// block (see `terminating_scopes`).
-    /// In constants, None is used to indicate that certain expressions
-    /// escape into 'static and should have no local cleanup scope.
-    rvalue_scopes: FxHashMap<hir::ItemLocalId, Option<Scope>>,
-
-    /// Encodes the hierarchy of fn bodies. Every fn body (including
-    /// closures) forms its own distinct region hierarchy, rooted in
-    /// the block that is the fn body. This map points from the ID of
-    /// that root block to the ID of the root block for the enclosing
-    /// fn, if any. Thus the map structures the fn bodies into a
-    /// hierarchy based on their lexical mapping. This is used to
-    /// handle the relationships between regions in a fn and in a
-    /// closure defined by that fn. See the "Modeling closures"
-    /// section of the README in infer::region_constraints for
-    /// more details.
-    closure_tree: FxHashMap<hir::ItemLocalId, hir::ItemLocalId>,
-
-    /// If there are any `yield` nested within a scope, this map
-    /// stores the `Span` of the last one and its index in the
-    /// postorder of the Visitor traversal on the HIR.
-    ///
-    /// HIR Visitor postorder indexes might seem like a peculiar
-    /// thing to care about. but it turns out that HIR bindings
-    /// and the temporary results of HIR expressions are never
-    /// storage-live at the end of HIR nodes with postorder indexes
-    /// lower than theirs, and therefore don't need to be suspended
-    /// at yield-points at these indexes.
-    ///
-    /// For an example, suppose we have some code such as:
-    /// ```rust,ignore (example)
-    ///     foo(f(), yield y, bar(g()))
-    /// ```
-    ///
-    /// With the HIR tree (calls numbered for expository purposes)
-    /// ```
-    ///     Call#0(foo, [Call#1(f), Yield(y), Call#2(bar, Call#3(g))])
-    /// ```
-    ///
-    /// Obviously, the result of `f()` was created before the yield
-    /// (and therefore needs to be kept valid over the yield) while
-    /// the result of `g()` occurs after the yield (and therefore
-    /// doesn't). If we want to infer that, we can look at the
-    /// postorder traversal:
-    /// ```plain,ignore
-    ///     `foo` `f` Call#1 `y` Yield `bar` `g` Call#3 Call#2 Call#0
-    /// ```
-    ///
-    /// In which we can easily see that `Call#1` occurs before the yield,
-    /// and `Call#3` after it.
-    ///
-    /// To see that this method works, consider:
-    ///
-    /// Let `D` be our binding/temporary and `U` be our other HIR node, with
-    /// `HIR-postorder(U) < HIR-postorder(D)` (in our example, U would be
-    /// the yield and D would be one of the calls). Let's show that
-    /// `D` is storage-dead at `U`.
-    ///
-    /// Remember that storage-live/storage-dead refers to the state of
-    /// the *storage*, and does not consider moves/drop flags.
-    ///
-    /// Then:
-    ///     1. From the ordering guarantee of HIR visitors (see
-    ///     `rustc::hir::intravisit`), `D` does not dominate `U`.
-    ///     2. Therefore, `D` is *potentially* storage-dead at `U` (because
-    ///     we might visit `U` without ever getting to `D`).
-    ///     3. However, we guarantee that at each HIR point, each
-    ///     binding/temporary is always either always storage-live
-    ///     or always storage-dead. This is what is being guaranteed
-    ///     by `terminating_scopes` including all blocks where the
-    ///     count of executions is not guaranteed.
-    ///     4. By `2.` and `3.`, `D` is *statically* storage-dead at `U`,
-    ///     QED.
-    ///
-    /// This property ought to not on (3) in an essential way -- it
-    /// is probably still correct even if we have "unrestricted" terminating
-    /// scopes. However, why use the complicated proof when a simple one
-    /// works?
-    ///
-    /// A subtle thing: `box` expressions, such as `box (&x, yield 2, &y)`. It
-    /// might seem that a `box` expression creates a `Box<T>` temporary
-    /// when it *starts* executing, at `HIR-preorder(BOX-EXPR)`. That might
-    /// be true in the MIR desugaring, but it is not important in the semantics.
-    ///
-    /// The reason is that semantically, until the `box` expression returns,
-    /// the values are still owned by their containing expressions. So
-    /// we'll see that `&x`.
-    pub yield_in_scope: FxHashMap<Scope, YieldData>,
-
-    /// The number of visit_expr and visit_pat calls done in the body.
-    /// Used to sanity check visit_expr/visit_pat call count when
-    /// calculating generator interiors.
-    pub body_expr_count: FxHashMap<hir::BodyId, usize>,
-}
-
-#[derive(Debug, Copy, Clone, RustcEncodable, RustcDecodable, HashStable)]
-pub struct YieldData {
-    /// The `Span` of the yield.
-    pub span: Span,
-    /// The number of expressions and patterns appearing before the `yield` in the body plus one.
-    pub expr_and_pat_count: usize,
-    pub source: hir::YieldSource,
-}
-
-impl<'tcx> ScopeTree {
-    pub fn record_scope_parent(&mut self, child: Scope, parent: Option<(Scope, ScopeDepth)>) {
-        debug!("{:?}.parent = {:?}", child, parent);
-
-        if let Some(p) = parent {
-            let prev = self.parent_map.insert(child, p);
-            assert!(prev.is_none());
-        }
-
-        // Record the destruction scopes for later so we can query them.
-        if let ScopeData::Destruction = child.data {
-            self.destruction_scopes.insert(child.item_local_id(), child);
-        }
-    }
-
-    pub fn each_encl_scope<E>(&self, mut e: E)
-    where
-        E: FnMut(Scope, Scope),
-    {
-        for (&child, &parent) in &self.parent_map {
-            e(child, parent.0)
-        }
-    }
-
-    pub fn each_var_scope<E>(&self, mut e: E)
-    where
-        E: FnMut(&hir::ItemLocalId, Scope),
-    {
-        for (child, &parent) in self.var_map.iter() {
-            e(child, parent)
-        }
-    }
-
-    pub fn opt_destruction_scope(&self, n: hir::ItemLocalId) -> Option<Scope> {
-        self.destruction_scopes.get(&n).cloned()
-    }
-
-    /// Records that `sub_closure` is defined within `sup_closure`. These IDs
-    /// should be the ID of the block that is the fn body, which is
-    /// also the root of the region hierarchy for that fn.
-    pub fn record_closure_parent(
-        &mut self,
-        sub_closure: hir::ItemLocalId,
-        sup_closure: hir::ItemLocalId,
-    ) {
-        debug!(
-            "record_closure_parent(sub_closure={:?}, sup_closure={:?})",
-            sub_closure, sup_closure
-        );
-        assert!(sub_closure != sup_closure);
-        let previous = self.closure_tree.insert(sub_closure, sup_closure);
-        assert!(previous.is_none());
-    }
-
-    pub fn record_var_scope(&mut self, var: hir::ItemLocalId, lifetime: Scope) {
-        debug!("record_var_scope(sub={:?}, sup={:?})", var, lifetime);
-        assert!(var != lifetime.item_local_id());
-        self.var_map.insert(var, lifetime);
-    }
-
-    pub fn record_rvalue_scope(&mut self, var: hir::ItemLocalId, lifetime: Option<Scope>) {
-        debug!("record_rvalue_scope(sub={:?}, sup={:?})", var, lifetime);
-        if let Some(lifetime) = lifetime {
-            assert!(var != lifetime.item_local_id());
-        }
-        self.rvalue_scopes.insert(var, lifetime);
-    }
-
-    /// Returns the narrowest scope that encloses `id`, if any.
-    pub fn opt_encl_scope(&self, id: Scope) -> Option<Scope> {
-        self.parent_map.get(&id).cloned().map(|(p, _)| p)
-    }
-
-    /// Returns the narrowest scope that encloses `id`, if any.
-    #[allow(dead_code)] // used in cfg
-    pub fn encl_scope(&self, id: Scope) -> Scope {
-        self.opt_encl_scope(id).unwrap()
-    }
-
-    /// Returns the lifetime of the local variable `var_id`
-    pub fn var_scope(&self, var_id: hir::ItemLocalId) -> Scope {
-        self.var_map
-            .get(&var_id)
-            .cloned()
-            .unwrap_or_else(|| bug!("no enclosing scope for id {:?}", var_id))
-    }
-
-    /// Returns the scope when the temp created by `expr_id` will be cleaned up.
-    pub fn temporary_scope(&self, expr_id: hir::ItemLocalId) -> Option<Scope> {
-        // Check for a designated rvalue scope.
-        if let Some(&s) = self.rvalue_scopes.get(&expr_id) {
-            debug!("temporary_scope({:?}) = {:?} [custom]", expr_id, s);
-            return s;
-        }
-
-        // Otherwise, locate the innermost terminating scope
-        // if there's one. Static items, for instance, won't
-        // have an enclosing scope, hence no scope will be
-        // returned.
-        let mut id = Scope { id: expr_id, data: ScopeData::Node };
-
-        while let Some(&(p, _)) = self.parent_map.get(&id) {
-            match p.data {
-                ScopeData::Destruction => {
-                    debug!("temporary_scope({:?}) = {:?} [enclosing]", expr_id, id);
-                    return Some(id);
-                }
-                _ => id = p,
-            }
-        }
-
-        debug!("temporary_scope({:?}) = None", expr_id);
-        return None;
-    }
-
-    /// Returns the lifetime of the variable `id`.
-    pub fn var_region(&self, id: hir::ItemLocalId) -> ty::RegionKind {
-        let scope = ty::ReScope(self.var_scope(id));
-        debug!("var_region({:?}) = {:?}", id, scope);
-        scope
-    }
-
-    pub fn scopes_intersect(&self, scope1: Scope, scope2: Scope) -> bool {
-        self.is_subscope_of(scope1, scope2) || self.is_subscope_of(scope2, scope1)
-    }
-
-    /// Returns `true` if `subscope` is equal to or is lexically nested inside `superscope`, and
-    /// `false` otherwise.
-    pub fn is_subscope_of(&self, subscope: Scope, superscope: Scope) -> bool {
-        let mut s = subscope;
-        debug!("is_subscope_of({:?}, {:?})", subscope, superscope);
-        while superscope != s {
-            match self.opt_encl_scope(s) {
-                None => {
-                    debug!("is_subscope_of({:?}, {:?}, s={:?})=false", subscope, superscope, s);
-                    return false;
-                }
-                Some(scope) => s = scope,
-            }
-        }
-
-        debug!("is_subscope_of({:?}, {:?})=true", subscope, superscope);
-
-        return true;
-    }
-
-    /// Returns the ID of the innermost containing body.
-    pub fn containing_body(&self, mut scope: Scope) -> Option<hir::ItemLocalId> {
-        loop {
-            if let ScopeData::CallSite = scope.data {
-                return Some(scope.item_local_id());
-            }
-
-            scope = self.opt_encl_scope(scope)?;
-        }
-    }
-
-    /// Finds the nearest common ancestor of two scopes. That is, finds the
-    /// smallest scope which is greater than or equal to both `scope_a` and
-    /// `scope_b`.
-    pub fn nearest_common_ancestor(&self, scope_a: Scope, scope_b: Scope) -> Scope {
-        if scope_a == scope_b {
-            return scope_a;
-        }
-
-        let mut a = scope_a;
-        let mut b = scope_b;
-
-        // Get the depth of each scope's parent. If either scope has no parent,
-        // it must be the root, which means we can stop immediately because the
-        // root must be the nearest common ancestor. (In practice, this is
-        // moderately common.)
-        let (parent_a, parent_a_depth) = match self.parent_map.get(&a) {
-            Some(pd) => *pd,
-            None => return a,
-        };
-        let (parent_b, parent_b_depth) = match self.parent_map.get(&b) {
-            Some(pd) => *pd,
-            None => return b,
-        };
-
-        if parent_a_depth > parent_b_depth {
-            // `a` is lower than `b`. Move `a` up until it's at the same depth
-            // as `b`. The first move up is trivial because we already found
-            // `parent_a` above; the loop does the remaining N-1 moves.
-            a = parent_a;
-            for _ in 0..(parent_a_depth - parent_b_depth - 1) {
-                a = self.parent_map.get(&a).unwrap().0;
-            }
-        } else if parent_b_depth > parent_a_depth {
-            // `b` is lower than `a`.
-            b = parent_b;
-            for _ in 0..(parent_b_depth - parent_a_depth - 1) {
-                b = self.parent_map.get(&b).unwrap().0;
-            }
-        } else {
-            // Both scopes are at the same depth, and we know they're not equal
-            // because that case was tested for at the top of this function. So
-            // we can trivially move them both up one level now.
-            assert!(parent_a_depth != 0);
-            a = parent_a;
-            b = parent_b;
-        }
-
-        // Now both scopes are at the same level. We move upwards in lockstep
-        // until they match. In practice, this loop is almost always executed
-        // zero times because `a` is almost always a direct ancestor of `b` or
-        // vice versa.
-        while a != b {
-            a = self.parent_map.get(&a).unwrap().0;
-            b = self.parent_map.get(&b).unwrap().0;
-        }
-
-        a
-    }
-
-    /// Assuming that the provided region was defined within this `ScopeTree`,
-    /// returns the outermost `Scope` that the region outlives.
-    pub fn early_free_scope(&self, tcx: TyCtxt<'tcx>, br: &ty::EarlyBoundRegion) -> Scope {
-        let param_owner = tcx.parent(br.def_id).unwrap();
-
-        let param_owner_id = tcx.hir().as_local_hir_id(param_owner).unwrap();
-        let scope = tcx
-            .hir()
-            .maybe_body_owned_by(param_owner_id)
-            .map(|body_id| tcx.hir().body(body_id).value.hir_id.local_id)
-            .unwrap_or_else(|| {
-                // The lifetime was defined on node that doesn't own a body,
-                // which in practice can only mean a trait or an impl, that
-                // is the parent of a method, and that is enforced below.
-                if Some(param_owner_id) != self.root_parent {
-                    tcx.sess.delay_span_bug(
-                        DUMMY_SP,
-                        &format!(
-                            "free_scope: {:?} not recognized by the \
-                              region scope tree for {:?} / {:?}",
-                            param_owner,
-                            self.root_parent.map(|id| tcx.hir().local_def_id(id)),
-                            self.root_body.map(|hir_id| DefId::local(hir_id.owner))
-                        ),
-                    );
-                }
-
-                // The trait/impl lifetime is in scope for the method's body.
-                self.root_body.unwrap().local_id
-            });
-
-        Scope { id: scope, data: ScopeData::CallSite }
-    }
-
-    /// Assuming that the provided region was defined within this `ScopeTree`,
-    /// returns the outermost `Scope` that the region outlives.
-    pub fn free_scope(&self, tcx: TyCtxt<'tcx>, fr: &ty::FreeRegion) -> Scope {
-        let param_owner = match fr.bound_region {
-            ty::BoundRegion::BrNamed(def_id, _) => tcx.parent(def_id).unwrap(),
-            _ => fr.scope,
-        };
-
-        // Ensure that the named late-bound lifetimes were defined
-        // on the same function that they ended up being freed in.
-        assert_eq!(param_owner, fr.scope);
-
-        let param_owner_id = tcx.hir().as_local_hir_id(param_owner).unwrap();
-        let body_id = tcx.hir().body_owned_by(param_owner_id);
-        Scope { id: tcx.hir().body(body_id).value.hir_id.local_id, data: ScopeData::CallSite }
-    }
-
-    /// Checks whether the given scope contains a `yield`. If so,
-    /// returns `Some((span, expr_count))` with the span of a yield we found and
-    /// the number of expressions and patterns appearing before the `yield` in the body + 1.
-    /// If there a are multiple yields in a scope, the one with the highest number is returned.
-    pub fn yield_in_scope(&self, scope: Scope) -> Option<YieldData> {
-        self.yield_in_scope.get(&scope).cloned()
-    }
-
-    /// Gives the number of expressions visited in a body.
-    /// Used to sanity check visit_expr call count when
-    /// calculating generator interiors.
-    pub fn body_expr_count(&self, body_id: hir::BodyId) -> Option<usize> {
-        self.body_expr_count.get(&body_id).map(|r| *r)
-    }
-}
-
-impl<'a> HashStable<StableHashingContext<'a>> for ScopeTree {
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        let ScopeTree {
-            root_body,
-            root_parent,
-            ref body_expr_count,
-            ref parent_map,
-            ref var_map,
-            ref destruction_scopes,
-            ref rvalue_scopes,
-            ref closure_tree,
-            ref yield_in_scope,
-        } = *self;
-
-        hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
-            root_body.hash_stable(hcx, hasher);
-            root_parent.hash_stable(hcx, hasher);
-        });
-
-        body_expr_count.hash_stable(hcx, hasher);
-        parent_map.hash_stable(hcx, hasher);
-        var_map.hash_stable(hcx, hasher);
-        destruction_scopes.hash_stable(hcx, hasher);
-        rvalue_scopes.hash_stable(hcx, hasher);
-        closure_tree.hash_stable(hcx, hasher);
-        yield_in_scope.hash_stable(hcx, hasher);
-    }
-}
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
deleted file mode 100644
index c21ba1b3bd2..00000000000
--- a/src/librustc/middle/resolve_lifetime.rs
+++ /dev/null
@@ -1,86 +0,0 @@
-//! Name resolution for lifetimes: type declarations.
-
-use crate::ty;
-
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
-use rustc_hir::def_id::{DefId, LocalDefId};
-use rustc_hir::{GenericParam, ItemLocalId};
-use rustc_hir::{GenericParamKind, LifetimeParamKind};
-use rustc_macros::HashStable;
-
-/// The origin of a named lifetime definition.
-///
-/// This is used to prevent the usage of in-band lifetimes in `Fn`/`fn` syntax.
-#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug, HashStable)]
-pub enum LifetimeDefOrigin {
-    // Explicit binders like `fn foo<'a>(x: &'a u8)` or elided like `impl Foo<&u32>`
-    ExplicitOrElided,
-    // In-band declarations like `fn foo(x: &'a u8)`
-    InBand,
-    // Some kind of erroneous origin
-    Error,
-}
-
-impl LifetimeDefOrigin {
-    pub fn from_param(param: &GenericParam<'_>) -> Self {
-        match param.kind {
-            GenericParamKind::Lifetime { kind } => match kind {
-                LifetimeParamKind::InBand => LifetimeDefOrigin::InBand,
-                LifetimeParamKind::Explicit => LifetimeDefOrigin::ExplicitOrElided,
-                LifetimeParamKind::Elided => LifetimeDefOrigin::ExplicitOrElided,
-                LifetimeParamKind::Error => LifetimeDefOrigin::Error,
-            },
-            _ => bug!("expected a lifetime param"),
-        }
-    }
-}
-
-#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug, HashStable)]
-pub enum Region {
-    Static,
-    EarlyBound(/* index */ u32, /* lifetime decl */ DefId, LifetimeDefOrigin),
-    LateBound(ty::DebruijnIndex, /* lifetime decl */ DefId, LifetimeDefOrigin),
-    LateBoundAnon(ty::DebruijnIndex, /* anon index */ u32),
-    Free(DefId, /* lifetime decl */ DefId),
-}
-
-/// A set containing, at most, one known element.
-/// If two distinct values are inserted into a set, then it
-/// becomes `Many`, which can be used to detect ambiguities.
-#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug, HashStable)]
-pub enum Set1<T> {
-    Empty,
-    One(T),
-    Many,
-}
-
-impl<T: PartialEq> Set1<T> {
-    pub fn insert(&mut self, value: T) {
-        *self = match self {
-            Set1::Empty => Set1::One(value),
-            Set1::One(old) if *old == value => return,
-            _ => Set1::Many,
-        };
-    }
-}
-
-pub type ObjectLifetimeDefault = Set1<Region>;
-
-/// Maps the id of each lifetime reference to the lifetime decl
-/// that it corresponds to.
-#[derive(Default, HashStable)]
-pub struct ResolveLifetimes {
-    /// Maps from every use of a named (not anonymous) lifetime to a
-    /// `Region` describing how that region is bound
-    pub defs: FxHashMap<LocalDefId, FxHashMap<ItemLocalId, Region>>,
-
-    /// Set of lifetime def ids that are late-bound; a region can
-    /// be late-bound if (a) it does NOT appear in a where-clause and
-    /// (b) it DOES appear in the arguments.
-    pub late_bound: FxHashMap<LocalDefId, FxHashSet<ItemLocalId>>,
-
-    /// For each type and trait definition, maps type parameters
-    /// to the trait object lifetime defaults computed from them.
-    pub object_lifetime_defaults:
-        FxHashMap<LocalDefId, FxHashMap<ItemLocalId, Vec<ObjectLifetimeDefault>>>,
-}
diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs
deleted file mode 100644
index 7b5faa2423a..00000000000
--- a/src/librustc/middle/stability.rs
+++ /dev/null
@@ -1,413 +0,0 @@
-//! A pass that annotates every item and method with its stability level,
-//! propagating default levels lexically from parent to children ast nodes.
-
-pub use self::StabilityLevel::*;
-
-use crate::session::{DiagnosticMessageId, Session};
-use crate::ty::{self, TyCtxt};
-use rustc_attr::{self as attr, ConstStability, Deprecation, RustcDeprecation, Stability};
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
-use rustc_errors::{Applicability, DiagnosticBuilder};
-use rustc_feature::GateIssue;
-use rustc_hir as hir;
-use rustc_hir::def::DefKind;
-use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX};
-use rustc_hir::{self, HirId};
-use rustc_session::lint::builtin::{DEPRECATED, DEPRECATED_IN_FUTURE, SOFT_UNSTABLE};
-use rustc_session::lint::{BuiltinLintDiagnostics, Lint, LintBuffer};
-use rustc_session::parse::feature_err_issue;
-use rustc_span::symbol::{sym, Symbol};
-use rustc_span::{MultiSpan, Span};
-use syntax::ast::CRATE_NODE_ID;
-
-use std::num::NonZeroU32;
-
-#[derive(PartialEq, Clone, Copy, Debug)]
-pub enum StabilityLevel {
-    Unstable,
-    Stable,
-}
-
-impl StabilityLevel {
-    pub fn from_attr_level(level: &attr::StabilityLevel) -> Self {
-        if level.is_stable() { Stable } else { Unstable }
-    }
-}
-
-/// An entry in the `depr_map`.
-#[derive(Clone, HashStable)]
-pub struct DeprecationEntry {
-    /// The metadata of the attribute associated with this entry.
-    pub attr: Deprecation,
-    /// The `DefId` where the attr was originally attached. `None` for non-local
-    /// `DefId`'s.
-    origin: Option<HirId>,
-}
-
-impl DeprecationEntry {
-    pub fn local(attr: Deprecation, id: HirId) -> DeprecationEntry {
-        DeprecationEntry { attr, origin: Some(id) }
-    }
-
-    pub fn external(attr: Deprecation) -> DeprecationEntry {
-        DeprecationEntry { attr, origin: None }
-    }
-
-    pub fn same_origin(&self, other: &DeprecationEntry) -> bool {
-        match (self.origin, other.origin) {
-            (Some(o1), Some(o2)) => o1 == o2,
-            _ => false,
-        }
-    }
-}
-
-/// A stability index, giving the stability level for items and methods.
-#[derive(HashStable)]
-pub struct Index<'tcx> {
-    /// This is mostly a cache, except the stabilities of local items
-    /// are filled by the annotator.
-    pub stab_map: FxHashMap<HirId, &'tcx Stability>,
-    pub const_stab_map: FxHashMap<HirId, &'tcx ConstStability>,
-    pub depr_map: FxHashMap<HirId, DeprecationEntry>,
-
-    /// Maps for each crate whether it is part of the staged API.
-    pub staged_api: FxHashMap<CrateNum, bool>,
-
-    /// Features enabled for this crate.
-    pub active_features: FxHashSet<Symbol>,
-}
-
-impl<'tcx> Index<'tcx> {
-    pub fn local_stability(&self, id: HirId) -> Option<&'tcx Stability> {
-        self.stab_map.get(&id).cloned()
-    }
-
-    pub fn local_const_stability(&self, id: HirId) -> Option<&'tcx ConstStability> {
-        self.const_stab_map.get(&id).cloned()
-    }
-
-    pub fn local_deprecation_entry(&self, id: HirId) -> Option<DeprecationEntry> {
-        self.depr_map.get(&id).cloned()
-    }
-}
-
-pub fn report_unstable(
-    sess: &Session,
-    feature: Symbol,
-    reason: Option<Symbol>,
-    issue: Option<NonZeroU32>,
-    is_soft: bool,
-    span: Span,
-    soft_handler: impl FnOnce(&'static Lint, Span, &str),
-) {
-    let msg = match reason {
-        Some(r) => format!("use of unstable library feature '{}': {}", feature, r),
-        None => format!("use of unstable library feature '{}'", &feature),
-    };
-
-    let msp: MultiSpan = span.into();
-    let sm = &sess.parse_sess.source_map();
-    let span_key = msp.primary_span().and_then(|sp: Span| {
-        if !sp.is_dummy() {
-            let file = sm.lookup_char_pos(sp.lo()).file;
-            if file.name.is_macros() { None } else { Some(span) }
-        } else {
-            None
-        }
-    });
-
-    let error_id = (DiagnosticMessageId::StabilityId(issue), span_key, msg.clone());
-    let fresh = sess.one_time_diagnostics.borrow_mut().insert(error_id);
-    if fresh {
-        if is_soft {
-            soft_handler(SOFT_UNSTABLE, span, &msg)
-        } else {
-            feature_err_issue(&sess.parse_sess, feature, span, GateIssue::Library(issue), &msg)
-                .emit();
-        }
-    }
-}
-
-/// Checks whether an item marked with `deprecated(since="X")` is currently
-/// deprecated (i.e., whether X is not greater than the current rustc version).
-pub fn deprecation_in_effect(since: &str) -> bool {
-    fn parse_version(ver: &str) -> Vec<u32> {
-        // We ignore non-integer components of the version (e.g., "nightly").
-        ver.split(|c| c == '.' || c == '-').flat_map(|s| s.parse()).collect()
-    }
-
-    if let Some(rustc) = option_env!("CFG_RELEASE") {
-        let since: Vec<u32> = parse_version(since);
-        let rustc: Vec<u32> = parse_version(rustc);
-        // We simply treat invalid `since` attributes as relating to a previous
-        // Rust version, thus always displaying the warning.
-        if since.len() != 3 {
-            return true;
-        }
-        since <= rustc
-    } else {
-        // By default, a deprecation warning applies to
-        // the current version of the compiler.
-        true
-    }
-}
-
-pub fn deprecation_suggestion(
-    diag: &mut DiagnosticBuilder<'_>,
-    suggestion: Option<Symbol>,
-    span: Span,
-) {
-    if let Some(suggestion) = suggestion {
-        diag.span_suggestion(
-            span,
-            "replace the use of the deprecated item",
-            suggestion.to_string(),
-            Applicability::MachineApplicable,
-        );
-    }
-}
-
-fn deprecation_message_common(message: String, reason: Option<Symbol>) -> String {
-    match reason {
-        Some(reason) => format!("{}: {}", message, reason),
-        None => message,
-    }
-}
-
-pub fn deprecation_message(depr: &Deprecation, path: &str) -> (String, &'static Lint) {
-    let message = format!("use of deprecated item '{}'", path);
-    (deprecation_message_common(message, depr.note), DEPRECATED)
-}
-
-pub fn rustc_deprecation_message(depr: &RustcDeprecation, path: &str) -> (String, &'static Lint) {
-    let (message, lint) = if deprecation_in_effect(&depr.since.as_str()) {
-        (format!("use of deprecated item '{}'", path), DEPRECATED)
-    } else {
-        (
-            format!(
-                "use of item '{}' that will be deprecated in future version {}",
-                path, depr.since
-            ),
-            DEPRECATED_IN_FUTURE,
-        )
-    };
-    (deprecation_message_common(message, Some(depr.reason)), lint)
-}
-
-pub fn early_report_deprecation(
-    lint_buffer: &'a mut LintBuffer,
-    message: &str,
-    suggestion: Option<Symbol>,
-    lint: &'static Lint,
-    span: Span,
-) {
-    if span.in_derive_expansion() {
-        return;
-    }
-
-    let diag = BuiltinLintDiagnostics::DeprecatedMacro(suggestion, span);
-    lint_buffer.buffer_lint_with_diagnostic(lint, CRATE_NODE_ID, span, message, diag);
-}
-
-fn late_report_deprecation(
-    tcx: TyCtxt<'_>,
-    message: &str,
-    suggestion: Option<Symbol>,
-    lint: &'static Lint,
-    span: Span,
-    def_id: DefId,
-    hir_id: HirId,
-) {
-    if span.in_derive_expansion() {
-        return;
-    }
-
-    tcx.struct_span_lint_hir(lint, hir_id, span, |lint| {
-        let mut diag = lint.build(message);
-        if let hir::Node::Expr(_) = tcx.hir().get(hir_id) {
-            deprecation_suggestion(&mut diag, suggestion, span);
-        }
-        diag.emit()
-    });
-    if hir_id == hir::DUMMY_HIR_ID {
-        span_bug!(span, "emitted a {} lint with dummy HIR id: {:?}", lint.name, def_id);
-    }
-}
-
-/// Result of `TyCtxt::eval_stability`.
-pub enum EvalResult {
-    /// We can use the item because it is stable or we provided the
-    /// corresponding feature gate.
-    Allow,
-    /// We cannot use the item because it is unstable and we did not provide the
-    /// corresponding feature gate.
-    Deny { feature: Symbol, reason: Option<Symbol>, issue: Option<NonZeroU32>, is_soft: bool },
-    /// The item does not have the `#[stable]` or `#[unstable]` marker assigned.
-    Unmarked,
-}
-
-// See issue #38412.
-fn skip_stability_check_due_to_privacy(tcx: TyCtxt<'_>, mut def_id: DefId) -> bool {
-    // Check if `def_id` is a trait method.
-    match tcx.def_kind(def_id) {
-        Some(DefKind::Method) | Some(DefKind::AssocTy) | Some(DefKind::AssocConst) => {
-            if let ty::TraitContainer(trait_def_id) = tcx.associated_item(def_id).container {
-                // Trait methods do not declare visibility (even
-                // for visibility info in cstore). Use containing
-                // trait instead, so methods of `pub` traits are
-                // themselves considered `pub`.
-                def_id = trait_def_id;
-            }
-        }
-        _ => {}
-    }
-
-    let visibility = tcx.visibility(def_id);
-
-    match visibility {
-        // Must check stability for `pub` items.
-        ty::Visibility::Public => false,
-
-        // These are not visible outside crate; therefore
-        // stability markers are irrelevant, if even present.
-        ty::Visibility::Restricted(..) | ty::Visibility::Invisible => true,
-    }
-}
-
-impl<'tcx> TyCtxt<'tcx> {
-    /// Evaluates the stability of an item.
-    ///
-    /// Returns `EvalResult::Allow` if the item is stable, or unstable but the corresponding
-    /// `#![feature]` has been provided. Returns `EvalResult::Deny` which describes the offending
-    /// unstable feature otherwise.
-    ///
-    /// If `id` is `Some(_)`, this function will also check if the item at `def_id` has been
-    /// deprecated. If the item is indeed deprecated, we will emit a deprecation lint attached to
-    /// `id`.
-    pub fn eval_stability(self, def_id: DefId, id: Option<HirId>, span: Span) -> EvalResult {
-        // Deprecated attributes apply in-crate and cross-crate.
-        if let Some(id) = id {
-            if let Some(depr_entry) = self.lookup_deprecation_entry(def_id) {
-                let parent_def_id = self.hir().local_def_id(self.hir().get_parent_item(id));
-                let skip = self
-                    .lookup_deprecation_entry(parent_def_id)
-                    .map_or(false, |parent_depr| parent_depr.same_origin(&depr_entry));
-
-                if !skip {
-                    let (message, lint) =
-                        deprecation_message(&depr_entry.attr, &self.def_path_str(def_id));
-                    late_report_deprecation(self, &message, None, lint, span, def_id, id);
-                }
-            };
-        }
-
-        let is_staged_api =
-            self.lookup_stability(DefId { index: CRATE_DEF_INDEX, ..def_id }).is_some();
-        if !is_staged_api {
-            return EvalResult::Allow;
-        }
-
-        let stability = self.lookup_stability(def_id);
-        debug!(
-            "stability: \
-                inspecting def_id={:?} span={:?} of stability={:?}",
-            def_id, span, stability
-        );
-
-        if let Some(id) = id {
-            if let Some(stability) = stability {
-                if let Some(depr) = &stability.rustc_depr {
-                    let (message, lint) =
-                        rustc_deprecation_message(depr, &self.def_path_str(def_id));
-                    late_report_deprecation(
-                        self,
-                        &message,
-                        depr.suggestion,
-                        lint,
-                        span,
-                        def_id,
-                        id,
-                    );
-                }
-            }
-        }
-
-        // Only the cross-crate scenario matters when checking unstable APIs
-        let cross_crate = !def_id.is_local();
-        if !cross_crate {
-            return EvalResult::Allow;
-        }
-
-        // Issue #38412: private items lack stability markers.
-        if skip_stability_check_due_to_privacy(self, def_id) {
-            return EvalResult::Allow;
-        }
-
-        match stability {
-            Some(&Stability {
-                level: attr::Unstable { reason, issue, is_soft }, feature, ..
-            }) => {
-                if span.allows_unstable(feature) {
-                    debug!("stability: skipping span={:?} since it is internal", span);
-                    return EvalResult::Allow;
-                }
-                if self.stability().active_features.contains(&feature) {
-                    return EvalResult::Allow;
-                }
-
-                // When we're compiling the compiler itself we may pull in
-                // crates from crates.io, but those crates may depend on other
-                // crates also pulled in from crates.io. We want to ideally be
-                // able to compile everything without requiring upstream
-                // modifications, so in the case that this looks like a
-                // `rustc_private` crate (e.g., a compiler crate) and we also have
-                // the `-Z force-unstable-if-unmarked` flag present (we're
-                // compiling a compiler crate), then let this missing feature
-                // annotation slide.
-                if feature == sym::rustc_private && issue == NonZeroU32::new(27812) {
-                    if self.sess.opts.debugging_opts.force_unstable_if_unmarked {
-                        return EvalResult::Allow;
-                    }
-                }
-
-                EvalResult::Deny { feature, reason, issue, is_soft }
-            }
-            Some(_) => {
-                // Stable APIs are always ok to call and deprecated APIs are
-                // handled by the lint emitting logic above.
-                EvalResult::Allow
-            }
-            None => EvalResult::Unmarked,
-        }
-    }
-
-    /// Checks if an item is stable or error out.
-    ///
-    /// If the item defined by `def_id` is unstable and the corresponding `#![feature]` does not
-    /// exist, emits an error.
-    ///
-    /// Additionally, this function will also check if the item is deprecated. If so, and `id` is
-    /// not `None`, a deprecated lint attached to `id` will be emitted.
-    pub fn check_stability(self, def_id: DefId, id: Option<HirId>, span: Span) {
-        let soft_handler = |lint, span, msg: &_| {
-            self.struct_span_lint_hir(lint, id.unwrap_or(hir::CRATE_HIR_ID), span, |lint| {
-                lint.build(msg).emit()
-            })
-        };
-        match self.eval_stability(def_id, id, span) {
-            EvalResult::Allow => {}
-            EvalResult::Deny { feature, reason, issue, is_soft } => {
-                report_unstable(self.sess, feature, reason, issue, is_soft, span, soft_handler)
-            }
-            EvalResult::Unmarked => {
-                // The API could be uncallable for other reasons, for example when a private module
-                // was referenced.
-                self.sess.delay_span_bug(span, &format!("encountered unmarked API: {:?}", def_id));
-            }
-        }
-    }
-
-    pub fn lookup_deprecation(self, id: DefId) -> Option<Deprecation> {
-        self.lookup_deprecation_entry(id).map(|depr| depr.attr)
-    }
-}
diff --git a/src/librustc/mir/cache.rs b/src/librustc/mir/cache.rs
deleted file mode 100644
index 00ecc7a7a0a..00000000000
--- a/src/librustc/mir/cache.rs
+++ /dev/null
@@ -1,271 +0,0 @@
-use crate::ich::StableHashingContext;
-use crate::mir::{BasicBlock, BasicBlockData, Body, LocalDecls, Location, Successors};
-use rustc_data_structures::graph::dominators::{dominators, Dominators};
-use rustc_data_structures::graph::{self, GraphPredecessors, GraphSuccessors};
-use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
-use rustc_index::vec::IndexVec;
-use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
-use std::iter;
-use std::ops::{Deref, DerefMut, Index, IndexMut};
-use std::vec::IntoIter;
-
-#[derive(Clone, Debug)]
-pub struct Cache {
-    predecessors: Option<IndexVec<BasicBlock, Vec<BasicBlock>>>,
-}
-
-impl rustc_serialize::Encodable for Cache {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
-        Encodable::encode(&(), s)
-    }
-}
-
-impl rustc_serialize::Decodable for Cache {
-    fn decode<D: Decoder>(d: &mut D) -> Result<Self, D::Error> {
-        Decodable::decode(d).map(|_v: ()| Self::new())
-    }
-}
-
-impl<'a> HashStable<StableHashingContext<'a>> for Cache {
-    fn hash_stable(&self, _: &mut StableHashingContext<'a>, _: &mut StableHasher) {
-        // Do nothing.
-    }
-}
-
-impl Cache {
-    pub fn new() -> Self {
-        Self { predecessors: None }
-    }
-
-    pub fn invalidate_predecessors(&mut self) {
-        // FIXME: consider being more fine-grained
-        self.predecessors = None;
-    }
-
-    pub fn ensure_predecessors(&mut self, body: &Body<'_>) {
-        if self.predecessors.is_none() {
-            let mut result = IndexVec::from_elem(vec![], body.basic_blocks());
-            for (bb, data) in body.basic_blocks().iter_enumerated() {
-                if let Some(ref term) = data.terminator {
-                    for &tgt in term.successors() {
-                        result[tgt].push(bb);
-                    }
-                }
-            }
-
-            self.predecessors = Some(result)
-        }
-    }
-
-    /// This will recompute the predecessors cache if it is not available
-    fn predecessors(&mut self, body: &Body<'_>) -> &IndexVec<BasicBlock, Vec<BasicBlock>> {
-        self.ensure_predecessors(body);
-        self.predecessors.as_ref().unwrap()
-    }
-
-    fn unwrap_predecessors_for(&self, bb: BasicBlock) -> &[BasicBlock] {
-        &self.predecessors.as_ref().unwrap()[bb]
-    }
-
-    fn unwrap_predecessor_locations<'a>(
-        &'a self,
-        loc: Location,
-        body: &'a Body<'a>,
-    ) -> impl Iterator<Item = Location> + 'a {
-        let if_zero_locations = if loc.statement_index == 0 {
-            let predecessor_blocks = self.unwrap_predecessors_for(loc.block);
-            let num_predecessor_blocks = predecessor_blocks.len();
-            Some(
-                (0..num_predecessor_blocks)
-                    .map(move |i| predecessor_blocks[i])
-                    .map(move |bb| body.terminator_loc(bb)),
-            )
-        } else {
-            None
-        };
-
-        let if_not_zero_locations = if loc.statement_index == 0 {
-            None
-        } else {
-            Some(Location { block: loc.block, statement_index: loc.statement_index - 1 })
-        };
-
-        if_zero_locations.into_iter().flatten().chain(if_not_zero_locations)
-    }
-
-    pub fn basic_blocks_mut<'a, 'tcx>(
-        &mut self,
-        body: &'a mut Body<'tcx>,
-    ) -> &'a mut IndexVec<BasicBlock, BasicBlockData<'tcx>> {
-        debug!("bbm: Clearing predecessors cache for body at: {:?}", body.span.data());
-        self.invalidate_predecessors();
-        &mut body.basic_blocks
-    }
-
-    pub fn basic_blocks_and_local_decls_mut<'a, 'tcx>(
-        &mut self,
-        body: &'a mut Body<'tcx>,
-    ) -> (&'a mut IndexVec<BasicBlock, BasicBlockData<'tcx>>, &'a mut LocalDecls<'tcx>) {
-        debug!("bbaldm: Clearing predecessors cache for body at: {:?}", body.span.data());
-        self.invalidate_predecessors();
-        (&mut body.basic_blocks, &mut body.local_decls)
-    }
-}
-
-#[derive(Clone, Debug, HashStable, RustcEncodable, RustcDecodable, TypeFoldable)]
-pub struct BodyAndCache<'tcx> {
-    body: Body<'tcx>,
-    cache: Cache,
-}
-
-impl BodyAndCache<'tcx> {
-    pub fn new(body: Body<'tcx>) -> Self {
-        Self { body, cache: Cache::new() }
-    }
-}
-
-#[macro_export]
-macro_rules! read_only {
-    ($body:expr) => {{
-        $body.ensure_predecessors();
-        $body.unwrap_read_only()
-    }};
-}
-
-impl BodyAndCache<'tcx> {
-    pub fn ensure_predecessors(&mut self) {
-        self.cache.ensure_predecessors(&self.body);
-    }
-
-    pub fn predecessors(&mut self) -> &IndexVec<BasicBlock, Vec<BasicBlock>> {
-        self.cache.predecessors(&self.body)
-    }
-
-    pub fn unwrap_read_only(&self) -> ReadOnlyBodyAndCache<'_, 'tcx> {
-        ReadOnlyBodyAndCache::new(&self.body, &self.cache)
-    }
-
-    pub fn basic_blocks_mut(&mut self) -> &mut IndexVec<BasicBlock, BasicBlockData<'tcx>> {
-        self.cache.basic_blocks_mut(&mut self.body)
-    }
-
-    pub fn basic_blocks_and_local_decls_mut(
-        &mut self,
-    ) -> (&mut IndexVec<BasicBlock, BasicBlockData<'tcx>>, &mut LocalDecls<'tcx>) {
-        self.cache.basic_blocks_and_local_decls_mut(&mut self.body)
-    }
-}
-
-impl<'tcx> Index<BasicBlock> for BodyAndCache<'tcx> {
-    type Output = BasicBlockData<'tcx>;
-
-    fn index(&self, index: BasicBlock) -> &BasicBlockData<'tcx> {
-        &self.body[index]
-    }
-}
-
-impl<'tcx> IndexMut<BasicBlock> for BodyAndCache<'tcx> {
-    fn index_mut(&mut self, index: BasicBlock) -> &mut Self::Output {
-        &mut self.basic_blocks_mut()[index]
-    }
-}
-
-impl<'tcx> Deref for BodyAndCache<'tcx> {
-    type Target = Body<'tcx>;
-
-    fn deref(&self) -> &Self::Target {
-        &self.body
-    }
-}
-
-impl<'tcx> DerefMut for BodyAndCache<'tcx> {
-    fn deref_mut(&mut self) -> &mut Self::Target {
-        &mut self.body
-    }
-}
-
-#[derive(Copy, Clone, Debug)]
-pub struct ReadOnlyBodyAndCache<'a, 'tcx> {
-    body: &'a Body<'tcx>,
-    cache: &'a Cache,
-}
-
-impl ReadOnlyBodyAndCache<'a, 'tcx> {
-    fn new(body: &'a Body<'tcx>, cache: &'a Cache) -> Self {
-        assert!(
-            cache.predecessors.is_some(),
-            "Cannot construct ReadOnlyBodyAndCache without computed predecessors"
-        );
-        Self { body, cache }
-    }
-
-    pub fn predecessors(&self) -> &IndexVec<BasicBlock, Vec<BasicBlock>> {
-        self.cache.predecessors.as_ref().unwrap()
-    }
-
-    pub fn predecessors_for(&self, bb: BasicBlock) -> &[BasicBlock] {
-        self.cache.unwrap_predecessors_for(bb)
-    }
-
-    pub fn predecessor_locations(&self, loc: Location) -> impl Iterator<Item = Location> + '_ {
-        self.cache.unwrap_predecessor_locations(loc, self.body)
-    }
-
-    pub fn basic_blocks(&self) -> &IndexVec<BasicBlock, BasicBlockData<'tcx>> {
-        &self.body.basic_blocks
-    }
-
-    pub fn dominators(&self) -> Dominators<BasicBlock> {
-        dominators(self)
-    }
-}
-
-impl graph::DirectedGraph for ReadOnlyBodyAndCache<'a, 'tcx> {
-    type Node = BasicBlock;
-}
-
-impl graph::GraphPredecessors<'graph> for ReadOnlyBodyAndCache<'a, 'tcx> {
-    type Item = BasicBlock;
-    type Iter = IntoIter<BasicBlock>;
-}
-
-impl graph::WithPredecessors for ReadOnlyBodyAndCache<'a, 'tcx> {
-    fn predecessors(&self, node: Self::Node) -> <Self as GraphPredecessors<'_>>::Iter {
-        self.cache.unwrap_predecessors_for(node).to_vec().into_iter()
-    }
-}
-
-impl graph::WithNumNodes for ReadOnlyBodyAndCache<'a, 'tcx> {
-    fn num_nodes(&self) -> usize {
-        self.body.num_nodes()
-    }
-}
-
-impl graph::WithStartNode for ReadOnlyBodyAndCache<'a, 'tcx> {
-    fn start_node(&self) -> Self::Node {
-        self.body.start_node()
-    }
-}
-
-impl graph::WithSuccessors for ReadOnlyBodyAndCache<'a, 'tcx> {
-    fn successors(&self, node: Self::Node) -> <Self as GraphSuccessors<'_>>::Iter {
-        self.body.successors(node)
-    }
-}
-
-impl<'a, 'b, 'tcx> graph::GraphSuccessors<'b> for ReadOnlyBodyAndCache<'a, 'tcx> {
-    type Item = BasicBlock;
-    type Iter = iter::Cloned<Successors<'b>>;
-}
-
-impl Deref for ReadOnlyBodyAndCache<'a, 'tcx> {
-    type Target = &'a Body<'tcx>;
-
-    fn deref(&self) -> &Self::Target {
-        &self.body
-    }
-}
-
-CloneTypeFoldableAndLiftImpls! {
-    Cache,
-}
diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs
deleted file mode 100644
index 052603f6e5e..00000000000
--- a/src/librustc/mir/interpret/allocation.rs
+++ /dev/null
@@ -1,906 +0,0 @@
-//! The virtual memory representation of the MIR interpreter.
-
-use super::{
-    read_target_uint, write_target_uint, AllocId, InterpResult, Pointer, Scalar, ScalarMaybeUndef,
-};
-
-use crate::ty::layout::{Align, Size};
-
-use rustc_data_structures::sorted_map::SortedMap;
-use rustc_target::abi::HasDataLayout;
-use std::borrow::Cow;
-use std::iter;
-use std::ops::{Deref, DerefMut, Range};
-use syntax::ast::Mutability;
-
-// NOTE: When adding new fields, make sure to adjust the `Snapshot` impl in
-// `src/librustc_mir/interpret/snapshot.rs`.
-#[derive(
-    Clone,
-    Debug,
-    Eq,
-    PartialEq,
-    PartialOrd,
-    Ord,
-    Hash,
-    RustcEncodable,
-    RustcDecodable,
-    HashStable
-)]
-pub struct Allocation<Tag = (), Extra = ()> {
-    /// The actual bytes of the allocation.
-    /// Note that the bytes of a pointer represent the offset of the pointer.
-    bytes: Vec<u8>,
-    /// Maps from byte addresses to extra data for each pointer.
-    /// Only the first byte of a pointer is inserted into the map; i.e.,
-    /// every entry in this map applies to `pointer_size` consecutive bytes starting
-    /// at the given offset.
-    relocations: Relocations<Tag>,
-    /// Denotes which part of this allocation is initialized.
-    undef_mask: UndefMask,
-    /// The size of the allocation. Currently, must always equal `bytes.len()`.
-    pub size: Size,
-    /// The alignment of the allocation to detect unaligned reads.
-    pub align: Align,
-    /// `true` if the allocation is mutable.
-    /// Also used by codegen to determine if a static should be put into mutable memory,
-    /// which happens for `static mut` and `static` with interior mutability.
-    pub mutability: Mutability,
-    /// Extra state for the machine.
-    pub extra: Extra,
-}
-
-pub trait AllocationExtra<Tag>: ::std::fmt::Debug + Clone {
-    // There is no constructor in here because the constructor's type depends
-    // on `MemoryKind`, and making things sufficiently generic leads to painful
-    // inference failure.
-
-    /// Hook for performing extra checks on a memory read access.
-    ///
-    /// Takes read-only access to the allocation so we can keep all the memory read
-    /// operations take `&self`. Use a `RefCell` in `AllocExtra` if you
-    /// need to mutate.
-    #[inline(always)]
-    fn memory_read(
-        _alloc: &Allocation<Tag, Self>,
-        _ptr: Pointer<Tag>,
-        _size: Size,
-    ) -> InterpResult<'tcx> {
-        Ok(())
-    }
-
-    /// Hook for performing extra checks on a memory write access.
-    #[inline(always)]
-    fn memory_written(
-        _alloc: &mut Allocation<Tag, Self>,
-        _ptr: Pointer<Tag>,
-        _size: Size,
-    ) -> InterpResult<'tcx> {
-        Ok(())
-    }
-
-    /// Hook for performing extra checks on a memory deallocation.
-    /// `size` will be the size of the allocation.
-    #[inline(always)]
-    fn memory_deallocated(
-        _alloc: &mut Allocation<Tag, Self>,
-        _ptr: Pointer<Tag>,
-        _size: Size,
-    ) -> InterpResult<'tcx> {
-        Ok(())
-    }
-}
-
-// For `Tag = ()` and no extra state, we have a trivial implementation.
-impl AllocationExtra<()> for () {}
-
-// The constructors are all without extra; the extra gets added by a machine hook later.
-impl<Tag> Allocation<Tag> {
-    /// Creates a read-only allocation initialized by the given bytes
-    pub fn from_bytes<'a>(slice: impl Into<Cow<'a, [u8]>>, align: Align) -> Self {
-        let bytes = slice.into().into_owned();
-        let size = Size::from_bytes(bytes.len() as u64);
-        Self {
-            bytes,
-            relocations: Relocations::new(),
-            undef_mask: UndefMask::new(size, true),
-            size,
-            align,
-            mutability: Mutability::Not,
-            extra: (),
-        }
-    }
-
-    pub fn from_byte_aligned_bytes<'a>(slice: impl Into<Cow<'a, [u8]>>) -> Self {
-        Allocation::from_bytes(slice, Align::from_bytes(1).unwrap())
-    }
-
-    pub fn undef(size: Size, align: Align) -> Self {
-        assert_eq!(size.bytes() as usize as u64, size.bytes());
-        Allocation {
-            bytes: vec![0; size.bytes() as usize],
-            relocations: Relocations::new(),
-            undef_mask: UndefMask::new(size, false),
-            size,
-            align,
-            mutability: Mutability::Mut,
-            extra: (),
-        }
-    }
-}
-
-impl Allocation<(), ()> {
-    /// Add Tag and Extra fields
-    pub fn with_tags_and_extra<T, E>(
-        self,
-        mut tagger: impl FnMut(AllocId) -> T,
-        extra: E,
-    ) -> Allocation<T, E> {
-        Allocation {
-            bytes: self.bytes,
-            size: self.size,
-            relocations: Relocations::from_presorted(
-                self.relocations
-                    .iter()
-                    // The allocations in the relocations (pointers stored *inside* this allocation)
-                    // all get the base pointer tag.
-                    .map(|&(offset, ((), alloc))| {
-                        let tag = tagger(alloc);
-                        (offset, (tag, alloc))
-                    })
-                    .collect(),
-            ),
-            undef_mask: self.undef_mask,
-            align: self.align,
-            mutability: self.mutability,
-            extra,
-        }
-    }
-}
-
-/// Raw accessors. Provide access to otherwise private bytes.
-impl<Tag, Extra> Allocation<Tag, Extra> {
-    pub fn len(&self) -> usize {
-        self.size.bytes() as usize
-    }
-
-    /// Looks at a slice which may describe undefined bytes or describe a relocation. This differs
-    /// from `get_bytes_with_undef_and_ptr` in that it does no relocation checks (even on the
-    /// edges) at all. It further ignores `AllocationExtra` callbacks.
-    /// This must not be used for reads affecting the interpreter execution.
-    pub fn inspect_with_undef_and_ptr_outside_interpreter(&self, range: Range<usize>) -> &[u8] {
-        &self.bytes[range]
-    }
-
-    /// Returns the undef mask.
-    pub fn undef_mask(&self) -> &UndefMask {
-        &self.undef_mask
-    }
-
-    /// Returns the relocation list.
-    pub fn relocations(&self) -> &Relocations<Tag> {
-        &self.relocations
-    }
-}
-
-impl<'tcx> rustc_serialize::UseSpecializedDecodable for &'tcx Allocation {}
-
-/// Byte accessors.
-impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
-    /// Just a small local helper function to avoid a bit of code repetition.
-    /// Returns the range of this allocation that was meant.
-    #[inline]
-    fn check_bounds(&self, offset: Size, size: Size) -> Range<usize> {
-        let end = offset + size; // This does overflow checking.
-        assert_eq!(
-            end.bytes() as usize as u64,
-            end.bytes(),
-            "cannot handle this access on this host architecture"
-        );
-        let end = end.bytes() as usize;
-        assert!(
-            end <= self.len(),
-            "Out-of-bounds access at offset {}, size {} in allocation of size {}",
-            offset.bytes(),
-            size.bytes(),
-            self.len()
-        );
-        (offset.bytes() as usize)..end
-    }
-
-    /// The last argument controls whether we error out when there are undefined
-    /// or pointer bytes. You should never call this, call `get_bytes` or
-    /// `get_bytes_with_undef_and_ptr` instead,
-    ///
-    /// This function also guarantees that the resulting pointer will remain stable
-    /// even when new allocations are pushed to the `HashMap`. `copy_repeatedly` relies
-    /// on that.
-    ///
-    /// It is the caller's responsibility to check bounds and alignment beforehand.
-    fn get_bytes_internal(
-        &self,
-        cx: &impl HasDataLayout,
-        ptr: Pointer<Tag>,
-        size: Size,
-        check_defined_and_ptr: bool,
-    ) -> InterpResult<'tcx, &[u8]> {
-        let range = self.check_bounds(ptr.offset, size);
-
-        if check_defined_and_ptr {
-            self.check_defined(ptr, size)?;
-            self.check_relocations(cx, ptr, size)?;
-        } else {
-            // We still don't want relocations on the *edges*.
-            self.check_relocation_edges(cx, ptr, size)?;
-        }
-
-        AllocationExtra::memory_read(self, ptr, size)?;
-
-        Ok(&self.bytes[range])
-    }
-
-    /// Checks that these bytes are initialized and not pointer bytes, and then return them
-    /// as a slice.
-    ///
-    /// It is the caller's responsibility to check bounds and alignment beforehand.
-    /// Most likely, you want to use the `PlaceTy` and `OperandTy`-based methods
-    /// on `InterpCx` instead.
-    #[inline]
-    pub fn get_bytes(
-        &self,
-        cx: &impl HasDataLayout,
-        ptr: Pointer<Tag>,
-        size: Size,
-    ) -> InterpResult<'tcx, &[u8]> {
-        self.get_bytes_internal(cx, ptr, size, true)
-    }
-
-    /// It is the caller's responsibility to handle undefined and pointer bytes.
-    /// However, this still checks that there are no relocations on the *edges*.
-    ///
-    /// It is the caller's responsibility to check bounds and alignment beforehand.
-    #[inline]
-    pub fn get_bytes_with_undef_and_ptr(
-        &self,
-        cx: &impl HasDataLayout,
-        ptr: Pointer<Tag>,
-        size: Size,
-    ) -> InterpResult<'tcx, &[u8]> {
-        self.get_bytes_internal(cx, ptr, size, false)
-    }
-
-    /// Just calling this already marks everything as defined and removes relocations,
-    /// so be sure to actually put data there!
-    ///
-    /// It is the caller's responsibility to check bounds and alignment beforehand.
-    /// Most likely, you want to use the `PlaceTy` and `OperandTy`-based methods
-    /// on `InterpCx` instead.
-    pub fn get_bytes_mut(
-        &mut self,
-        cx: &impl HasDataLayout,
-        ptr: Pointer<Tag>,
-        size: Size,
-    ) -> InterpResult<'tcx, &mut [u8]> {
-        let range = self.check_bounds(ptr.offset, size);
-
-        self.mark_definedness(ptr, size, true);
-        self.clear_relocations(cx, ptr, size)?;
-
-        AllocationExtra::memory_written(self, ptr, size)?;
-
-        Ok(&mut self.bytes[range])
-    }
-}
-
-/// Reading and writing.
-impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
-    /// Reads bytes until a `0` is encountered. Will error if the end of the allocation is reached
-    /// before a `0` is found.
-    ///
-    /// Most likely, you want to call `Memory::read_c_str` instead of this method.
-    pub fn read_c_str(
-        &self,
-        cx: &impl HasDataLayout,
-        ptr: Pointer<Tag>,
-    ) -> InterpResult<'tcx, &[u8]> {
-        assert_eq!(ptr.offset.bytes() as usize as u64, ptr.offset.bytes());
-        let offset = ptr.offset.bytes() as usize;
-        Ok(match self.bytes[offset..].iter().position(|&c| c == 0) {
-            Some(size) => {
-                let size_with_null = Size::from_bytes((size + 1) as u64);
-                // Go through `get_bytes` for checks and AllocationExtra hooks.
-                // We read the null, so we include it in the request, but we want it removed
-                // from the result, so we do subslicing.
-                &self.get_bytes(cx, ptr, size_with_null)?[..size]
-            }
-            // This includes the case where `offset` is out-of-bounds to begin with.
-            None => throw_unsup!(UnterminatedCString(ptr.erase_tag())),
-        })
-    }
-
-    /// Validates that `ptr.offset` and `ptr.offset + size` do not point to the middle of a
-    /// relocation. If `allow_ptr_and_undef` is `false`, also enforces that the memory in the
-    /// given range contains neither relocations nor undef bytes.
-    pub fn check_bytes(
-        &self,
-        cx: &impl HasDataLayout,
-        ptr: Pointer<Tag>,
-        size: Size,
-        allow_ptr_and_undef: bool,
-    ) -> InterpResult<'tcx> {
-        // Check bounds and relocations on the edges.
-        self.get_bytes_with_undef_and_ptr(cx, ptr, size)?;
-        // Check undef and ptr.
-        if !allow_ptr_and_undef {
-            self.check_defined(ptr, size)?;
-            self.check_relocations(cx, ptr, size)?;
-        }
-        Ok(())
-    }
-
-    /// Writes `src` to the memory starting at `ptr.offset`.
-    ///
-    /// It is the caller's responsibility to check bounds and alignment beforehand.
-    /// Most likely, you want to call `Memory::write_bytes` instead of this method.
-    pub fn write_bytes(
-        &mut self,
-        cx: &impl HasDataLayout,
-        ptr: Pointer<Tag>,
-        src: impl IntoIterator<Item = u8>,
-    ) -> InterpResult<'tcx> {
-        let mut src = src.into_iter();
-        let (lower, upper) = src.size_hint();
-        let len = upper.expect("can only write bounded iterators");
-        assert_eq!(lower, len, "can only write iterators with a precise length");
-        let bytes = self.get_bytes_mut(cx, ptr, Size::from_bytes(len as u64))?;
-        // `zip` would stop when the first iterator ends; we want to definitely
-        // cover all of `bytes`.
-        for dest in bytes {
-            *dest = src.next().expect("iterator was shorter than it said it would be");
-        }
-        src.next().expect_none("iterator was longer than it said it would be");
-        Ok(())
-    }
-
-    /// Reads a *non-ZST* scalar.
-    ///
-    /// ZSTs can't be read for two reasons:
-    /// * byte-order cannot work with zero-element buffers;
-    /// * in order to obtain a `Pointer`, we need to check for ZSTness anyway due to integer
-    ///   pointers being valid for ZSTs.
-    ///
-    /// It is the caller's responsibility to check bounds and alignment beforehand.
-    /// Most likely, you want to call `InterpCx::read_scalar` instead of this method.
-    pub fn read_scalar(
-        &self,
-        cx: &impl HasDataLayout,
-        ptr: Pointer<Tag>,
-        size: Size,
-    ) -> InterpResult<'tcx, ScalarMaybeUndef<Tag>> {
-        // `get_bytes_unchecked` tests relocation edges.
-        let bytes = self.get_bytes_with_undef_and_ptr(cx, ptr, size)?;
-        // Undef check happens *after* we established that the alignment is correct.
-        // We must not return `Ok()` for unaligned pointers!
-        if self.check_defined(ptr, size).is_err() {
-            // This inflates undefined bytes to the entire scalar, even if only a few
-            // bytes are undefined.
-            return Ok(ScalarMaybeUndef::Undef);
-        }
-        // Now we do the actual reading.
-        let bits = read_target_uint(cx.data_layout().endian, bytes).unwrap();
-        // See if we got a pointer.
-        if size != cx.data_layout().pointer_size {
-            // *Now*, we better make sure that the inside is free of relocations too.
-            self.check_relocations(cx, ptr, size)?;
-        } else {
-            match self.relocations.get(&ptr.offset) {
-                Some(&(tag, alloc_id)) => {
-                    let ptr = Pointer::new_with_tag(alloc_id, Size::from_bytes(bits as u64), tag);
-                    return Ok(ScalarMaybeUndef::Scalar(ptr.into()));
-                }
-                None => {}
-            }
-        }
-        // We don't. Just return the bits.
-        Ok(ScalarMaybeUndef::Scalar(Scalar::from_uint(bits, size)))
-    }
-
-    /// Reads a pointer-sized scalar.
-    ///
-    /// It is the caller's responsibility to check bounds and alignment beforehand.
-    /// Most likely, you want to call `InterpCx::read_scalar` instead of this method.
-    pub fn read_ptr_sized(
-        &self,
-        cx: &impl HasDataLayout,
-        ptr: Pointer<Tag>,
-    ) -> InterpResult<'tcx, ScalarMaybeUndef<Tag>> {
-        self.read_scalar(cx, ptr, cx.data_layout().pointer_size)
-    }
-
-    /// Writes a *non-ZST* scalar.
-    ///
-    /// ZSTs can't be read for two reasons:
-    /// * byte-order cannot work with zero-element buffers;
-    /// * in order to obtain a `Pointer`, we need to check for ZSTness anyway due to integer
-    ///   pointers being valid for ZSTs.
-    ///
-    /// It is the caller's responsibility to check bounds and alignment beforehand.
-    /// Most likely, you want to call `InterpCx::write_scalar` instead of this method.
-    pub fn write_scalar(
-        &mut self,
-        cx: &impl HasDataLayout,
-        ptr: Pointer<Tag>,
-        val: ScalarMaybeUndef<Tag>,
-        type_size: Size,
-    ) -> InterpResult<'tcx> {
-        let val = match val {
-            ScalarMaybeUndef::Scalar(scalar) => scalar,
-            ScalarMaybeUndef::Undef => {
-                self.mark_definedness(ptr, type_size, false);
-                return Ok(());
-            }
-        };
-
-        let bytes = match val.to_bits_or_ptr(type_size, cx) {
-            Err(val) => val.offset.bytes() as u128,
-            Ok(data) => data,
-        };
-
-        let endian = cx.data_layout().endian;
-        let dst = self.get_bytes_mut(cx, ptr, type_size)?;
-        write_target_uint(endian, dst, bytes).unwrap();
-
-        // See if we have to also write a relocation.
-        match val {
-            Scalar::Ptr(val) => {
-                self.relocations.insert(ptr.offset, (val.tag, val.alloc_id));
-            }
-            _ => {}
-        }
-
-        Ok(())
-    }
-
-    /// Writes a pointer-sized scalar.
-    ///
-    /// It is the caller's responsibility to check bounds and alignment beforehand.
-    /// Most likely, you want to call `InterpCx::write_scalar` instead of this method.
-    pub fn write_ptr_sized(
-        &mut self,
-        cx: &impl HasDataLayout,
-        ptr: Pointer<Tag>,
-        val: ScalarMaybeUndef<Tag>,
-    ) -> InterpResult<'tcx> {
-        let ptr_size = cx.data_layout().pointer_size;
-        self.write_scalar(cx, ptr.into(), val, ptr_size)
-    }
-}
-
-/// Relocations.
-impl<'tcx, Tag: Copy, Extra> Allocation<Tag, Extra> {
-    /// Returns all relocations overlapping with the given pointer-offset pair.
-    pub fn get_relocations(
-        &self,
-        cx: &impl HasDataLayout,
-        ptr: Pointer<Tag>,
-        size: Size,
-    ) -> &[(Size, (Tag, AllocId))] {
-        // We have to go back `pointer_size - 1` bytes, as that one would still overlap with
-        // the beginning of this range.
-        let start = ptr.offset.bytes().saturating_sub(cx.data_layout().pointer_size.bytes() - 1);
-        let end = ptr.offset + size; // This does overflow checking.
-        self.relocations.range(Size::from_bytes(start)..end)
-    }
-
-    /// Checks that there are no relocations overlapping with the given range.
-    #[inline(always)]
-    fn check_relocations(
-        &self,
-        cx: &impl HasDataLayout,
-        ptr: Pointer<Tag>,
-        size: Size,
-    ) -> InterpResult<'tcx> {
-        if self.get_relocations(cx, ptr, size).is_empty() {
-            Ok(())
-        } else {
-            throw_unsup!(ReadPointerAsBytes)
-        }
-    }
-
-    /// Removes all relocations inside the given range.
-    /// If there are relocations overlapping with the edges, they
-    /// are removed as well *and* the bytes they cover are marked as
-    /// uninitialized. This is a somewhat odd "spooky action at a distance",
-    /// but it allows strictly more code to run than if we would just error
-    /// immediately in that case.
-    fn clear_relocations(
-        &mut self,
-        cx: &impl HasDataLayout,
-        ptr: Pointer<Tag>,
-        size: Size,
-    ) -> InterpResult<'tcx> {
-        // Find the start and end of the given range and its outermost relocations.
-        let (first, last) = {
-            // Find all relocations overlapping the given range.
-            let relocations = self.get_relocations(cx, ptr, size);
-            if relocations.is_empty() {
-                return Ok(());
-            }
-
-            (
-                relocations.first().unwrap().0,
-                relocations.last().unwrap().0 + cx.data_layout().pointer_size,
-            )
-        };
-        let start = ptr.offset;
-        let end = start + size;
-
-        // Mark parts of the outermost relocations as undefined if they partially fall outside the
-        // given range.
-        if first < start {
-            self.undef_mask.set_range(first, start, false);
-        }
-        if last > end {
-            self.undef_mask.set_range(end, last, false);
-        }
-
-        // Forget all the relocations.
-        self.relocations.remove_range(first..last);
-
-        Ok(())
-    }
-
-    /// Errors if there are relocations overlapping with the edges of the
-    /// given memory range.
-    #[inline]
-    fn check_relocation_edges(
-        &self,
-        cx: &impl HasDataLayout,
-        ptr: Pointer<Tag>,
-        size: Size,
-    ) -> InterpResult<'tcx> {
-        self.check_relocations(cx, ptr, Size::ZERO)?;
-        self.check_relocations(cx, ptr.offset(size, cx)?, Size::ZERO)?;
-        Ok(())
-    }
-}
-
-/// Undefined bytes.
-impl<'tcx, Tag, Extra> Allocation<Tag, Extra> {
-    /// Checks that a range of bytes is defined. If not, returns the `ReadUndefBytes`
-    /// error which will report the first byte which is undefined.
-    #[inline]
-    fn check_defined(&self, ptr: Pointer<Tag>, size: Size) -> InterpResult<'tcx> {
-        self.undef_mask
-            .is_range_defined(ptr.offset, ptr.offset + size)
-            .or_else(|idx| throw_unsup!(ReadUndefBytes(idx)))
-    }
-
-    pub fn mark_definedness(&mut self, ptr: Pointer<Tag>, size: Size, new_state: bool) {
-        if size.bytes() == 0 {
-            return;
-        }
-        self.undef_mask.set_range(ptr.offset, ptr.offset + size, new_state);
-    }
-}
-
-/// Run-length encoding of the undef mask.
-/// Used to copy parts of a mask multiple times to another allocation.
-pub struct AllocationDefinedness {
-    /// The definedness of the first range.
-    initial: bool,
-    /// The lengths of ranges that are run-length encoded.
-    /// The definedness of the ranges alternate starting with `initial`.
-    ranges: smallvec::SmallVec<[u64; 1]>,
-}
-
-impl AllocationDefinedness {
-    pub fn all_bytes_undef(&self) -> bool {
-        // The `ranges` are run-length encoded and of alternating definedness.
-        // So if `ranges.len() > 1` then the second block is a range of defined.
-        !self.initial && self.ranges.len() == 1
-    }
-}
-
-/// Transferring the definedness mask to other allocations.
-impl<Tag, Extra> Allocation<Tag, Extra> {
-    /// Creates a run-length encoding of the undef mask.
-    pub fn compress_undef_range(&self, src: Pointer<Tag>, size: Size) -> AllocationDefinedness {
-        // Since we are copying `size` bytes from `src` to `dest + i * size` (`for i in 0..repeat`),
-        // a naive undef mask copying algorithm would repeatedly have to read the undef mask from
-        // the source and write it to the destination. Even if we optimized the memory accesses,
-        // we'd be doing all of this `repeat` times.
-        // Therefor we precompute a compressed version of the undef mask of the source value and
-        // then write it back `repeat` times without computing any more information from the source.
-
-        // A precomputed cache for ranges of defined/undefined bits
-        // 0000010010001110 will become
-        // `[5, 1, 2, 1, 3, 3, 1]`,
-        // where each element toggles the state.
-
-        let mut ranges = smallvec::SmallVec::<[u64; 1]>::new();
-        let initial = self.undef_mask.get(src.offset);
-        let mut cur_len = 1;
-        let mut cur = initial;
-
-        for i in 1..size.bytes() {
-            // FIXME: optimize to bitshift the current undef block's bits and read the top bit.
-            if self.undef_mask.get(src.offset + Size::from_bytes(i)) == cur {
-                cur_len += 1;
-            } else {
-                ranges.push(cur_len);
-                cur_len = 1;
-                cur = !cur;
-            }
-        }
-
-        ranges.push(cur_len);
-
-        AllocationDefinedness { ranges, initial }
-    }
-
-    /// Applies multiple instances of the run-length encoding to the undef mask.
-    pub fn mark_compressed_undef_range(
-        &mut self,
-        defined: &AllocationDefinedness,
-        dest: Pointer<Tag>,
-        size: Size,
-        repeat: u64,
-    ) {
-        // An optimization where we can just overwrite an entire range of definedness bits if
-        // they are going to be uniformly `1` or `0`.
-        if defined.ranges.len() <= 1 {
-            self.undef_mask.set_range_inbounds(
-                dest.offset,
-                dest.offset + size * repeat,
-                defined.initial,
-            );
-            return;
-        }
-
-        for mut j in 0..repeat {
-            j *= size.bytes();
-            j += dest.offset.bytes();
-            let mut cur = defined.initial;
-            for range in &defined.ranges {
-                let old_j = j;
-                j += range;
-                self.undef_mask.set_range_inbounds(
-                    Size::from_bytes(old_j),
-                    Size::from_bytes(j),
-                    cur,
-                );
-                cur = !cur;
-            }
-        }
-    }
-}
-
-/// Relocations.
-#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
-pub struct Relocations<Tag = (), Id = AllocId>(SortedMap<Size, (Tag, Id)>);
-
-impl<Tag, Id> Relocations<Tag, Id> {
-    pub fn new() -> Self {
-        Relocations(SortedMap::new())
-    }
-
-    // The caller must guarantee that the given relocations are already sorted
-    // by address and contain no duplicates.
-    pub fn from_presorted(r: Vec<(Size, (Tag, Id))>) -> Self {
-        Relocations(SortedMap::from_presorted_elements(r))
-    }
-}
-
-impl<Tag> Deref for Relocations<Tag> {
-    type Target = SortedMap<Size, (Tag, AllocId)>;
-
-    fn deref(&self) -> &Self::Target {
-        &self.0
-    }
-}
-
-impl<Tag> DerefMut for Relocations<Tag> {
-    fn deref_mut(&mut self) -> &mut Self::Target {
-        &mut self.0
-    }
-}
-
-/// A partial, owned list of relocations to transfer into another allocation.
-pub struct AllocationRelocations<Tag> {
-    relative_relocations: Vec<(Size, (Tag, AllocId))>,
-}
-
-impl<Tag: Copy, Extra> Allocation<Tag, Extra> {
-    pub fn prepare_relocation_copy(
-        &self,
-        cx: &impl HasDataLayout,
-        src: Pointer<Tag>,
-        size: Size,
-        dest: Pointer<Tag>,
-        length: u64,
-    ) -> AllocationRelocations<Tag> {
-        let relocations = self.get_relocations(cx, src, size);
-        if relocations.is_empty() {
-            return AllocationRelocations { relative_relocations: Vec::new() };
-        }
-
-        let mut new_relocations = Vec::with_capacity(relocations.len() * (length as usize));
-
-        for i in 0..length {
-            new_relocations.extend(relocations.iter().map(|&(offset, reloc)| {
-                // compute offset for current repetition
-                let dest_offset = dest.offset + (i * size);
-                (
-                    // shift offsets from source allocation to destination allocation
-                    offset + dest_offset - src.offset,
-                    reloc,
-                )
-            }));
-        }
-
-        AllocationRelocations { relative_relocations: new_relocations }
-    }
-
-    /// Applies a relocation copy.
-    /// The affected range, as defined in the parameters to `prepare_relocation_copy` is expected
-    /// to be clear of relocations.
-    pub fn mark_relocation_range(&mut self, relocations: AllocationRelocations<Tag>) {
-        self.relocations.insert_presorted(relocations.relative_relocations);
-    }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Undefined byte tracking
-////////////////////////////////////////////////////////////////////////////////
-
-type Block = u64;
-
-/// A bitmask where each bit refers to the byte with the same index. If the bit is `true`, the byte
-/// is defined. If it is `false` the byte is undefined.
-#[derive(
-    Clone,
-    Debug,
-    Eq,
-    PartialEq,
-    PartialOrd,
-    Ord,
-    Hash,
-    RustcEncodable,
-    RustcDecodable,
-    HashStable
-)]
-pub struct UndefMask {
-    blocks: Vec<Block>,
-    len: Size,
-}
-
-impl UndefMask {
-    pub const BLOCK_SIZE: u64 = 64;
-
-    pub fn new(size: Size, state: bool) -> Self {
-        let mut m = UndefMask { blocks: vec![], len: Size::ZERO };
-        m.grow(size, state);
-        m
-    }
-
-    /// Checks whether the range `start..end` (end-exclusive) is entirely defined.
-    ///
-    /// Returns `Ok(())` if it's defined. Otherwise returns the index of the byte
-    /// at which the first undefined access begins.
-    #[inline]
-    pub fn is_range_defined(&self, start: Size, end: Size) -> Result<(), Size> {
-        if end > self.len {
-            return Err(self.len);
-        }
-
-        // FIXME(oli-obk): optimize this for allocations larger than a block.
-        let idx = (start.bytes()..end.bytes()).map(|i| Size::from_bytes(i)).find(|&i| !self.get(i));
-
-        match idx {
-            Some(idx) => Err(idx),
-            None => Ok(()),
-        }
-    }
-
-    pub fn set_range(&mut self, start: Size, end: Size, new_state: bool) {
-        let len = self.len;
-        if end > len {
-            self.grow(end - len, new_state);
-        }
-        self.set_range_inbounds(start, end, new_state);
-    }
-
-    pub fn set_range_inbounds(&mut self, start: Size, end: Size, new_state: bool) {
-        let (blocka, bita) = bit_index(start);
-        let (blockb, bitb) = bit_index(end);
-        if blocka == blockb {
-            // First set all bits except the first `bita`,
-            // then unset the last `64 - bitb` bits.
-            let range = if bitb == 0 {
-                u64::max_value() << bita
-            } else {
-                (u64::max_value() << bita) & (u64::max_value() >> (64 - bitb))
-            };
-            if new_state {
-                self.blocks[blocka] |= range;
-            } else {
-                self.blocks[blocka] &= !range;
-            }
-            return;
-        }
-        // across block boundaries
-        if new_state {
-            // Set `bita..64` to `1`.
-            self.blocks[blocka] |= u64::max_value() << bita;
-            // Set `0..bitb` to `1`.
-            if bitb != 0 {
-                self.blocks[blockb] |= u64::max_value() >> (64 - bitb);
-            }
-            // Fill in all the other blocks (much faster than one bit at a time).
-            for block in (blocka + 1)..blockb {
-                self.blocks[block] = u64::max_value();
-            }
-        } else {
-            // Set `bita..64` to `0`.
-            self.blocks[blocka] &= !(u64::max_value() << bita);
-            // Set `0..bitb` to `0`.
-            if bitb != 0 {
-                self.blocks[blockb] &= !(u64::max_value() >> (64 - bitb));
-            }
-            // Fill in all the other blocks (much faster than one bit at a time).
-            for block in (blocka + 1)..blockb {
-                self.blocks[block] = 0;
-            }
-        }
-    }
-
-    #[inline]
-    pub fn get(&self, i: Size) -> bool {
-        let (block, bit) = bit_index(i);
-        (self.blocks[block] & (1 << bit)) != 0
-    }
-
-    #[inline]
-    pub fn set(&mut self, i: Size, new_state: bool) {
-        let (block, bit) = bit_index(i);
-        self.set_bit(block, bit, new_state);
-    }
-
-    #[inline]
-    fn set_bit(&mut self, block: usize, bit: usize, new_state: bool) {
-        if new_state {
-            self.blocks[block] |= 1 << bit;
-        } else {
-            self.blocks[block] &= !(1 << bit);
-        }
-    }
-
-    pub fn grow(&mut self, amount: Size, new_state: bool) {
-        if amount.bytes() == 0 {
-            return;
-        }
-        let unused_trailing_bits = self.blocks.len() as u64 * Self::BLOCK_SIZE - self.len.bytes();
-        if amount.bytes() > unused_trailing_bits {
-            let additional_blocks = amount.bytes() / Self::BLOCK_SIZE + 1;
-            assert_eq!(additional_blocks as usize as u64, additional_blocks);
-            self.blocks.extend(
-                // FIXME(oli-obk): optimize this by repeating `new_state as Block`.
-                iter::repeat(0).take(additional_blocks as usize),
-            );
-        }
-        let start = self.len;
-        self.len += amount;
-        self.set_range_inbounds(start, start + amount, new_state);
-    }
-}
-
-#[inline]
-fn bit_index(bits: Size) -> (usize, usize) {
-    let bits = bits.bytes();
-    let a = bits / UndefMask::BLOCK_SIZE;
-    let b = bits % UndefMask::BLOCK_SIZE;
-    assert_eq!(a as usize as u64, a);
-    assert_eq!(b as usize as u64, b);
-    (a as usize, b as usize)
-}
diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs
deleted file mode 100644
index a23ff6bd66d..00000000000
--- a/src/librustc/mir/interpret/error.rs
+++ /dev/null
@@ -1,614 +0,0 @@
-use super::{CheckInAllocMsg, Pointer, RawConst, ScalarMaybeUndef};
-
-use crate::hir::map::definitions::DefPathData;
-use crate::mir;
-use crate::mir::interpret::ConstValue;
-use crate::ty::layout::{Align, LayoutError, Size};
-use crate::ty::query::TyCtxtAt;
-use crate::ty::{self, layout, Ty};
-
-use backtrace::Backtrace;
-use rustc_errors::{struct_span_err, DiagnosticBuilder};
-use rustc_hir as hir;
-use rustc_macros::HashStable;
-use rustc_span::{Pos, Span};
-use rustc_target::spec::abi::Abi;
-use std::{any::Any, env, fmt};
-
-#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, RustcEncodable, RustcDecodable)]
-pub enum ErrorHandled {
-    /// Already reported a lint or an error for this evaluation.
-    Reported,
-    /// Don't emit an error, the evaluation failed because the MIR was generic
-    /// and the substs didn't fully monomorphize it.
-    TooGeneric,
-}
-
-impl ErrorHandled {
-    pub fn assert_reported(self) {
-        match self {
-            ErrorHandled::Reported => {}
-            ErrorHandled::TooGeneric => bug!(
-                "MIR interpretation failed without reporting an error \
-                 even though it was fully monomorphized"
-            ),
-        }
-    }
-}
-
-CloneTypeFoldableImpls! {
-    ErrorHandled,
-}
-
-pub type ConstEvalRawResult<'tcx> = Result<RawConst<'tcx>, ErrorHandled>;
-pub type ConstEvalResult<'tcx> = Result<ConstValue<'tcx>, ErrorHandled>;
-
-#[derive(Debug)]
-pub struct ConstEvalErr<'tcx> {
-    pub span: Span,
-    pub error: crate::mir::interpret::InterpError<'tcx>,
-    pub stacktrace: Vec<FrameInfo<'tcx>>,
-}
-
-#[derive(Debug)]
-pub struct FrameInfo<'tcx> {
-    /// This span is in the caller.
-    pub call_site: Span,
-    pub instance: ty::Instance<'tcx>,
-    pub lint_root: Option<hir::HirId>,
-}
-
-impl<'tcx> fmt::Display for FrameInfo<'tcx> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        ty::tls::with(|tcx| {
-            if tcx.def_key(self.instance.def_id()).disambiguated_data.data
-                == DefPathData::ClosureExpr
-            {
-                write!(f, "inside call to closure")?;
-            } else {
-                write!(f, "inside call to `{}`", self.instance)?;
-            }
-            if !self.call_site.is_dummy() {
-                let lo = tcx.sess.source_map().lookup_char_pos(self.call_site.lo());
-                write!(f, " at {}:{}:{}", lo.file.name, lo.line, lo.col.to_usize() + 1)?;
-            }
-            Ok(())
-        })
-    }
-}
-
-impl<'tcx> ConstEvalErr<'tcx> {
-    pub fn struct_error(
-        &self,
-        tcx: TyCtxtAt<'tcx>,
-        message: &str,
-        emit: impl FnOnce(DiagnosticBuilder<'_>),
-    ) -> Result<(), ErrorHandled> {
-        self.struct_generic(tcx, message, emit, None)
-    }
-
-    pub fn report_as_error(&self, tcx: TyCtxtAt<'tcx>, message: &str) -> ErrorHandled {
-        match self.struct_error(tcx, message, |mut e| e.emit()) {
-            Ok(_) => ErrorHandled::Reported,
-            Err(x) => x,
-        }
-    }
-
-    pub fn report_as_lint(
-        &self,
-        tcx: TyCtxtAt<'tcx>,
-        message: &str,
-        lint_root: hir::HirId,
-        span: Option<Span>,
-    ) -> ErrorHandled {
-        match self.struct_generic(
-            tcx,
-            message,
-            |mut lint: DiagnosticBuilder<'_>| {
-                // Apply the span.
-                if let Some(span) = span {
-                    let primary_spans = lint.span.primary_spans().to_vec();
-                    // point at the actual error as the primary span
-                    lint.replace_span_with(span);
-                    // point to the `const` statement as a secondary span
-                    // they don't have any label
-                    for sp in primary_spans {
-                        if sp != span {
-                            lint.span_label(sp, "");
-                        }
-                    }
-                }
-                lint.emit();
-            },
-            Some(lint_root),
-        ) {
-            Ok(_) => ErrorHandled::Reported,
-            Err(err) => err,
-        }
-    }
-
-    /// Create a diagnostic for this const eval error.
-    ///
-    /// Sets the message passed in via `message` and adds span labels with detailed error
-    /// information before handing control back to `emit` to do any final processing.
-    /// It's the caller's responsibility to call emit(), stash(), etc. within the `emit`
-    /// function to dispose of the diagnostic properly.
-    ///
-    /// If `lint_root.is_some()` report it as a lint, else report it as a hard error.
-    /// (Except that for some errors, we ignore all that -- see `must_error` below.)
-    fn struct_generic(
-        &self,
-        tcx: TyCtxtAt<'tcx>,
-        message: &str,
-        emit: impl FnOnce(DiagnosticBuilder<'_>),
-        lint_root: Option<hir::HirId>,
-    ) -> Result<(), ErrorHandled> {
-        let must_error = match self.error {
-            err_inval!(Layout(LayoutError::Unknown(_))) | err_inval!(TooGeneric) => {
-                return Err(ErrorHandled::TooGeneric);
-            }
-            err_inval!(TypeckError) => return Err(ErrorHandled::Reported),
-            // We must *always* hard error on these, even if the caller wants just a lint.
-            err_inval!(Layout(LayoutError::SizeOverflow(_))) => true,
-            _ => false,
-        };
-        trace!("reporting const eval failure at {:?}", self.span);
-
-        let err_msg = match &self.error {
-            InterpError::MachineStop(msg) => {
-                // A custom error (`ConstEvalErrKind` in `librustc_mir/interp/const_eval/error.rs`).
-                // Should be turned into a string by now.
-                msg.downcast_ref::<String>().expect("invalid MachineStop payload").clone()
-            }
-            err => err.to_string(),
-        };
-
-        let finish = |mut err: DiagnosticBuilder<'_>, span_msg: Option<String>| {
-            if let Some(span_msg) = span_msg {
-                err.span_label(self.span, span_msg);
-            }
-            // Add spans for the stacktrace.
-            // Skip the last, which is just the environment of the constant.  The stacktrace
-            // is sometimes empty because we create "fake" eval contexts in CTFE to do work
-            // on constant values.
-            if self.stacktrace.len() > 0 {
-                for frame_info in &self.stacktrace[..self.stacktrace.len() - 1] {
-                    err.span_label(frame_info.call_site, frame_info.to_string());
-                }
-            }
-            // Let the caller finish the job.
-            emit(err)
-        };
-
-        if must_error {
-            // The `message` makes little sense here, this is a more serious error than the
-            // caller thinks anyway.
-            // See <https://github.com/rust-lang/rust/pull/63152>.
-            finish(struct_error(tcx, &err_msg), None);
-        } else {
-            // Regular case.
-            if let Some(lint_root) = lint_root {
-                // Report as lint.
-                let hir_id = self
-                    .stacktrace
-                    .iter()
-                    .rev()
-                    .filter_map(|frame| frame.lint_root)
-                    .next()
-                    .unwrap_or(lint_root);
-                tcx.struct_span_lint_hir(
-                    rustc_session::lint::builtin::CONST_ERR,
-                    hir_id,
-                    tcx.span,
-                    |lint| finish(lint.build(message), Some(err_msg)),
-                );
-            } else {
-                // Report as hard error.
-                finish(struct_error(tcx, message), Some(err_msg));
-            }
-        }
-        Ok(())
-    }
-}
-
-pub fn struct_error<'tcx>(tcx: TyCtxtAt<'tcx>, msg: &str) -> DiagnosticBuilder<'tcx> {
-    struct_span_err!(tcx.sess, tcx.span, E0080, "{}", msg)
-}
-
-/// Packages the kind of error we got from the const code interpreter
-/// up with a Rust-level backtrace of where the error occurred.
-/// Thsese should always be constructed by calling `.into()` on
-/// a `InterpError`. In `librustc_mir::interpret`, we have `throw_err_*`
-/// macros for this.
-#[derive(Debug)]
-pub struct InterpErrorInfo<'tcx> {
-    pub kind: InterpError<'tcx>,
-    backtrace: Option<Box<Backtrace>>,
-}
-
-impl fmt::Display for InterpErrorInfo<'_> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "{}", self.kind)
-    }
-}
-
-impl InterpErrorInfo<'_> {
-    pub fn print_backtrace(&mut self) {
-        if let Some(ref mut backtrace) = self.backtrace {
-            print_backtrace(&mut *backtrace);
-        }
-    }
-}
-
-fn print_backtrace(backtrace: &mut Backtrace) {
-    backtrace.resolve();
-    eprintln!("\n\nAn error occurred in miri:\n{:?}", backtrace);
-}
-
-impl From<ErrorHandled> for InterpErrorInfo<'tcx> {
-    fn from(err: ErrorHandled) -> Self {
-        match err {
-            ErrorHandled::Reported => err_inval!(ReferencedConstant),
-            ErrorHandled::TooGeneric => err_inval!(TooGeneric),
-        }
-        .into()
-    }
-}
-
-impl<'tcx> From<InterpError<'tcx>> for InterpErrorInfo<'tcx> {
-    fn from(kind: InterpError<'tcx>) -> Self {
-        let backtrace = match env::var("RUSTC_CTFE_BACKTRACE") {
-            // Matching `RUST_BACKTRACE` -- we treat "0" the same as "not present".
-            Ok(ref val) if val != "0" => {
-                let mut backtrace = Backtrace::new_unresolved();
-
-                if val == "immediate" {
-                    // Print it now.
-                    print_backtrace(&mut backtrace);
-                    None
-                } else {
-                    Some(Box::new(backtrace))
-                }
-            }
-            _ => None,
-        };
-        InterpErrorInfo { kind, backtrace }
-    }
-}
-
-/// Error information for when the program we executed turned out not to actually be a valid
-/// program. This cannot happen in stand-alone Miri, but it can happen during CTFE/ConstProp
-/// where we work on generic code or execution does not have all information available.
-pub enum InvalidProgramInfo<'tcx> {
-    /// Resolution can fail if we are in a too generic context.
-    TooGeneric,
-    /// Cannot compute this constant because it depends on another one
-    /// which already produced an error.
-    ReferencedConstant,
-    /// Abort in case type errors are reached.
-    TypeckError,
-    /// An error occurred during layout computation.
-    Layout(layout::LayoutError<'tcx>),
-}
-
-impl fmt::Debug for InvalidProgramInfo<'tcx> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        use InvalidProgramInfo::*;
-        match self {
-            TooGeneric => write!(f, "encountered overly generic constant"),
-            ReferencedConstant => write!(f, "referenced constant has errors"),
-            TypeckError => write!(f, "encountered constants with type errors, stopping evaluation"),
-            Layout(ref err) => write!(f, "{}", err),
-        }
-    }
-}
-
-/// Error information for when the program caused Undefined Behavior.
-pub enum UndefinedBehaviorInfo {
-    /// Free-form case. Only for errors that are never caught!
-    Ub(String),
-    /// Free-form case for experimental UB. Only for errors that are never caught!
-    UbExperimental(String),
-    /// Unreachable code was executed.
-    Unreachable,
-    /// An enum discriminant was set to a value which was outside the range of valid values.
-    InvalidDiscriminant(ScalarMaybeUndef),
-    /// A slice/array index projection went out-of-bounds.
-    BoundsCheckFailed { len: u64, index: u64 },
-    /// Something was divided by 0 (x / 0).
-    DivisionByZero,
-    /// Something was "remainded" by 0 (x % 0).
-    RemainderByZero,
-    /// Overflowing inbounds pointer arithmetic.
-    PointerArithOverflow,
-}
-
-impl fmt::Debug for UndefinedBehaviorInfo {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        use UndefinedBehaviorInfo::*;
-        match self {
-            Ub(msg) | UbExperimental(msg) => write!(f, "{}", msg),
-            Unreachable => write!(f, "entering unreachable code"),
-            InvalidDiscriminant(val) => write!(f, "encountering invalid enum discriminant {}", val),
-            BoundsCheckFailed { ref len, ref index } => write!(
-                f,
-                "indexing out of bounds: the len is {:?} but the index is {:?}",
-                len, index
-            ),
-            DivisionByZero => write!(f, "dividing by zero"),
-            RemainderByZero => write!(f, "calculating the remainder with a divisor of zero"),
-            PointerArithOverflow => write!(f, "overflowing in-bounds pointer arithmetic"),
-        }
-    }
-}
-
-/// Error information for when the program did something that might (or might not) be correct
-/// to do according to the Rust spec, but due to limitations in the interpreter, the
-/// operation could not be carried out. These limitations can differ between CTFE and the
-/// Miri engine, e.g., CTFE does not support casting pointers to "real" integers.
-///
-/// Currently, we also use this as fall-back error kind for errors that have not been
-/// categorized yet.
-pub enum UnsupportedOpInfo<'tcx> {
-    /// Free-form case. Only for errors that are never caught!
-    Unsupported(String),
-
-    /// When const-prop encounters a situation it does not support, it raises this error.
-    /// This must not allocate for performance reasons.
-    ConstPropUnsupported(&'tcx str),
-
-    // -- Everything below is not categorized yet --
-    FunctionAbiMismatch(Abi, Abi),
-    FunctionArgMismatch(Ty<'tcx>, Ty<'tcx>),
-    FunctionRetMismatch(Ty<'tcx>, Ty<'tcx>),
-    FunctionArgCountMismatch,
-    UnterminatedCString(Pointer),
-    DanglingPointerDeref,
-    DoubleFree,
-    InvalidMemoryAccess,
-    InvalidFunctionPointer,
-    InvalidBool,
-    PointerOutOfBounds {
-        ptr: Pointer,
-        msg: CheckInAllocMsg,
-        allocation_size: Size,
-    },
-    InvalidNullPointerUsage,
-    ReadPointerAsBytes,
-    ReadBytesAsPointer,
-    ReadForeignStatic,
-    InvalidPointerMath,
-    ReadUndefBytes(Size),
-    DeadLocal,
-    InvalidBoolOp(mir::BinOp),
-    UnimplementedTraitSelection,
-    CalledClosureAsFunction,
-    NoMirFor(String),
-    DerefFunctionPointer,
-    ExecuteMemory,
-    InvalidChar(u128),
-    OutOfTls,
-    TlsOutOfBounds,
-    AlignmentCheckFailed {
-        required: Align,
-        has: Align,
-    },
-    ValidationFailure(String),
-    VtableForArgumentlessMethod,
-    ModifiedConstantMemory,
-    ModifiedStatic,
-    TypeNotPrimitive(Ty<'tcx>),
-    ReallocatedWrongMemoryKind(String, String),
-    DeallocatedWrongMemoryKind(String, String),
-    ReallocateNonBasePtr,
-    DeallocateNonBasePtr,
-    IncorrectAllocationInformation(Size, Size, Align, Align),
-    HeapAllocZeroBytes,
-    HeapAllocNonPowerOfTwoAlignment(u64),
-    ReadFromReturnPointer,
-    PathNotFound(Vec<String>),
-    TransmuteSizeDiff(Ty<'tcx>, Ty<'tcx>),
-}
-
-impl fmt::Debug for UnsupportedOpInfo<'tcx> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        use UnsupportedOpInfo::*;
-        match self {
-            PointerOutOfBounds { ptr, msg, allocation_size } => write!(
-                f,
-                "{} failed: pointer must be in-bounds at offset {}, \
-                           but is outside bounds of allocation {} which has size {}",
-                msg,
-                ptr.offset.bytes(),
-                ptr.alloc_id,
-                allocation_size.bytes()
-            ),
-            ValidationFailure(ref err) => write!(f, "type validation failed: {}", err),
-            NoMirFor(ref func) => write!(f, "no MIR for `{}`", func),
-            FunctionAbiMismatch(caller_abi, callee_abi) => write!(
-                f,
-                "tried to call a function with ABI {:?} using caller ABI {:?}",
-                callee_abi, caller_abi
-            ),
-            FunctionArgMismatch(caller_ty, callee_ty) => write!(
-                f,
-                "tried to call a function with argument of type {:?} \
-                           passing data of type {:?}",
-                callee_ty, caller_ty
-            ),
-            TransmuteSizeDiff(from_ty, to_ty) => write!(
-                f,
-                "tried to transmute from {:?} to {:?}, but their sizes differed",
-                from_ty, to_ty
-            ),
-            FunctionRetMismatch(caller_ty, callee_ty) => write!(
-                f,
-                "tried to call a function with return type {:?} \
-                           passing return place of type {:?}",
-                callee_ty, caller_ty
-            ),
-            FunctionArgCountMismatch => {
-                write!(f, "tried to call a function with incorrect number of arguments")
-            }
-            ReallocatedWrongMemoryKind(ref old, ref new) => {
-                write!(f, "tried to reallocate memory from `{}` to `{}`", old, new)
-            }
-            DeallocatedWrongMemoryKind(ref old, ref new) => {
-                write!(f, "tried to deallocate `{}` memory but gave `{}` as the kind", old, new)
-            }
-            InvalidChar(c) => {
-                write!(f, "tried to interpret an invalid 32-bit value as a char: {}", c)
-            }
-            AlignmentCheckFailed { required, has } => write!(
-                f,
-                "tried to access memory with alignment {}, but alignment {} is required",
-                has.bytes(),
-                required.bytes()
-            ),
-            TypeNotPrimitive(ty) => write!(f, "expected primitive type, got {}", ty),
-            PathNotFound(ref path) => write!(f, "cannot find path {:?}", path),
-            IncorrectAllocationInformation(size, size2, align, align2) => write!(
-                f,
-                "incorrect alloc info: expected size {} and align {}, \
-                           got size {} and align {}",
-                size.bytes(),
-                align.bytes(),
-                size2.bytes(),
-                align2.bytes()
-            ),
-            InvalidMemoryAccess => write!(f, "tried to access memory through an invalid pointer"),
-            DanglingPointerDeref => write!(f, "dangling pointer was dereferenced"),
-            DoubleFree => write!(f, "tried to deallocate dangling pointer"),
-            InvalidFunctionPointer => {
-                write!(f, "tried to use a function pointer after offsetting it")
-            }
-            InvalidBool => write!(f, "invalid boolean value read"),
-            InvalidNullPointerUsage => write!(f, "invalid use of NULL pointer"),
-            ReadPointerAsBytes => write!(
-                f,
-                "a raw memory access tried to access part of a pointer value as raw \
-                    bytes"
-            ),
-            ReadBytesAsPointer => {
-                write!(f, "a memory access tried to interpret some bytes as a pointer")
-            }
-            ReadForeignStatic => write!(f, "tried to read from foreign (extern) static"),
-            InvalidPointerMath => write!(
-                f,
-                "attempted to do invalid arithmetic on pointers that would leak base \
-                    addresses, e.g., comparing pointers into different allocations"
-            ),
-            DeadLocal => write!(f, "tried to access a dead local variable"),
-            DerefFunctionPointer => write!(f, "tried to dereference a function pointer"),
-            ExecuteMemory => write!(f, "tried to treat a memory pointer as a function pointer"),
-            OutOfTls => write!(f, "reached the maximum number of representable TLS keys"),
-            TlsOutOfBounds => write!(f, "accessed an invalid (unallocated) TLS key"),
-            CalledClosureAsFunction => {
-                write!(f, "tried to call a closure through a function pointer")
-            }
-            VtableForArgumentlessMethod => {
-                write!(f, "tried to call a vtable function without arguments")
-            }
-            ModifiedConstantMemory => write!(f, "tried to modify constant memory"),
-            ModifiedStatic => write!(
-                f,
-                "tried to modify a static's initial value from another static's \
-                    initializer"
-            ),
-            ReallocateNonBasePtr => write!(
-                f,
-                "tried to reallocate with a pointer not to the beginning of an \
-                    existing object"
-            ),
-            DeallocateNonBasePtr => write!(
-                f,
-                "tried to deallocate with a pointer not to the beginning of an \
-                    existing object"
-            ),
-            HeapAllocZeroBytes => write!(f, "tried to re-, de- or allocate zero bytes on the heap"),
-            ReadFromReturnPointer => write!(f, "tried to read from the return pointer"),
-            UnimplementedTraitSelection => {
-                write!(f, "there were unresolved type arguments during trait selection")
-            }
-            InvalidBoolOp(_) => write!(f, "invalid boolean operation"),
-            UnterminatedCString(_) => write!(
-                f,
-                "attempted to get length of a null-terminated string, but no null \
-                    found before end of allocation"
-            ),
-            ReadUndefBytes(_) => write!(f, "attempted to read undefined bytes"),
-            HeapAllocNonPowerOfTwoAlignment(_) => write!(
-                f,
-                "tried to re-, de-, or allocate heap memory with alignment that is \
-                    not a power of two"
-            ),
-            Unsupported(ref msg) => write!(f, "{}", msg),
-            ConstPropUnsupported(ref msg) => {
-                write!(f, "Constant propagation encountered an unsupported situation: {}", msg)
-            }
-        }
-    }
-}
-
-/// Error information for when the program exhausted the resources granted to it
-/// by the interpreter.
-pub enum ResourceExhaustionInfo {
-    /// The stack grew too big.
-    StackFrameLimitReached,
-    /// The program ran into an infinite loop.
-    InfiniteLoop,
-}
-
-impl fmt::Debug for ResourceExhaustionInfo {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        use ResourceExhaustionInfo::*;
-        match self {
-            StackFrameLimitReached => {
-                write!(f, "reached the configured maximum number of stack frames")
-            }
-            InfiniteLoop => write!(
-                f,
-                "duplicate interpreter state observed here, const evaluation will never \
-                    terminate"
-            ),
-        }
-    }
-}
-
-pub enum InterpError<'tcx> {
-    /// The program caused undefined behavior.
-    UndefinedBehavior(UndefinedBehaviorInfo),
-    /// The program did something the interpreter does not support (some of these *might* be UB
-    /// but the interpreter is not sure).
-    Unsupported(UnsupportedOpInfo<'tcx>),
-    /// The program was invalid (ill-typed, bad MIR, not sufficiently monomorphized, ...).
-    InvalidProgram(InvalidProgramInfo<'tcx>),
-    /// The program exhausted the interpreter's resources (stack/heap too big,
-    /// execution takes too long, ...).
-    ResourceExhaustion(ResourceExhaustionInfo),
-    /// Stop execution for a machine-controlled reason. This is never raised by
-    /// the core engine itself.
-    MachineStop(Box<dyn Any + Send>),
-}
-
-pub type InterpResult<'tcx, T = ()> = Result<T, InterpErrorInfo<'tcx>>;
-
-impl fmt::Display for InterpError<'_> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        // Forward `Display` to `Debug`.
-        write!(f, "{:?}", self)
-    }
-}
-
-impl fmt::Debug for InterpError<'_> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        use InterpError::*;
-        match *self {
-            Unsupported(ref msg) => write!(f, "{:?}", msg),
-            InvalidProgram(ref msg) => write!(f, "{:?}", msg),
-            UndefinedBehavior(ref msg) => write!(f, "{:?}", msg),
-            ResourceExhaustion(ref msg) => write!(f, "{:?}", msg),
-            MachineStop(_) => bug!("unhandled MachineStop"),
-        }
-    }
-}
diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs
deleted file mode 100644
index c62f9a049a0..00000000000
--- a/src/librustc/mir/interpret/mod.rs
+++ /dev/null
@@ -1,565 +0,0 @@
-//! An interpreter for MIR used in CTFE and by miri.
-
-#[macro_export]
-macro_rules! err_unsup {
-    ($($tt:tt)*) => {
-        $crate::mir::interpret::InterpError::Unsupported(
-            $crate::mir::interpret::UnsupportedOpInfo::$($tt)*
-        )
-    };
-}
-
-#[macro_export]
-macro_rules! err_unsup_format {
-    ($($tt:tt)*) => { err_unsup!(Unsupported(format!($($tt)*))) };
-}
-
-#[macro_export]
-macro_rules! err_inval {
-    ($($tt:tt)*) => {
-        $crate::mir::interpret::InterpError::InvalidProgram(
-            $crate::mir::interpret::InvalidProgramInfo::$($tt)*
-        )
-    };
-}
-
-#[macro_export]
-macro_rules! err_ub {
-    ($($tt:tt)*) => {
-        $crate::mir::interpret::InterpError::UndefinedBehavior(
-            $crate::mir::interpret::UndefinedBehaviorInfo::$($tt)*
-        )
-    };
-}
-
-#[macro_export]
-macro_rules! err_ub_format {
-    ($($tt:tt)*) => { err_ub!(Ub(format!($($tt)*))) };
-}
-
-#[macro_export]
-macro_rules! err_exhaust {
-    ($($tt:tt)*) => {
-        $crate::mir::interpret::InterpError::ResourceExhaustion(
-            $crate::mir::interpret::ResourceExhaustionInfo::$($tt)*
-        )
-    };
-}
-
-#[macro_export]
-macro_rules! throw_unsup {
-    ($($tt:tt)*) => { return Err(err_unsup!($($tt)*).into()) };
-}
-
-#[macro_export]
-macro_rules! throw_unsup_format {
-    ($($tt:tt)*) => { throw_unsup!(Unsupported(format!($($tt)*))) };
-}
-
-#[macro_export]
-macro_rules! throw_inval {
-    ($($tt:tt)*) => { return Err(err_inval!($($tt)*).into()) };
-}
-
-#[macro_export]
-macro_rules! throw_ub {
-    ($($tt:tt)*) => { return Err(err_ub!($($tt)*).into()) };
-}
-
-#[macro_export]
-macro_rules! throw_ub_format {
-    ($($tt:tt)*) => { throw_ub!(Ub(format!($($tt)*))) };
-}
-
-#[macro_export]
-macro_rules! throw_exhaust {
-    ($($tt:tt)*) => { return Err(err_exhaust!($($tt)*).into()) };
-}
-
-#[macro_export]
-macro_rules! throw_machine_stop {
-    ($($tt:tt)*) => {
-        return Err($crate::mir::interpret::InterpError::MachineStop(Box::new($($tt)*)).into())
-    };
-}
-
-mod allocation;
-mod error;
-mod pointer;
-mod queries;
-mod value;
-
-pub use self::error::{
-    struct_error, ConstEvalErr, ConstEvalRawResult, ConstEvalResult, ErrorHandled, FrameInfo,
-    InterpError, InterpErrorInfo, InterpResult, InvalidProgramInfo, ResourceExhaustionInfo,
-    UndefinedBehaviorInfo, UnsupportedOpInfo,
-};
-
-pub use self::value::{get_slice_bytes, ConstValue, RawConst, Scalar, ScalarMaybeUndef};
-
-pub use self::allocation::{Allocation, AllocationExtra, Relocations, UndefMask};
-
-pub use self::pointer::{CheckInAllocMsg, Pointer, PointerArithmetic};
-
-use crate::mir;
-use crate::ty::codec::TyDecoder;
-use crate::ty::layout::{self, Size};
-use crate::ty::subst::GenericArgKind;
-use crate::ty::{self, Instance, Ty, TyCtxt};
-use byteorder::{BigEndian, LittleEndian, ReadBytesExt, WriteBytesExt};
-use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::sync::{HashMapExt, Lock};
-use rustc_data_structures::tiny_list::TinyList;
-use rustc_hir::def_id::DefId;
-use rustc_macros::HashStable;
-use rustc_serialize::{Decodable, Encodable, Encoder};
-use std::fmt;
-use std::io;
-use std::num::NonZeroU32;
-use std::sync::atomic::{AtomicU32, Ordering};
-use syntax::ast::LitKind;
-
-/// Uniquely identifies one of the following:
-/// - A constant
-/// - A static
-/// - A const fn where all arguments (if any) are zero-sized types
-#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, RustcEncodable, RustcDecodable)]
-#[derive(HashStable, Lift)]
-pub struct GlobalId<'tcx> {
-    /// For a constant or static, the `Instance` of the item itself.
-    /// For a promoted global, the `Instance` of the function they belong to.
-    pub instance: ty::Instance<'tcx>,
-
-    /// The index for promoted globals within their function's `mir::Body`.
-    pub promoted: Option<mir::Promoted>,
-}
-
-/// Input argument for `tcx.lit_to_const`.
-#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, HashStable)]
-pub struct LitToConstInput<'tcx> {
-    /// The absolute value of the resultant constant.
-    pub lit: &'tcx LitKind,
-    /// The type of the constant.
-    pub ty: Ty<'tcx>,
-    /// If the constant is negative.
-    pub neg: bool,
-}
-
-/// Error type for `tcx.lit_to_const`.
-#[derive(Copy, Clone, Debug, Eq, PartialEq, HashStable)]
-pub enum LitToConstError {
-    /// The literal's inferred type did not match the expected `ty` in the input.
-    /// This is used for graceful error handling (`delay_span_bug`) in
-    /// type checking (`AstConv::ast_const_to_const`).
-    TypeError,
-    UnparseableFloat,
-    Reported,
-}
-
-#[derive(Copy, Clone, Eq, Hash, Ord, PartialEq, PartialOrd)]
-pub struct AllocId(pub u64);
-
-impl fmt::Debug for AllocId {
-    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(fmt, "alloc{}", self.0)
-    }
-}
-
-impl rustc_serialize::UseSpecializedEncodable for AllocId {}
-impl rustc_serialize::UseSpecializedDecodable for AllocId {}
-
-#[derive(RustcDecodable, RustcEncodable)]
-enum AllocDiscriminant {
-    Alloc,
-    Fn,
-    Static,
-}
-
-pub fn specialized_encode_alloc_id<'tcx, E: Encoder>(
-    encoder: &mut E,
-    tcx: TyCtxt<'tcx>,
-    alloc_id: AllocId,
-) -> Result<(), E::Error> {
-    let alloc: GlobalAlloc<'tcx> =
-        tcx.alloc_map.lock().get(alloc_id).expect("no value for given alloc ID");
-    match alloc {
-        GlobalAlloc::Memory(alloc) => {
-            trace!("encoding {:?} with {:#?}", alloc_id, alloc);
-            AllocDiscriminant::Alloc.encode(encoder)?;
-            alloc.encode(encoder)?;
-        }
-        GlobalAlloc::Function(fn_instance) => {
-            trace!("encoding {:?} with {:#?}", alloc_id, fn_instance);
-            AllocDiscriminant::Fn.encode(encoder)?;
-            fn_instance.encode(encoder)?;
-        }
-        GlobalAlloc::Static(did) => {
-            // References to statics doesn't need to know about their allocations,
-            // just about its `DefId`.
-            AllocDiscriminant::Static.encode(encoder)?;
-            did.encode(encoder)?;
-        }
-    }
-    Ok(())
-}
-
-// Used to avoid infinite recursion when decoding cyclic allocations.
-type DecodingSessionId = NonZeroU32;
-
-#[derive(Clone)]
-enum State {
-    Empty,
-    InProgressNonAlloc(TinyList<DecodingSessionId>),
-    InProgress(TinyList<DecodingSessionId>, AllocId),
-    Done(AllocId),
-}
-
-pub struct AllocDecodingState {
-    // For each `AllocId`, we keep track of which decoding state it's currently in.
-    decoding_state: Vec<Lock<State>>,
-    // The offsets of each allocation in the data stream.
-    data_offsets: Vec<u32>,
-}
-
-impl AllocDecodingState {
-    pub fn new_decoding_session(&self) -> AllocDecodingSession<'_> {
-        static DECODER_SESSION_ID: AtomicU32 = AtomicU32::new(0);
-        let counter = DECODER_SESSION_ID.fetch_add(1, Ordering::SeqCst);
-
-        // Make sure this is never zero.
-        let session_id = DecodingSessionId::new((counter & 0x7FFFFFFF) + 1).unwrap();
-
-        AllocDecodingSession { state: self, session_id }
-    }
-
-    pub fn new(data_offsets: Vec<u32>) -> Self {
-        let decoding_state = vec![Lock::new(State::Empty); data_offsets.len()];
-
-        Self { decoding_state, data_offsets }
-    }
-}
-
-#[derive(Copy, Clone)]
-pub struct AllocDecodingSession<'s> {
-    state: &'s AllocDecodingState,
-    session_id: DecodingSessionId,
-}
-
-impl<'s> AllocDecodingSession<'s> {
-    /// Decodes an `AllocId` in a thread-safe way.
-    pub fn decode_alloc_id<D>(&self, decoder: &mut D) -> Result<AllocId, D::Error>
-    where
-        D: TyDecoder<'tcx>,
-    {
-        // Read the index of the allocation.
-        let idx = decoder.read_u32()? as usize;
-        let pos = self.state.data_offsets[idx] as usize;
-
-        // Decode the `AllocDiscriminant` now so that we know if we have to reserve an
-        // `AllocId`.
-        let (alloc_kind, pos) = decoder.with_position(pos, |decoder| {
-            let alloc_kind = AllocDiscriminant::decode(decoder)?;
-            Ok((alloc_kind, decoder.position()))
-        })?;
-
-        // Check the decoding state to see if it's already decoded or if we should
-        // decode it here.
-        let alloc_id = {
-            let mut entry = self.state.decoding_state[idx].lock();
-
-            match *entry {
-                State::Done(alloc_id) => {
-                    return Ok(alloc_id);
-                }
-                ref mut entry @ State::Empty => {
-                    // We are allowed to decode.
-                    match alloc_kind {
-                        AllocDiscriminant::Alloc => {
-                            // If this is an allocation, we need to reserve an
-                            // `AllocId` so we can decode cyclic graphs.
-                            let alloc_id = decoder.tcx().alloc_map.lock().reserve();
-                            *entry =
-                                State::InProgress(TinyList::new_single(self.session_id), alloc_id);
-                            Some(alloc_id)
-                        }
-                        AllocDiscriminant::Fn | AllocDiscriminant::Static => {
-                            // Fns and statics cannot be cyclic, and their `AllocId`
-                            // is determined later by interning.
-                            *entry =
-                                State::InProgressNonAlloc(TinyList::new_single(self.session_id));
-                            None
-                        }
-                    }
-                }
-                State::InProgressNonAlloc(ref mut sessions) => {
-                    if sessions.contains(&self.session_id) {
-                        bug!("this should be unreachable");
-                    } else {
-                        // Start decoding concurrently.
-                        sessions.insert(self.session_id);
-                        None
-                    }
-                }
-                State::InProgress(ref mut sessions, alloc_id) => {
-                    if sessions.contains(&self.session_id) {
-                        // Don't recurse.
-                        return Ok(alloc_id);
-                    } else {
-                        // Start decoding concurrently.
-                        sessions.insert(self.session_id);
-                        Some(alloc_id)
-                    }
-                }
-            }
-        };
-
-        // Now decode the actual data.
-        let alloc_id = decoder.with_position(pos, |decoder| {
-            match alloc_kind {
-                AllocDiscriminant::Alloc => {
-                    let alloc = <&'tcx Allocation as Decodable>::decode(decoder)?;
-                    // We already have a reserved `AllocId`.
-                    let alloc_id = alloc_id.unwrap();
-                    trace!("decoded alloc {:?}: {:#?}", alloc_id, alloc);
-                    decoder.tcx().alloc_map.lock().set_alloc_id_same_memory(alloc_id, alloc);
-                    Ok(alloc_id)
-                }
-                AllocDiscriminant::Fn => {
-                    assert!(alloc_id.is_none());
-                    trace!("creating fn alloc ID");
-                    let instance = ty::Instance::decode(decoder)?;
-                    trace!("decoded fn alloc instance: {:?}", instance);
-                    let alloc_id = decoder.tcx().alloc_map.lock().create_fn_alloc(instance);
-                    Ok(alloc_id)
-                }
-                AllocDiscriminant::Static => {
-                    assert!(alloc_id.is_none());
-                    trace!("creating extern static alloc ID");
-                    let did = DefId::decode(decoder)?;
-                    trace!("decoded static def-ID: {:?}", did);
-                    let alloc_id = decoder.tcx().alloc_map.lock().create_static_alloc(did);
-                    Ok(alloc_id)
-                }
-            }
-        })?;
-
-        self.state.decoding_state[idx].with_lock(|entry| {
-            *entry = State::Done(alloc_id);
-        });
-
-        Ok(alloc_id)
-    }
-}
-
-impl fmt::Display for AllocId {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "{}", self.0)
-    }
-}
-
-/// An allocation in the global (tcx-managed) memory can be either a function pointer,
-/// a static, or a "real" allocation with some data in it.
-#[derive(Debug, Clone, Eq, PartialEq, Hash, RustcDecodable, RustcEncodable, HashStable)]
-pub enum GlobalAlloc<'tcx> {
-    /// The alloc ID is used as a function pointer.
-    Function(Instance<'tcx>),
-    /// The alloc ID points to a "lazy" static variable that did not get computed (yet).
-    /// This is also used to break the cycle in recursive statics.
-    Static(DefId),
-    /// The alloc ID points to memory.
-    Memory(&'tcx Allocation),
-}
-
-pub struct AllocMap<'tcx> {
-    /// Maps `AllocId`s to their corresponding allocations.
-    alloc_map: FxHashMap<AllocId, GlobalAlloc<'tcx>>,
-
-    /// Used to ensure that statics and functions only get one associated `AllocId`.
-    /// Should never contain a `GlobalAlloc::Memory`!
-    //
-    // FIXME: Should we just have two separate dedup maps for statics and functions each?
-    dedup: FxHashMap<GlobalAlloc<'tcx>, AllocId>,
-
-    /// The `AllocId` to assign to the next requested ID.
-    /// Always incremented; never gets smaller.
-    next_id: AllocId,
-}
-
-impl<'tcx> AllocMap<'tcx> {
-    pub fn new() -> Self {
-        AllocMap { alloc_map: Default::default(), dedup: Default::default(), next_id: AllocId(0) }
-    }
-
-    /// Obtains a new allocation ID that can be referenced but does not
-    /// yet have an allocation backing it.
-    ///
-    /// Make sure to call `set_alloc_id_memory` or `set_alloc_id_same_memory` before returning such
-    /// an `AllocId` from a query.
-    pub fn reserve(&mut self) -> AllocId {
-        let next = self.next_id;
-        self.next_id.0 = self.next_id.0.checked_add(1).expect(
-            "You overflowed a u64 by incrementing by 1... \
-             You've just earned yourself a free drink if we ever meet. \
-             Seriously, how did you do that?!",
-        );
-        next
-    }
-
-    /// Reserves a new ID *if* this allocation has not been dedup-reserved before.
-    /// Should only be used for function pointers and statics, we don't want
-    /// to dedup IDs for "real" memory!
-    fn reserve_and_set_dedup(&mut self, alloc: GlobalAlloc<'tcx>) -> AllocId {
-        match alloc {
-            GlobalAlloc::Function(..) | GlobalAlloc::Static(..) => {}
-            GlobalAlloc::Memory(..) => bug!("Trying to dedup-reserve memory with real data!"),
-        }
-        if let Some(&alloc_id) = self.dedup.get(&alloc) {
-            return alloc_id;
-        }
-        let id = self.reserve();
-        debug!("creating alloc {:?} with id {}", alloc, id);
-        self.alloc_map.insert(id, alloc.clone());
-        self.dedup.insert(alloc, id);
-        id
-    }
-
-    /// Generates an `AllocId` for a static or return a cached one in case this function has been
-    /// called on the same static before.
-    pub fn create_static_alloc(&mut self, static_id: DefId) -> AllocId {
-        self.reserve_and_set_dedup(GlobalAlloc::Static(static_id))
-    }
-
-    /// Generates an `AllocId` for a function.  Depending on the function type,
-    /// this might get deduplicated or assigned a new ID each time.
-    pub fn create_fn_alloc(&mut self, instance: Instance<'tcx>) -> AllocId {
-        // Functions cannot be identified by pointers, as asm-equal functions can get deduplicated
-        // by the linker (we set the "unnamed_addr" attribute for LLVM) and functions can be
-        // duplicated across crates.
-        // We thus generate a new `AllocId` for every mention of a function. This means that
-        // `main as fn() == main as fn()` is false, while `let x = main as fn(); x == x` is true.
-        // However, formatting code relies on function identity (see #58320), so we only do
-        // this for generic functions.  Lifetime parameters are ignored.
-        let is_generic = instance.substs.into_iter().any(|kind| match kind.unpack() {
-            GenericArgKind::Lifetime(_) => false,
-            _ => true,
-        });
-        if is_generic {
-            // Get a fresh ID.
-            let id = self.reserve();
-            self.alloc_map.insert(id, GlobalAlloc::Function(instance));
-            id
-        } else {
-            // Deduplicate.
-            self.reserve_and_set_dedup(GlobalAlloc::Function(instance))
-        }
-    }
-
-    /// Interns the `Allocation` and return a new `AllocId`, even if there's already an identical
-    /// `Allocation` with a different `AllocId`.
-    /// Statics with identical content will still point to the same `Allocation`, i.e.,
-    /// their data will be deduplicated through `Allocation` interning -- but they
-    /// are different places in memory and as such need different IDs.
-    pub fn create_memory_alloc(&mut self, mem: &'tcx Allocation) -> AllocId {
-        let id = self.reserve();
-        self.set_alloc_id_memory(id, mem);
-        id
-    }
-
-    /// Returns `None` in case the `AllocId` is dangling. An `InterpretCx` can still have a
-    /// local `Allocation` for that `AllocId`, but having such an `AllocId` in a constant is
-    /// illegal and will likely ICE.
-    /// This function exists to allow const eval to detect the difference between evaluation-
-    /// local dangling pointers and allocations in constants/statics.
-    #[inline]
-    pub fn get(&self, id: AllocId) -> Option<GlobalAlloc<'tcx>> {
-        self.alloc_map.get(&id).cloned()
-    }
-
-    /// Panics if the `AllocId` does not refer to an `Allocation`
-    pub fn unwrap_memory(&self, id: AllocId) -> &'tcx Allocation {
-        match self.get(id) {
-            Some(GlobalAlloc::Memory(mem)) => mem,
-            _ => bug!("expected allocation ID {} to point to memory", id),
-        }
-    }
-
-    /// Panics if the `AllocId` does not refer to a function
-    pub fn unwrap_fn(&self, id: AllocId) -> Instance<'tcx> {
-        match self.get(id) {
-            Some(GlobalAlloc::Function(instance)) => instance,
-            _ => bug!("expected allocation ID {} to point to a function", id),
-        }
-    }
-
-    /// Freezes an `AllocId` created with `reserve` by pointing it at an `Allocation`. Trying to
-    /// call this function twice, even with the same `Allocation` will ICE the compiler.
-    pub fn set_alloc_id_memory(&mut self, id: AllocId, mem: &'tcx Allocation) {
-        if let Some(old) = self.alloc_map.insert(id, GlobalAlloc::Memory(mem)) {
-            bug!("tried to set allocation ID {}, but it was already existing as {:#?}", id, old);
-        }
-    }
-
-    /// Freezes an `AllocId` created with `reserve` by pointing it at an `Allocation`. May be called
-    /// twice for the same `(AllocId, Allocation)` pair.
-    fn set_alloc_id_same_memory(&mut self, id: AllocId, mem: &'tcx Allocation) {
-        self.alloc_map.insert_same(id, GlobalAlloc::Memory(mem));
-    }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Methods to access integers in the target endianness
-////////////////////////////////////////////////////////////////////////////////
-
-#[inline]
-pub fn write_target_uint(
-    endianness: layout::Endian,
-    mut target: &mut [u8],
-    data: u128,
-) -> Result<(), io::Error> {
-    let len = target.len();
-    match endianness {
-        layout::Endian::Little => target.write_uint128::<LittleEndian>(data, len),
-        layout::Endian::Big => target.write_uint128::<BigEndian>(data, len),
-    }
-}
-
-#[inline]
-pub fn read_target_uint(endianness: layout::Endian, mut source: &[u8]) -> Result<u128, io::Error> {
-    match endianness {
-        layout::Endian::Little => source.read_uint128::<LittleEndian>(source.len()),
-        layout::Endian::Big => source.read_uint128::<BigEndian>(source.len()),
-    }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Methods to facilitate working with signed integers stored in a u128
-////////////////////////////////////////////////////////////////////////////////
-
-/// Truncates `value` to `size` bits and then sign-extend it to 128 bits
-/// (i.e., if it is negative, fill with 1's on the left).
-#[inline]
-pub fn sign_extend(value: u128, size: Size) -> u128 {
-    let size = size.bits();
-    if size == 0 {
-        // Truncated until nothing is left.
-        return 0;
-    }
-    // Sign-extend it.
-    let shift = 128 - size;
-    // Shift the unsigned value to the left, then shift back to the right as signed
-    // (essentially fills with FF on the left).
-    (((value << shift) as i128) >> shift) as u128
-}
-
-/// Truncates `value` to `size` bits.
-#[inline]
-pub fn truncate(value: u128, size: Size) -> u128 {
-    let size = size.bits();
-    if size == 0 {
-        // Truncated until nothing is left.
-        return 0;
-    }
-    let shift = 128 - size;
-    // Truncate (shift left to drop out leftover values, shift right to fill with zeroes).
-    (value << shift) >> shift
-}
diff --git a/src/librustc/mir/interpret/pointer.rs b/src/librustc/mir/interpret/pointer.rs
deleted file mode 100644
index a4974fb541b..00000000000
--- a/src/librustc/mir/interpret/pointer.rs
+++ /dev/null
@@ -1,232 +0,0 @@
-use super::{AllocId, InterpResult};
-
-use crate::ty::layout::{self, HasDataLayout, Size};
-
-use rustc_macros::HashStable;
-
-use std::convert::TryFrom;
-use std::fmt::{self, Display};
-
-/// Used by `check_in_alloc` to indicate context of check
-#[derive(Debug, Copy, Clone, RustcEncodable, RustcDecodable, HashStable)]
-pub enum CheckInAllocMsg {
-    MemoryAccessTest,
-    NullPointerTest,
-    PointerArithmeticTest,
-    InboundsTest,
-}
-
-impl Display for CheckInAllocMsg {
-    /// When this is printed as an error the context looks like this
-    /// "{test name} failed: pointer must be in-bounds at offset..."
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(
-            f,
-            "{}",
-            match *self {
-                CheckInAllocMsg::MemoryAccessTest => "Memory access",
-                CheckInAllocMsg::NullPointerTest => "Null pointer test",
-                CheckInAllocMsg::PointerArithmeticTest => "Pointer arithmetic",
-                CheckInAllocMsg::InboundsTest => "Inbounds test",
-            }
-        )
-    }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Pointer arithmetic
-////////////////////////////////////////////////////////////////////////////////
-
-pub trait PointerArithmetic: layout::HasDataLayout {
-    // These are not supposed to be overridden.
-
-    #[inline(always)]
-    fn pointer_size(&self) -> Size {
-        self.data_layout().pointer_size
-    }
-
-    #[inline]
-    fn usize_max(&self) -> u64 {
-        let max_usize_plus_1 = 1u128 << self.pointer_size().bits();
-        u64::try_from(max_usize_plus_1 - 1).unwrap()
-    }
-
-    #[inline]
-    fn isize_max(&self) -> i64 {
-        let max_isize_plus_1 = 1u128 << (self.pointer_size().bits() - 1);
-        i64::try_from(max_isize_plus_1 - 1).unwrap()
-    }
-
-    /// Helper function: truncate given value-"overflowed flag" pair to pointer size and
-    /// update "overflowed flag" if there was an overflow.
-    /// This should be called by all the other methods before returning!
-    #[inline]
-    fn truncate_to_ptr(&self, (val, over): (u64, bool)) -> (u64, bool) {
-        let val = val as u128;
-        let max_ptr_plus_1 = 1u128 << self.pointer_size().bits();
-        ((val % max_ptr_plus_1) as u64, over || val >= max_ptr_plus_1)
-    }
-
-    #[inline]
-    fn overflowing_offset(&self, val: u64, i: u64) -> (u64, bool) {
-        let res = val.overflowing_add(i);
-        self.truncate_to_ptr(res)
-    }
-
-    // Overflow checking only works properly on the range from -u64 to +u64.
-    #[inline]
-    fn overflowing_signed_offset(&self, val: u64, i: i128) -> (u64, bool) {
-        // FIXME: is it possible to over/underflow here?
-        if i < 0 {
-            // Trickery to ensure that `i64::min_value()` works fine: compute `n = -i`.
-            // This formula only works for true negative values; it overflows for zero!
-            let n = u64::max_value() - (i as u64) + 1;
-            let res = val.overflowing_sub(n);
-            self.truncate_to_ptr(res)
-        } else {
-            self.overflowing_offset(val, i as u64)
-        }
-    }
-
-    #[inline]
-    fn offset<'tcx>(&self, val: u64, i: u64) -> InterpResult<'tcx, u64> {
-        let (res, over) = self.overflowing_offset(val, i);
-        if over { throw_ub!(PointerArithOverflow) } else { Ok(res) }
-    }
-
-    #[inline]
-    fn signed_offset<'tcx>(&self, val: u64, i: i64) -> InterpResult<'tcx, u64> {
-        let (res, over) = self.overflowing_signed_offset(val, i128::from(i));
-        if over { throw_ub!(PointerArithOverflow) } else { Ok(res) }
-    }
-}
-
-impl<T: layout::HasDataLayout> PointerArithmetic for T {}
-
-/// `Pointer` is generic over the type that represents a reference to `Allocation`s,
-/// thus making it possible for the most convenient representation to be used in
-/// each context.
-///
-/// Defaults to the index based and loosely coupled `AllocId`.
-///
-/// `Pointer` is also generic over the `Tag` associated with each pointer,
-/// which is used to do provenance tracking during execution.
-#[derive(
-    Copy,
-    Clone,
-    Eq,
-    PartialEq,
-    Ord,
-    PartialOrd,
-    RustcEncodable,
-    RustcDecodable,
-    Hash,
-    HashStable
-)]
-pub struct Pointer<Tag = (), Id = AllocId> {
-    pub alloc_id: Id,
-    pub offset: Size,
-    pub tag: Tag,
-}
-
-static_assert_size!(Pointer, 16);
-
-impl<Tag: fmt::Debug, Id: fmt::Debug> fmt::Debug for Pointer<Tag, Id> {
-    default fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "{:?}+{:x}[{:?}]", self.alloc_id, self.offset.bytes(), self.tag)
-    }
-}
-// Specialization for no tag
-impl<Id: fmt::Debug> fmt::Debug for Pointer<(), Id> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "{:?}+{:x}", self.alloc_id, self.offset.bytes())
-    }
-}
-
-/// Produces a `Pointer` that points to the beginning of the `Allocation`.
-impl From<AllocId> for Pointer {
-    #[inline(always)]
-    fn from(alloc_id: AllocId) -> Self {
-        Pointer::new(alloc_id, Size::ZERO)
-    }
-}
-
-impl Pointer<()> {
-    #[inline(always)]
-    pub fn new(alloc_id: AllocId, offset: Size) -> Self {
-        Pointer { alloc_id, offset, tag: () }
-    }
-
-    #[inline(always)]
-    pub fn with_tag<Tag>(self, tag: Tag) -> Pointer<Tag> {
-        Pointer::new_with_tag(self.alloc_id, self.offset, tag)
-    }
-}
-
-impl<'tcx, Tag> Pointer<Tag> {
-    #[inline(always)]
-    pub fn new_with_tag(alloc_id: AllocId, offset: Size, tag: Tag) -> Self {
-        Pointer { alloc_id, offset, tag }
-    }
-
-    #[inline]
-    pub fn offset(self, i: Size, cx: &impl HasDataLayout) -> InterpResult<'tcx, Self> {
-        Ok(Pointer::new_with_tag(
-            self.alloc_id,
-            Size::from_bytes(cx.data_layout().offset(self.offset.bytes(), i.bytes())?),
-            self.tag,
-        ))
-    }
-
-    #[inline]
-    pub fn overflowing_offset(self, i: Size, cx: &impl HasDataLayout) -> (Self, bool) {
-        let (res, over) = cx.data_layout().overflowing_offset(self.offset.bytes(), i.bytes());
-        (Pointer::new_with_tag(self.alloc_id, Size::from_bytes(res), self.tag), over)
-    }
-
-    #[inline(always)]
-    pub fn wrapping_offset(self, i: Size, cx: &impl HasDataLayout) -> Self {
-        self.overflowing_offset(i, cx).0
-    }
-
-    #[inline]
-    pub fn signed_offset(self, i: i64, cx: &impl HasDataLayout) -> InterpResult<'tcx, Self> {
-        Ok(Pointer::new_with_tag(
-            self.alloc_id,
-            Size::from_bytes(cx.data_layout().signed_offset(self.offset.bytes(), i)?),
-            self.tag,
-        ))
-    }
-
-    #[inline]
-    pub fn overflowing_signed_offset(self, i: i128, cx: &impl HasDataLayout) -> (Self, bool) {
-        let (res, over) = cx.data_layout().overflowing_signed_offset(self.offset.bytes(), i);
-        (Pointer::new_with_tag(self.alloc_id, Size::from_bytes(res), self.tag), over)
-    }
-
-    #[inline(always)]
-    pub fn wrapping_signed_offset(self, i: i64, cx: &impl HasDataLayout) -> Self {
-        self.overflowing_signed_offset(i128::from(i), cx).0
-    }
-
-    #[inline(always)]
-    pub fn erase_tag(self) -> Pointer {
-        Pointer { alloc_id: self.alloc_id, offset: self.offset, tag: () }
-    }
-
-    /// Test if the pointer is "inbounds" of an allocation of the given size.
-    /// A pointer is "inbounds" even if its offset is equal to the size; this is
-    /// a "one-past-the-end" pointer.
-    #[inline(always)]
-    pub fn check_inbounds_alloc(
-        self,
-        allocation_size: Size,
-        msg: CheckInAllocMsg,
-    ) -> InterpResult<'tcx, ()> {
-        if self.offset > allocation_size {
-            throw_unsup!(PointerOutOfBounds { ptr: self.erase_tag(), msg, allocation_size })
-        } else {
-            Ok(())
-        }
-    }
-}
diff --git a/src/librustc/mir/interpret/queries.rs b/src/librustc/mir/interpret/queries.rs
deleted file mode 100644
index ed57f81e782..00000000000
--- a/src/librustc/mir/interpret/queries.rs
+++ /dev/null
@@ -1,78 +0,0 @@
-use super::{ConstEvalResult, ErrorHandled, GlobalId};
-
-use crate::mir;
-use crate::ty::subst::{InternalSubsts, SubstsRef};
-use crate::ty::{self, TyCtxt};
-use rustc_hir::def_id::DefId;
-use rustc_span::Span;
-
-impl<'tcx> TyCtxt<'tcx> {
-    /// Evaluates a constant without providing any substitutions. This is useful to evaluate consts
-    /// that can't take any generic arguments like statics, const items or enum discriminants. If a
-    /// generic parameter is used within the constant `ErrorHandled::ToGeneric` will be returned.
-    pub fn const_eval_poly(self, def_id: DefId) -> ConstEvalResult<'tcx> {
-        // In some situations def_id will have substitutions within scope, but they aren't allowed
-        // to be used. So we can't use `Instance::mono`, instead we feed unresolved substitutions
-        // into `const_eval` which will return `ErrorHandled::ToGeneric` if any og them are
-        // encountered.
-        let substs = InternalSubsts::identity_for_item(self, def_id);
-        let instance = ty::Instance::new(def_id, substs);
-        let cid = GlobalId { instance, promoted: None };
-        let param_env = self.param_env(def_id).with_reveal_all();
-        self.const_eval_validated(param_env.and(cid))
-    }
-
-    /// Resolves and evaluates a constant.
-    ///
-    /// The constant can be located on a trait like `<A as B>::C`, in which case the given
-    /// substitutions and environment are used to resolve the constant. Alternatively if the
-    /// constant has generic parameters in scope the substitutions are used to evaluate the value of
-    /// the constant. For example in `fn foo<T>() { let _ = [0; bar::<T>()]; }` the repeat count
-    /// constant `bar::<T>()` requires a substitution for `T`, if the substitution for `T` is still
-    /// too generic for the constant to be evaluated then `Err(ErrorHandled::TooGeneric)` is
-    /// returned.
-    pub fn const_eval_resolve(
-        self,
-        param_env: ty::ParamEnv<'tcx>,
-        def_id: DefId,
-        substs: SubstsRef<'tcx>,
-        promoted: Option<mir::Promoted>,
-        span: Option<Span>,
-    ) -> ConstEvalResult<'tcx> {
-        let instance = ty::Instance::resolve(self, param_env, def_id, substs);
-        if let Some(instance) = instance {
-            if let Some(promoted) = promoted {
-                self.const_eval_promoted(param_env, instance, promoted)
-            } else {
-                self.const_eval_instance(param_env, instance, span)
-            }
-        } else {
-            Err(ErrorHandled::TooGeneric)
-        }
-    }
-
-    pub fn const_eval_instance(
-        self,
-        param_env: ty::ParamEnv<'tcx>,
-        instance: ty::Instance<'tcx>,
-        span: Option<Span>,
-    ) -> ConstEvalResult<'tcx> {
-        let cid = GlobalId { instance, promoted: None };
-        if let Some(span) = span {
-            self.at(span).const_eval_validated(param_env.and(cid))
-        } else {
-            self.const_eval_validated(param_env.and(cid))
-        }
-    }
-
-    /// Evaluate a promoted constant.
-    pub fn const_eval_promoted(
-        self,
-        param_env: ty::ParamEnv<'tcx>,
-        instance: ty::Instance<'tcx>,
-        promoted: mir::Promoted,
-    ) -> ConstEvalResult<'tcx> {
-        let cid = GlobalId { instance, promoted: Some(promoted) };
-        self.const_eval_validated(param_env.and(cid))
-    }
-}
diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs
deleted file mode 100644
index 2c146b5d7b4..00000000000
--- a/src/librustc/mir/interpret/value.rs
+++ /dev/null
@@ -1,679 +0,0 @@
-use rustc_apfloat::{
-    ieee::{Double, Single},
-    Float,
-};
-use rustc_macros::HashStable;
-use std::fmt;
-
-use crate::ty::{
-    layout::{HasDataLayout, Size},
-    ParamEnv, Ty, TyCtxt,
-};
-
-use super::{sign_extend, truncate, AllocId, Allocation, InterpResult, Pointer, PointerArithmetic};
-
-/// Represents the result of a raw const operation, pre-validation.
-#[derive(Clone, HashStable)]
-pub struct RawConst<'tcx> {
-    // the value lives here, at offset 0, and that allocation definitely is a `AllocKind::Memory`
-    // (so you can use `AllocMap::unwrap_memory`).
-    pub alloc_id: AllocId,
-    pub ty: Ty<'tcx>,
-}
-
-/// Represents a constant value in Rust. `Scalar` and `Slice` are optimizations for
-/// array length computations, enum discriminants and the pattern matching logic.
-#[derive(
-    Copy,
-    Clone,
-    Debug,
-    Eq,
-    PartialEq,
-    PartialOrd,
-    Ord,
-    RustcEncodable,
-    RustcDecodable,
-    Hash,
-    HashStable
-)]
-pub enum ConstValue<'tcx> {
-    /// Used only for types with `layout::abi::Scalar` ABI and ZSTs.
-    ///
-    /// Not using the enum `Value` to encode that this must not be `Undef`.
-    Scalar(Scalar),
-
-    /// Used only for `&[u8]` and `&str`
-    Slice { data: &'tcx Allocation, start: usize, end: usize },
-
-    /// A value not represented/representable by `Scalar` or `Slice`
-    ByRef {
-        /// The backing memory of the value, may contain more memory than needed for just the value
-        /// in order to share `Allocation`s between values
-        alloc: &'tcx Allocation,
-        /// Offset into `alloc`
-        offset: Size,
-    },
-}
-
-#[cfg(target_arch = "x86_64")]
-static_assert_size!(ConstValue<'_>, 32);
-
-impl<'tcx> ConstValue<'tcx> {
-    #[inline]
-    pub fn try_to_scalar(&self) -> Option<Scalar> {
-        match *self {
-            ConstValue::ByRef { .. } | ConstValue::Slice { .. } => None,
-            ConstValue::Scalar(val) => Some(val),
-        }
-    }
-
-    pub fn try_to_bits(&self, size: Size) -> Option<u128> {
-        self.try_to_scalar()?.to_bits(size).ok()
-    }
-
-    pub fn try_to_bits_for_ty(
-        &self,
-        tcx: TyCtxt<'tcx>,
-        param_env: ParamEnv<'tcx>,
-        ty: Ty<'tcx>,
-    ) -> Option<u128> {
-        let size = tcx.layout_of(param_env.with_reveal_all().and(ty)).ok()?.size;
-        self.try_to_bits(size)
-    }
-
-    pub fn from_bool(b: bool) -> Self {
-        ConstValue::Scalar(Scalar::from_bool(b))
-    }
-
-    pub fn from_u64(i: u64) -> Self {
-        ConstValue::Scalar(Scalar::from_u64(i))
-    }
-
-    pub fn from_machine_usize(i: u64, cx: &impl HasDataLayout) -> Self {
-        ConstValue::Scalar(Scalar::from_machine_usize(i, cx))
-    }
-}
-
-/// A `Scalar` represents an immediate, primitive value existing outside of a
-/// `memory::Allocation`. It is in many ways like a small chunk of a `Allocation`, up to 8 bytes in
-/// size. Like a range of bytes in an `Allocation`, a `Scalar` can either represent the raw bytes
-/// of a simple value or a pointer into another `Allocation`
-#[derive(
-    Clone,
-    Copy,
-    Eq,
-    PartialEq,
-    Ord,
-    PartialOrd,
-    RustcEncodable,
-    RustcDecodable,
-    Hash,
-    HashStable
-)]
-pub enum Scalar<Tag = (), Id = AllocId> {
-    /// The raw bytes of a simple value.
-    Raw {
-        /// The first `size` bytes of `data` are the value.
-        /// Do not try to read less or more bytes than that. The remaining bytes must be 0.
-        data: u128,
-        size: u8,
-    },
-
-    /// A pointer into an `Allocation`. An `Allocation` in the `memory` module has a list of
-    /// relocations, but a `Scalar` is only large enough to contain one, so we just represent the
-    /// relocation and its associated offset together as a `Pointer` here.
-    Ptr(Pointer<Tag, Id>),
-}
-
-#[cfg(target_arch = "x86_64")]
-static_assert_size!(Scalar, 24);
-
-impl<Tag: fmt::Debug, Id: fmt::Debug> fmt::Debug for Scalar<Tag, Id> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match self {
-            Scalar::Ptr(ptr) => write!(f, "{:?}", ptr),
-            &Scalar::Raw { data, size } => {
-                Scalar::check_data(data, size);
-                if size == 0 {
-                    write!(f, "<ZST>")
-                } else {
-                    // Format as hex number wide enough to fit any value of the given `size`.
-                    // So data=20, size=1 will be "0x14", but with size=4 it'll be "0x00000014".
-                    write!(f, "0x{:>0width$x}", data, width = (size * 2) as usize)
-                }
-            }
-        }
-    }
-}
-
-impl<Tag> fmt::Display for Scalar<Tag> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match self {
-            Scalar::Ptr(_) => write!(f, "a pointer"),
-            Scalar::Raw { data, .. } => write!(f, "{}", data),
-        }
-    }
-}
-
-impl<Tag> From<Single> for Scalar<Tag> {
-    #[inline(always)]
-    fn from(f: Single) -> Self {
-        Scalar::from_f32(f)
-    }
-}
-
-impl<Tag> From<Double> for Scalar<Tag> {
-    #[inline(always)]
-    fn from(f: Double) -> Self {
-        Scalar::from_f64(f)
-    }
-}
-
-impl Scalar<()> {
-    #[inline(always)]
-    fn check_data(data: u128, size: u8) {
-        debug_assert_eq!(
-            truncate(data, Size::from_bytes(size as u64)),
-            data,
-            "Scalar value {:#x} exceeds size of {} bytes",
-            data,
-            size
-        );
-    }
-
-    /// Tag this scalar with `new_tag` if it is a pointer, leave it unchanged otherwise.
-    ///
-    /// Used by `MemPlace::replace_tag`.
-    #[inline]
-    pub fn with_tag<Tag>(self, new_tag: Tag) -> Scalar<Tag> {
-        match self {
-            Scalar::Ptr(ptr) => Scalar::Ptr(ptr.with_tag(new_tag)),
-            Scalar::Raw { data, size } => Scalar::Raw { data, size },
-        }
-    }
-}
-
-impl<'tcx, Tag> Scalar<Tag> {
-    /// Erase the tag from the scalar, if any.
-    ///
-    /// Used by error reporting code to avoid having the error type depend on `Tag`.
-    #[inline]
-    pub fn erase_tag(self) -> Scalar {
-        match self {
-            Scalar::Ptr(ptr) => Scalar::Ptr(ptr.erase_tag()),
-            Scalar::Raw { data, size } => Scalar::Raw { data, size },
-        }
-    }
-
-    #[inline]
-    pub fn ptr_null(cx: &impl HasDataLayout) -> Self {
-        Scalar::Raw { data: 0, size: cx.data_layout().pointer_size.bytes() as u8 }
-    }
-
-    #[inline]
-    pub fn zst() -> Self {
-        Scalar::Raw { data: 0, size: 0 }
-    }
-
-    #[inline]
-    pub fn ptr_offset(self, i: Size, cx: &impl HasDataLayout) -> InterpResult<'tcx, Self> {
-        let dl = cx.data_layout();
-        match self {
-            Scalar::Raw { data, size } => {
-                assert_eq!(size as u64, dl.pointer_size.bytes());
-                Ok(Scalar::Raw { data: dl.offset(data as u64, i.bytes())? as u128, size })
-            }
-            Scalar::Ptr(ptr) => ptr.offset(i, dl).map(Scalar::Ptr),
-        }
-    }
-
-    #[inline]
-    pub fn ptr_wrapping_offset(self, i: Size, cx: &impl HasDataLayout) -> Self {
-        let dl = cx.data_layout();
-        match self {
-            Scalar::Raw { data, size } => {
-                assert_eq!(size as u64, dl.pointer_size.bytes());
-                Scalar::Raw { data: dl.overflowing_offset(data as u64, i.bytes()).0 as u128, size }
-            }
-            Scalar::Ptr(ptr) => Scalar::Ptr(ptr.wrapping_offset(i, dl)),
-        }
-    }
-
-    #[inline]
-    pub fn ptr_signed_offset(self, i: i64, cx: &impl HasDataLayout) -> InterpResult<'tcx, Self> {
-        let dl = cx.data_layout();
-        match self {
-            Scalar::Raw { data, size } => {
-                assert_eq!(size as u64, dl.pointer_size().bytes());
-                Ok(Scalar::Raw { data: dl.signed_offset(data as u64, i)? as u128, size })
-            }
-            Scalar::Ptr(ptr) => ptr.signed_offset(i, dl).map(Scalar::Ptr),
-        }
-    }
-
-    #[inline]
-    pub fn ptr_wrapping_signed_offset(self, i: i64, cx: &impl HasDataLayout) -> Self {
-        let dl = cx.data_layout();
-        match self {
-            Scalar::Raw { data, size } => {
-                assert_eq!(size as u64, dl.pointer_size.bytes());
-                Scalar::Raw {
-                    data: dl.overflowing_signed_offset(data as u64, i128::from(i)).0 as u128,
-                    size,
-                }
-            }
-            Scalar::Ptr(ptr) => Scalar::Ptr(ptr.wrapping_signed_offset(i, dl)),
-        }
-    }
-
-    #[inline]
-    pub fn from_bool(b: bool) -> Self {
-        Scalar::Raw { data: b as u128, size: 1 }
-    }
-
-    #[inline]
-    pub fn from_char(c: char) -> Self {
-        Scalar::Raw { data: c as u128, size: 4 }
-    }
-
-    #[inline]
-    pub fn try_from_uint(i: impl Into<u128>, size: Size) -> Option<Self> {
-        let i = i.into();
-        if truncate(i, size) == i {
-            Some(Scalar::Raw { data: i, size: size.bytes() as u8 })
-        } else {
-            None
-        }
-    }
-
-    #[inline]
-    pub fn from_uint(i: impl Into<u128>, size: Size) -> Self {
-        let i = i.into();
-        Self::try_from_uint(i, size)
-            .unwrap_or_else(|| bug!("Unsigned value {:#x} does not fit in {} bits", i, size.bits()))
-    }
-
-    #[inline]
-    pub fn from_u8(i: u8) -> Self {
-        Scalar::Raw { data: i as u128, size: 1 }
-    }
-
-    #[inline]
-    pub fn from_u16(i: u16) -> Self {
-        Scalar::Raw { data: i as u128, size: 2 }
-    }
-
-    #[inline]
-    pub fn from_u32(i: u32) -> Self {
-        Scalar::Raw { data: i as u128, size: 4 }
-    }
-
-    #[inline]
-    pub fn from_u64(i: u64) -> Self {
-        Scalar::Raw { data: i as u128, size: 8 }
-    }
-
-    #[inline]
-    pub fn from_machine_usize(i: u64, cx: &impl HasDataLayout) -> Self {
-        Self::from_uint(i, cx.data_layout().pointer_size)
-    }
-
-    #[inline]
-    pub fn try_from_int(i: impl Into<i128>, size: Size) -> Option<Self> {
-        let i = i.into();
-        // `into` performed sign extension, we have to truncate
-        let truncated = truncate(i as u128, size);
-        if sign_extend(truncated, size) as i128 == i {
-            Some(Scalar::Raw { data: truncated, size: size.bytes() as u8 })
-        } else {
-            None
-        }
-    }
-
-    #[inline]
-    pub fn from_int(i: impl Into<i128>, size: Size) -> Self {
-        let i = i.into();
-        Self::try_from_int(i, size)
-            .unwrap_or_else(|| bug!("Signed value {:#x} does not fit in {} bits", i, size.bits()))
-    }
-
-    #[inline]
-    pub fn from_machine_isize(i: i64, cx: &impl HasDataLayout) -> Self {
-        Self::from_int(i, cx.data_layout().pointer_size)
-    }
-
-    #[inline]
-    pub fn from_f32(f: Single) -> Self {
-        // We trust apfloat to give us properly truncated data.
-        Scalar::Raw { data: f.to_bits(), size: 4 }
-    }
-
-    #[inline]
-    pub fn from_f64(f: Double) -> Self {
-        // We trust apfloat to give us properly truncated data.
-        Scalar::Raw { data: f.to_bits(), size: 8 }
-    }
-
-    /// This is very rarely the method you want!  You should dispatch on the type
-    /// and use `force_bits`/`assert_bits`/`force_ptr`/`assert_ptr`.
-    /// This method only exists for the benefit of low-level memory operations
-    /// as well as the implementation of the `force_*` methods.
-    #[inline]
-    pub fn to_bits_or_ptr(
-        self,
-        target_size: Size,
-        cx: &impl HasDataLayout,
-    ) -> Result<u128, Pointer<Tag>> {
-        match self {
-            Scalar::Raw { data, size } => {
-                assert_eq!(target_size.bytes(), size as u64);
-                assert_ne!(size, 0, "you should never look at the bits of a ZST");
-                Scalar::check_data(data, size);
-                Ok(data)
-            }
-            Scalar::Ptr(ptr) => {
-                assert_eq!(target_size, cx.data_layout().pointer_size);
-                Err(ptr)
-            }
-        }
-    }
-
-    #[inline(always)]
-    pub fn check_raw(data: u128, size: u8, target_size: Size) {
-        assert_eq!(target_size.bytes(), size as u64);
-        assert_ne!(size, 0, "you should never look at the bits of a ZST");
-        Scalar::check_data(data, size);
-    }
-
-    /// Do not call this method!  Use either `assert_bits` or `force_bits`.
-    #[inline]
-    pub fn to_bits(self, target_size: Size) -> InterpResult<'tcx, u128> {
-        match self {
-            Scalar::Raw { data, size } => {
-                Self::check_raw(data, size, target_size);
-                Ok(data)
-            }
-            Scalar::Ptr(_) => throw_unsup!(ReadPointerAsBytes),
-        }
-    }
-
-    #[inline(always)]
-    pub fn assert_bits(self, target_size: Size) -> u128 {
-        self.to_bits(target_size).expect("expected Raw bits but got a Pointer")
-    }
-
-    /// Do not call this method!  Use either `assert_ptr` or `force_ptr`.
-    /// This method is intentionally private, do not make it public.
-    #[inline]
-    fn to_ptr(self) -> InterpResult<'tcx, Pointer<Tag>> {
-        match self {
-            Scalar::Raw { data: 0, .. } => throw_unsup!(InvalidNullPointerUsage),
-            Scalar::Raw { .. } => throw_unsup!(ReadBytesAsPointer),
-            Scalar::Ptr(p) => Ok(p),
-        }
-    }
-
-    #[inline(always)]
-    pub fn assert_ptr(self) -> Pointer<Tag> {
-        self.to_ptr().expect("expected a Pointer but got Raw bits")
-    }
-
-    /// Do not call this method!  Dispatch based on the type instead.
-    #[inline]
-    pub fn is_bits(self) -> bool {
-        match self {
-            Scalar::Raw { .. } => true,
-            _ => false,
-        }
-    }
-
-    /// Do not call this method!  Dispatch based on the type instead.
-    #[inline]
-    pub fn is_ptr(self) -> bool {
-        match self {
-            Scalar::Ptr(_) => true,
-            _ => false,
-        }
-    }
-
-    pub fn to_bool(self) -> InterpResult<'tcx, bool> {
-        match self {
-            Scalar::Raw { data: 0, size: 1 } => Ok(false),
-            Scalar::Raw { data: 1, size: 1 } => Ok(true),
-            _ => throw_unsup!(InvalidBool),
-        }
-    }
-
-    pub fn to_char(self) -> InterpResult<'tcx, char> {
-        let val = self.to_u32()?;
-        match ::std::char::from_u32(val) {
-            Some(c) => Ok(c),
-            None => throw_unsup!(InvalidChar(val as u128)),
-        }
-    }
-
-    #[inline]
-    fn to_unsigned_with_bit_width(self, bits: u64) -> InterpResult<'static, u128> {
-        let sz = Size::from_bits(bits);
-        self.to_bits(sz)
-    }
-
-    /// Converts the scalar to produce an `u8`. Fails if the scalar is a pointer.
-    pub fn to_u8(self) -> InterpResult<'static, u8> {
-        self.to_unsigned_with_bit_width(8).map(|v| v as u8)
-    }
-
-    /// Converts the scalar to produce an `u16`. Fails if the scalar is a pointer.
-    pub fn to_u16(self) -> InterpResult<'static, u16> {
-        self.to_unsigned_with_bit_width(16).map(|v| v as u16)
-    }
-
-    /// Converts the scalar to produce an `u32`. Fails if the scalar is a pointer.
-    pub fn to_u32(self) -> InterpResult<'static, u32> {
-        self.to_unsigned_with_bit_width(32).map(|v| v as u32)
-    }
-
-    /// Converts the scalar to produce an `u64`. Fails if the scalar is a pointer.
-    pub fn to_u64(self) -> InterpResult<'static, u64> {
-        self.to_unsigned_with_bit_width(64).map(|v| v as u64)
-    }
-
-    pub fn to_machine_usize(self, cx: &impl HasDataLayout) -> InterpResult<'static, u64> {
-        let b = self.to_bits(cx.data_layout().pointer_size)?;
-        Ok(b as u64)
-    }
-
-    #[inline]
-    fn to_signed_with_bit_width(self, bits: u64) -> InterpResult<'static, i128> {
-        let sz = Size::from_bits(bits);
-        let b = self.to_bits(sz)?;
-        Ok(sign_extend(b, sz) as i128)
-    }
-
-    /// Converts the scalar to produce an `i8`. Fails if the scalar is a pointer.
-    pub fn to_i8(self) -> InterpResult<'static, i8> {
-        self.to_signed_with_bit_width(8).map(|v| v as i8)
-    }
-
-    /// Converts the scalar to produce an `i16`. Fails if the scalar is a pointer.
-    pub fn to_i16(self) -> InterpResult<'static, i16> {
-        self.to_signed_with_bit_width(16).map(|v| v as i16)
-    }
-
-    /// Converts the scalar to produce an `i32`. Fails if the scalar is a pointer.
-    pub fn to_i32(self) -> InterpResult<'static, i32> {
-        self.to_signed_with_bit_width(32).map(|v| v as i32)
-    }
-
-    /// Converts the scalar to produce an `i64`. Fails if the scalar is a pointer.
-    pub fn to_i64(self) -> InterpResult<'static, i64> {
-        self.to_signed_with_bit_width(64).map(|v| v as i64)
-    }
-
-    pub fn to_machine_isize(self, cx: &impl HasDataLayout) -> InterpResult<'static, i64> {
-        let sz = cx.data_layout().pointer_size;
-        let b = self.to_bits(sz)?;
-        let b = sign_extend(b, sz) as i128;
-        Ok(b as i64)
-    }
-
-    #[inline]
-    pub fn to_f32(self) -> InterpResult<'static, Single> {
-        // Going through `u32` to check size and truncation.
-        Ok(Single::from_bits(self.to_u32()? as u128))
-    }
-
-    #[inline]
-    pub fn to_f64(self) -> InterpResult<'static, Double> {
-        // Going through `u64` to check size and truncation.
-        Ok(Double::from_bits(self.to_u64()? as u128))
-    }
-}
-
-impl<Tag> From<Pointer<Tag>> for Scalar<Tag> {
-    #[inline(always)]
-    fn from(ptr: Pointer<Tag>) -> Self {
-        Scalar::Ptr(ptr)
-    }
-}
-
-#[derive(Clone, Copy, Eq, PartialEq, RustcEncodable, RustcDecodable, HashStable, Hash)]
-pub enum ScalarMaybeUndef<Tag = (), Id = AllocId> {
-    Scalar(Scalar<Tag, Id>),
-    Undef,
-}
-
-impl<Tag> From<Scalar<Tag>> for ScalarMaybeUndef<Tag> {
-    #[inline(always)]
-    fn from(s: Scalar<Tag>) -> Self {
-        ScalarMaybeUndef::Scalar(s)
-    }
-}
-
-impl<Tag> From<Pointer<Tag>> for ScalarMaybeUndef<Tag> {
-    #[inline(always)]
-    fn from(s: Pointer<Tag>) -> Self {
-        ScalarMaybeUndef::Scalar(s.into())
-    }
-}
-
-impl<Tag: fmt::Debug, Id: fmt::Debug> fmt::Debug for ScalarMaybeUndef<Tag, Id> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match self {
-            ScalarMaybeUndef::Undef => write!(f, "Undef"),
-            ScalarMaybeUndef::Scalar(s) => write!(f, "{:?}", s),
-        }
-    }
-}
-
-impl<Tag> fmt::Display for ScalarMaybeUndef<Tag> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match self {
-            ScalarMaybeUndef::Undef => write!(f, "uninitialized bytes"),
-            ScalarMaybeUndef::Scalar(s) => write!(f, "{}", s),
-        }
-    }
-}
-
-impl<'tcx, Tag> ScalarMaybeUndef<Tag> {
-    /// Erase the tag from the scalar, if any.
-    ///
-    /// Used by error reporting code to avoid having the error type depend on `Tag`.
-    #[inline]
-    pub fn erase_tag(self) -> ScalarMaybeUndef {
-        match self {
-            ScalarMaybeUndef::Scalar(s) => ScalarMaybeUndef::Scalar(s.erase_tag()),
-            ScalarMaybeUndef::Undef => ScalarMaybeUndef::Undef,
-        }
-    }
-
-    #[inline]
-    pub fn not_undef(self) -> InterpResult<'static, Scalar<Tag>> {
-        match self {
-            ScalarMaybeUndef::Scalar(scalar) => Ok(scalar),
-            ScalarMaybeUndef::Undef => throw_unsup!(ReadUndefBytes(Size::ZERO)),
-        }
-    }
-
-    /// Do not call this method!  Use either `assert_bits` or `force_bits`.
-    #[inline(always)]
-    pub fn to_bits(self, target_size: Size) -> InterpResult<'tcx, u128> {
-        self.not_undef()?.to_bits(target_size)
-    }
-
-    #[inline(always)]
-    pub fn to_bool(self) -> InterpResult<'tcx, bool> {
-        self.not_undef()?.to_bool()
-    }
-
-    #[inline(always)]
-    pub fn to_char(self) -> InterpResult<'tcx, char> {
-        self.not_undef()?.to_char()
-    }
-
-    #[inline(always)]
-    pub fn to_f32(self) -> InterpResult<'tcx, Single> {
-        self.not_undef()?.to_f32()
-    }
-
-    #[inline(always)]
-    pub fn to_f64(self) -> InterpResult<'tcx, Double> {
-        self.not_undef()?.to_f64()
-    }
-
-    #[inline(always)]
-    pub fn to_u8(self) -> InterpResult<'tcx, u8> {
-        self.not_undef()?.to_u8()
-    }
-
-    #[inline(always)]
-    pub fn to_u32(self) -> InterpResult<'tcx, u32> {
-        self.not_undef()?.to_u32()
-    }
-
-    #[inline(always)]
-    pub fn to_u64(self) -> InterpResult<'tcx, u64> {
-        self.not_undef()?.to_u64()
-    }
-
-    #[inline(always)]
-    pub fn to_machine_usize(self, cx: &impl HasDataLayout) -> InterpResult<'tcx, u64> {
-        self.not_undef()?.to_machine_usize(cx)
-    }
-
-    #[inline(always)]
-    pub fn to_i8(self) -> InterpResult<'tcx, i8> {
-        self.not_undef()?.to_i8()
-    }
-
-    #[inline(always)]
-    pub fn to_i32(self) -> InterpResult<'tcx, i32> {
-        self.not_undef()?.to_i32()
-    }
-
-    #[inline(always)]
-    pub fn to_i64(self) -> InterpResult<'tcx, i64> {
-        self.not_undef()?.to_i64()
-    }
-
-    #[inline(always)]
-    pub fn to_machine_isize(self, cx: &impl HasDataLayout) -> InterpResult<'tcx, i64> {
-        self.not_undef()?.to_machine_isize(cx)
-    }
-}
-
-/// Gets the bytes of a constant slice value.
-pub fn get_slice_bytes<'tcx>(cx: &impl HasDataLayout, val: ConstValue<'tcx>) -> &'tcx [u8] {
-    if let ConstValue::Slice { data, start, end } = val {
-        let len = end - start;
-        data.get_bytes(
-            cx,
-            // invent a pointer, only the offset is relevant anyway
-            Pointer::new(AllocId(0), Size::from_bytes(start as u64)),
-            Size::from_bytes(len as u64),
-        )
-        .unwrap_or_else(|err| bug!("const slice is invalid: {:?}", err))
-    } else {
-        bug!("expected const slice, but found another const value");
-    }
-}
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
deleted file mode 100644
index 3086f9b04df..00000000000
--- a/src/librustc/mir/mod.rs
+++ /dev/null
@@ -1,2995 +0,0 @@
-//! MIR datatypes and passes. See the [rustc guide] for more info.
-//!
-//! [rustc guide]: https://rust-lang.github.io/rustc-guide/mir/index.html
-
-use crate::mir::interpret::{GlobalAlloc, Scalar};
-use crate::mir::visit::MirVisitable;
-use crate::ty::adjustment::PointerCast;
-use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
-use crate::ty::layout::VariantIdx;
-use crate::ty::print::{FmtPrinter, Printer};
-use crate::ty::subst::{Subst, SubstsRef};
-use crate::ty::{
-    self, AdtDef, CanonicalUserTypeAnnotations, List, Region, Ty, TyCtxt, UserTypeAnnotationIndex,
-};
-use rustc_hir as hir;
-use rustc_hir::def::{CtorKind, Namespace};
-use rustc_hir::def_id::DefId;
-use rustc_hir::{self, GeneratorKind};
-
-use polonius_engine::Atom;
-use rustc_data_structures::fx::FxHashSet;
-use rustc_data_structures::graph::dominators::Dominators;
-use rustc_data_structures::graph::{self, GraphSuccessors};
-use rustc_index::bit_set::BitMatrix;
-use rustc_index::vec::{Idx, IndexVec};
-use rustc_macros::HashStable;
-use rustc_serialize::{Decodable, Encodable};
-use rustc_span::symbol::Symbol;
-use rustc_span::{Span, DUMMY_SP};
-use std::borrow::Cow;
-use std::fmt::{self, Debug, Display, Formatter, Write};
-use std::ops::Index;
-use std::slice;
-use std::{iter, mem, option, u32};
-pub use syntax::ast::Mutability;
-use syntax::ast::Name;
-
-pub use self::cache::{BodyAndCache, ReadOnlyBodyAndCache};
-pub use self::query::*;
-pub use crate::read_only;
-
-mod cache;
-pub mod interpret;
-pub mod mono;
-mod query;
-pub mod tcx;
-pub mod traversal;
-pub mod visit;
-
-/// Types for locals
-type LocalDecls<'tcx> = IndexVec<Local, LocalDecl<'tcx>>;
-
-pub trait HasLocalDecls<'tcx> {
-    fn local_decls(&self) -> &LocalDecls<'tcx>;
-}
-
-impl<'tcx> HasLocalDecls<'tcx> for LocalDecls<'tcx> {
-    fn local_decls(&self) -> &LocalDecls<'tcx> {
-        self
-    }
-}
-
-impl<'tcx> HasLocalDecls<'tcx> for Body<'tcx> {
-    fn local_decls(&self) -> &LocalDecls<'tcx> {
-        &self.local_decls
-    }
-}
-
-/// The various "big phases" that MIR goes through.
-///
-/// Warning: ordering of variants is significant.
-#[derive(
-    Copy,
-    Clone,
-    RustcEncodable,
-    RustcDecodable,
-    HashStable,
-    Debug,
-    PartialEq,
-    Eq,
-    PartialOrd,
-    Ord
-)]
-pub enum MirPhase {
-    Build = 0,
-    Const = 1,
-    Validated = 2,
-    Optimized = 3,
-}
-
-impl MirPhase {
-    /// Gets the index of the current MirPhase within the set of all `MirPhase`s.
-    pub fn phase_index(&self) -> usize {
-        *self as usize
-    }
-}
-
-/// The lowered representation of a single function.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable, TypeFoldable)]
-pub struct Body<'tcx> {
-    /// A list of basic blocks. References to basic block use a newtyped index type `BasicBlock`
-    /// that indexes into this vector.
-    basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>,
-
-    /// Records how far through the "desugaring and optimization" process this particular
-    /// MIR has traversed. This is particularly useful when inlining, since in that context
-    /// we instantiate the promoted constants and add them to our promoted vector -- but those
-    /// promoted items have already been optimized, whereas ours have not. This field allows
-    /// us to see the difference and forego optimization on the inlined promoted items.
-    pub phase: MirPhase,
-
-    /// A list of source scopes; these are referenced by statements
-    /// and used for debuginfo. Indexed by a `SourceScope`.
-    pub source_scopes: IndexVec<SourceScope, SourceScopeData>,
-
-    /// The yield type of the function, if it is a generator.
-    pub yield_ty: Option<Ty<'tcx>>,
-
-    /// Generator drop glue.
-    pub generator_drop: Option<Box<BodyAndCache<'tcx>>>,
-
-    /// The layout of a generator. Produced by the state transformation.
-    pub generator_layout: Option<GeneratorLayout<'tcx>>,
-
-    /// If this is a generator then record the type of source expression that caused this generator
-    /// to be created.
-    pub generator_kind: Option<GeneratorKind>,
-
-    /// Declarations of locals.
-    ///
-    /// The first local is the return value pointer, followed by `arg_count`
-    /// locals for the function arguments, followed by any user-declared
-    /// variables and temporaries.
-    pub local_decls: LocalDecls<'tcx>,
-
-    /// User type annotations.
-    pub user_type_annotations: CanonicalUserTypeAnnotations<'tcx>,
-
-    /// The number of arguments this function takes.
-    ///
-    /// Starting at local 1, `arg_count` locals will be provided by the caller
-    /// and can be assumed to be initialized.
-    ///
-    /// If this MIR was built for a constant, this will be 0.
-    pub arg_count: usize,
-
-    /// Mark an argument local (which must be a tuple) as getting passed as
-    /// its individual components at the LLVM level.
-    ///
-    /// This is used for the "rust-call" ABI.
-    pub spread_arg: Option<Local>,
-
-    /// Debug information pertaining to user variables, including captures.
-    pub var_debug_info: Vec<VarDebugInfo<'tcx>>,
-
-    /// Mark this MIR of a const context other than const functions as having converted a `&&` or
-    /// `||` expression into `&` or `|` respectively. This is problematic because if we ever stop
-    /// this conversion from happening and use short circuiting, we will cause the following code
-    /// to change the value of `x`: `let mut x = 42; false && { x = 55; true };`
-    ///
-    /// List of places where control flow was destroyed. Used for error reporting.
-    pub control_flow_destroyed: Vec<(Span, String)>,
-
-    /// A span representing this MIR, for error reporting.
-    pub span: Span,
-
-    /// The user may be writing e.g. &[(SOME_CELL, 42)][i].1 and this would get promoted, because
-    /// we'd statically know that no thing with interior mutability will ever be available to the
-    /// user without some serious unsafe code.  Now this means that our promoted is actually
-    /// &[(SOME_CELL, 42)] and the MIR using it will do the &promoted[i].1 projection because the
-    /// index may be a runtime value. Such a promoted value is illegal because it has reachable
-    /// interior mutability. This flag just makes this situation very obvious where the previous
-    /// implementation without the flag hid this situation silently.
-    /// FIXME(oli-obk): rewrite the promoted during promotion to eliminate the cell components.
-    pub ignore_interior_mut_in_const_validation: bool,
-}
-
-impl<'tcx> Body<'tcx> {
-    pub fn new(
-        basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>,
-        source_scopes: IndexVec<SourceScope, SourceScopeData>,
-        local_decls: LocalDecls<'tcx>,
-        user_type_annotations: CanonicalUserTypeAnnotations<'tcx>,
-        arg_count: usize,
-        var_debug_info: Vec<VarDebugInfo<'tcx>>,
-        span: Span,
-        control_flow_destroyed: Vec<(Span, String)>,
-        generator_kind: Option<GeneratorKind>,
-    ) -> Self {
-        // We need `arg_count` locals, and one for the return place.
-        assert!(
-            local_decls.len() >= arg_count + 1,
-            "expected at least {} locals, got {}",
-            arg_count + 1,
-            local_decls.len()
-        );
-
-        Body {
-            phase: MirPhase::Build,
-            basic_blocks,
-            source_scopes,
-            yield_ty: None,
-            generator_drop: None,
-            generator_layout: None,
-            generator_kind,
-            local_decls,
-            user_type_annotations,
-            arg_count,
-            spread_arg: None,
-            var_debug_info,
-            span,
-            ignore_interior_mut_in_const_validation: false,
-            control_flow_destroyed,
-        }
-    }
-
-    /// Returns a partially initialized MIR body containing only a list of basic blocks.
-    ///
-    /// The returned MIR contains no `LocalDecl`s (even for the return place) or source scopes. It
-    /// is only useful for testing but cannot be `#[cfg(test)]` because it is used in a different
-    /// crate.
-    pub fn new_cfg_only(basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>) -> Self {
-        Body {
-            phase: MirPhase::Build,
-            basic_blocks,
-            source_scopes: IndexVec::new(),
-            yield_ty: None,
-            generator_drop: None,
-            generator_layout: None,
-            local_decls: IndexVec::new(),
-            user_type_annotations: IndexVec::new(),
-            arg_count: 0,
-            spread_arg: None,
-            span: DUMMY_SP,
-            control_flow_destroyed: Vec::new(),
-            generator_kind: None,
-            var_debug_info: Vec::new(),
-            ignore_interior_mut_in_const_validation: false,
-        }
-    }
-
-    #[inline]
-    pub fn basic_blocks(&self) -> &IndexVec<BasicBlock, BasicBlockData<'tcx>> {
-        &self.basic_blocks
-    }
-
-    /// Returns `true` if a cycle exists in the control-flow graph that is reachable from the
-    /// `START_BLOCK`.
-    pub fn is_cfg_cyclic(&self) -> bool {
-        graph::is_cyclic(self)
-    }
-
-    #[inline]
-    pub fn local_kind(&self, local: Local) -> LocalKind {
-        let index = local.as_usize();
-        if index == 0 {
-            debug_assert!(
-                self.local_decls[local].mutability == Mutability::Mut,
-                "return place should be mutable"
-            );
-
-            LocalKind::ReturnPointer
-        } else if index < self.arg_count + 1 {
-            LocalKind::Arg
-        } else if self.local_decls[local].is_user_variable() {
-            LocalKind::Var
-        } else {
-            LocalKind::Temp
-        }
-    }
-
-    /// Returns an iterator over all temporaries.
-    #[inline]
-    pub fn temps_iter<'a>(&'a self) -> impl Iterator<Item = Local> + 'a {
-        (self.arg_count + 1..self.local_decls.len()).filter_map(move |index| {
-            let local = Local::new(index);
-            if self.local_decls[local].is_user_variable() { None } else { Some(local) }
-        })
-    }
-
-    /// Returns an iterator over all user-declared locals.
-    #[inline]
-    pub fn vars_iter<'a>(&'a self) -> impl Iterator<Item = Local> + 'a {
-        (self.arg_count + 1..self.local_decls.len()).filter_map(move |index| {
-            let local = Local::new(index);
-            self.local_decls[local].is_user_variable().then_some(local)
-        })
-    }
-
-    /// Returns an iterator over all user-declared mutable locals.
-    #[inline]
-    pub fn mut_vars_iter<'a>(&'a self) -> impl Iterator<Item = Local> + 'a {
-        (self.arg_count + 1..self.local_decls.len()).filter_map(move |index| {
-            let local = Local::new(index);
-            let decl = &self.local_decls[local];
-            if decl.is_user_variable() && decl.mutability == Mutability::Mut {
-                Some(local)
-            } else {
-                None
-            }
-        })
-    }
-
-    /// Returns an iterator over all user-declared mutable arguments and locals.
-    #[inline]
-    pub fn mut_vars_and_args_iter<'a>(&'a self) -> impl Iterator<Item = Local> + 'a {
-        (1..self.local_decls.len()).filter_map(move |index| {
-            let local = Local::new(index);
-            let decl = &self.local_decls[local];
-            if (decl.is_user_variable() || index < self.arg_count + 1)
-                && decl.mutability == Mutability::Mut
-            {
-                Some(local)
-            } else {
-                None
-            }
-        })
-    }
-
-    /// Returns an iterator over all function arguments.
-    #[inline]
-    pub fn args_iter(&self) -> impl Iterator<Item = Local> + ExactSizeIterator {
-        let arg_count = self.arg_count;
-        (1..arg_count + 1).map(Local::new)
-    }
-
-    /// Returns an iterator over all user-defined variables and compiler-generated temporaries (all
-    /// locals that are neither arguments nor the return place).
-    #[inline]
-    pub fn vars_and_temps_iter(&self) -> impl Iterator<Item = Local> + ExactSizeIterator {
-        let arg_count = self.arg_count;
-        let local_count = self.local_decls.len();
-        (arg_count + 1..local_count).map(Local::new)
-    }
-
-    /// Changes a statement to a nop. This is both faster than deleting instructions and avoids
-    /// invalidating statement indices in `Location`s.
-    pub fn make_statement_nop(&mut self, location: Location) {
-        let block = &mut self.basic_blocks[location.block];
-        debug_assert!(location.statement_index < block.statements.len());
-        block.statements[location.statement_index].make_nop()
-    }
-
-    /// Returns the source info associated with `location`.
-    pub fn source_info(&self, location: Location) -> &SourceInfo {
-        let block = &self[location.block];
-        let stmts = &block.statements;
-        let idx = location.statement_index;
-        if idx < stmts.len() {
-            &stmts[idx].source_info
-        } else {
-            assert_eq!(idx, stmts.len());
-            &block.terminator().source_info
-        }
-    }
-
-    /// Checks if `sub` is a sub scope of `sup`
-    pub fn is_sub_scope(&self, mut sub: SourceScope, sup: SourceScope) -> bool {
-        while sub != sup {
-            match self.source_scopes[sub].parent_scope {
-                None => return false,
-                Some(p) => sub = p,
-            }
-        }
-        true
-    }
-
-    /// Returns the return type; it always return first element from `local_decls` array.
-    pub fn return_ty(&self) -> Ty<'tcx> {
-        self.local_decls[RETURN_PLACE].ty
-    }
-
-    /// Gets the location of the terminator for the given block.
-    pub fn terminator_loc(&self, bb: BasicBlock) -> Location {
-        Location { block: bb, statement_index: self[bb].statements.len() }
-    }
-}
-
-#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
-pub enum Safety {
-    Safe,
-    /// Unsafe because of a PushUnsafeBlock
-    BuiltinUnsafe,
-    /// Unsafe because of an unsafe fn
-    FnUnsafe,
-    /// Unsafe because of an `unsafe` block
-    ExplicitUnsafe(hir::HirId),
-}
-
-impl<'tcx> Index<BasicBlock> for Body<'tcx> {
-    type Output = BasicBlockData<'tcx>;
-
-    #[inline]
-    fn index(&self, index: BasicBlock) -> &BasicBlockData<'tcx> {
-        &self.basic_blocks()[index]
-    }
-}
-
-#[derive(Copy, Clone, Debug, HashStable, TypeFoldable)]
-pub enum ClearCrossCrate<T> {
-    Clear,
-    Set(T),
-}
-
-impl<T> ClearCrossCrate<T> {
-    pub fn as_ref(&'a self) -> ClearCrossCrate<&'a T> {
-        match self {
-            ClearCrossCrate::Clear => ClearCrossCrate::Clear,
-            ClearCrossCrate::Set(v) => ClearCrossCrate::Set(v),
-        }
-    }
-
-    pub fn assert_crate_local(self) -> T {
-        match self {
-            ClearCrossCrate::Clear => bug!("unwrapping cross-crate data"),
-            ClearCrossCrate::Set(v) => v,
-        }
-    }
-}
-
-impl<T: Encodable> rustc_serialize::UseSpecializedEncodable for ClearCrossCrate<T> {}
-impl<T: Decodable> rustc_serialize::UseSpecializedDecodable for ClearCrossCrate<T> {}
-
-/// Grouped information about the source code origin of a MIR entity.
-/// Intended to be inspected by diagnostics and debuginfo.
-/// Most passes can work with it as a whole, within a single function.
-// The unofficial Cranelift backend, at least as of #65828, needs `SourceInfo` to implement `Eq` and
-// `Hash`. Please ping @bjorn3 if removing them.
-#[derive(Copy, Clone, Debug, Eq, PartialEq, RustcEncodable, RustcDecodable, Hash, HashStable)]
-pub struct SourceInfo {
-    /// The source span for the AST pertaining to this MIR entity.
-    pub span: Span,
-
-    /// The source scope, keeping track of which bindings can be
-    /// seen by debuginfo, active lint levels, `unsafe {...}`, etc.
-    pub scope: SourceScope,
-}
-
-///////////////////////////////////////////////////////////////////////////
-// Borrow kinds
-
-#[derive(
-    Copy,
-    Clone,
-    Debug,
-    PartialEq,
-    Eq,
-    PartialOrd,
-    Ord,
-    RustcEncodable,
-    RustcDecodable,
-    HashStable
-)]
-pub enum BorrowKind {
-    /// Data must be immutable and is aliasable.
-    Shared,
-
-    /// The immediately borrowed place must be immutable, but projections from
-    /// it don't need to be. For example, a shallow borrow of `a.b` doesn't
-    /// conflict with a mutable borrow of `a.b.c`.
-    ///
-    /// This is used when lowering matches: when matching on a place we want to
-    /// ensure that place have the same value from the start of the match until
-    /// an arm is selected. This prevents this code from compiling:
-    ///
-    ///     let mut x = &Some(0);
-    ///     match *x {
-    ///         None => (),
-    ///         Some(_) if { x = &None; false } => (),
-    ///         Some(_) => (),
-    ///     }
-    ///
-    /// This can't be a shared borrow because mutably borrowing (*x as Some).0
-    /// should not prevent `if let None = x { ... }`, for example, because the
-    /// mutating `(*x as Some).0` can't affect the discriminant of `x`.
-    /// We can also report errors with this kind of borrow differently.
-    Shallow,
-
-    /// Data must be immutable but not aliasable. This kind of borrow
-    /// cannot currently be expressed by the user and is used only in
-    /// implicit closure bindings. It is needed when the closure is
-    /// borrowing or mutating a mutable referent, e.g.:
-    ///
-    ///     let x: &mut isize = ...;
-    ///     let y = || *x += 5;
-    ///
-    /// If we were to try to translate this closure into a more explicit
-    /// form, we'd encounter an error with the code as written:
-    ///
-    ///     struct Env { x: & &mut isize }
-    ///     let x: &mut isize = ...;
-    ///     let y = (&mut Env { &x }, fn_ptr);  // Closure is pair of env and fn
-    ///     fn fn_ptr(env: &mut Env) { **env.x += 5; }
-    ///
-    /// This is then illegal because you cannot mutate an `&mut` found
-    /// in an aliasable location. To solve, you'd have to translate with
-    /// an `&mut` borrow:
-    ///
-    ///     struct Env { x: & &mut isize }
-    ///     let x: &mut isize = ...;
-    ///     let y = (&mut Env { &mut x }, fn_ptr); // changed from &x to &mut x
-    ///     fn fn_ptr(env: &mut Env) { **env.x += 5; }
-    ///
-    /// Now the assignment to `**env.x` is legal, but creating a
-    /// mutable pointer to `x` is not because `x` is not mutable. We
-    /// could fix this by declaring `x` as `let mut x`. This is ok in
-    /// user code, if awkward, but extra weird for closures, since the
-    /// borrow is hidden.
-    ///
-    /// So we introduce a "unique imm" borrow -- the referent is
-    /// immutable, but not aliasable. This solves the problem. For
-    /// simplicity, we don't give users the way to express this
-    /// borrow, it's just used when translating closures.
-    Unique,
-
-    /// Data is mutable and not aliasable.
-    Mut {
-        /// `true` if this borrow arose from method-call auto-ref
-        /// (i.e., `adjustment::Adjust::Borrow`).
-        allow_two_phase_borrow: bool,
-    },
-}
-
-impl BorrowKind {
-    pub fn allows_two_phase_borrow(&self) -> bool {
-        match *self {
-            BorrowKind::Shared | BorrowKind::Shallow | BorrowKind::Unique => false,
-            BorrowKind::Mut { allow_two_phase_borrow } => allow_two_phase_borrow,
-        }
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////
-// Variables and temps
-
-rustc_index::newtype_index! {
-    pub struct Local {
-        derive [HashStable]
-        DEBUG_FORMAT = "_{}",
-        const RETURN_PLACE = 0,
-    }
-}
-
-impl Atom for Local {
-    fn index(self) -> usize {
-        Idx::index(self)
-    }
-}
-
-/// Classifies locals into categories. See `Body::local_kind`.
-#[derive(PartialEq, Eq, Debug, HashStable)]
-pub enum LocalKind {
-    /// User-declared variable binding.
-    Var,
-    /// Compiler-introduced temporary.
-    Temp,
-    /// Function argument.
-    Arg,
-    /// Location of function's return value.
-    ReturnPointer,
-}
-
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
-pub struct VarBindingForm<'tcx> {
-    /// Is variable bound via `x`, `mut x`, `ref x`, or `ref mut x`?
-    pub binding_mode: ty::BindingMode,
-    /// If an explicit type was provided for this variable binding,
-    /// this holds the source Span of that type.
-    ///
-    /// NOTE: if you want to change this to a `HirId`, be wary that
-    /// doing so breaks incremental compilation (as of this writing),
-    /// while a `Span` does not cause our tests to fail.
-    pub opt_ty_info: Option<Span>,
-    /// Place of the RHS of the =, or the subject of the `match` where this
-    /// variable is initialized. None in the case of `let PATTERN;`.
-    /// Some((None, ..)) in the case of and `let [mut] x = ...` because
-    /// (a) the right-hand side isn't evaluated as a place expression.
-    /// (b) it gives a way to separate this case from the remaining cases
-    ///     for diagnostics.
-    pub opt_match_place: Option<(Option<Place<'tcx>>, Span)>,
-    /// The span of the pattern in which this variable was bound.
-    pub pat_span: Span,
-}
-
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
-pub enum BindingForm<'tcx> {
-    /// This is a binding for a non-`self` binding, or a `self` that has an explicit type.
-    Var(VarBindingForm<'tcx>),
-    /// Binding for a `self`/`&self`/`&mut self` binding where the type is implicit.
-    ImplicitSelf(ImplicitSelfKind),
-    /// Reference used in a guard expression to ensure immutability.
-    RefForGuard,
-}
-
-/// Represents what type of implicit self a function has, if any.
-#[derive(Clone, Copy, PartialEq, Debug, RustcEncodable, RustcDecodable, HashStable)]
-pub enum ImplicitSelfKind {
-    /// Represents a `fn x(self);`.
-    Imm,
-    /// Represents a `fn x(mut self);`.
-    Mut,
-    /// Represents a `fn x(&self);`.
-    ImmRef,
-    /// Represents a `fn x(&mut self);`.
-    MutRef,
-    /// Represents when a function does not have a self argument or
-    /// when a function has a `self: X` argument.
-    None,
-}
-
-CloneTypeFoldableAndLiftImpls! { BindingForm<'tcx>, }
-
-mod binding_form_impl {
-    use crate::ich::StableHashingContext;
-    use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
-
-    impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for super::BindingForm<'tcx> {
-        fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-            use super::BindingForm::*;
-            ::std::mem::discriminant(self).hash_stable(hcx, hasher);
-
-            match self {
-                Var(binding) => binding.hash_stable(hcx, hasher),
-                ImplicitSelf(kind) => kind.hash_stable(hcx, hasher),
-                RefForGuard => (),
-            }
-        }
-    }
-}
-
-/// `BlockTailInfo` is attached to the `LocalDecl` for temporaries
-/// created during evaluation of expressions in a block tail
-/// expression; that is, a block like `{ STMT_1; STMT_2; EXPR }`.
-///
-/// It is used to improve diagnostics when such temporaries are
-/// involved in borrow_check errors, e.g., explanations of where the
-/// temporaries come from, when their destructors are run, and/or how
-/// one might revise the code to satisfy the borrow checker's rules.
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
-pub struct BlockTailInfo {
-    /// If `true`, then the value resulting from evaluating this tail
-    /// expression is ignored by the block's expression context.
-    ///
-    /// Examples include `{ ...; tail };` and `let _ = { ...; tail };`
-    /// but not e.g., `let _x = { ...; tail };`
-    pub tail_result_is_ignored: bool,
-}
-
-/// A MIR local.
-///
-/// This can be a binding declared by the user, a temporary inserted by the compiler, a function
-/// argument, or the return place.
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
-pub struct LocalDecl<'tcx> {
-    /// Whether this is a mutable minding (i.e., `let x` or `let mut x`).
-    ///
-    /// Temporaries and the return place are always mutable.
-    pub mutability: Mutability,
-
-    // FIXME(matthewjasper) Don't store in this in `Body`
-    pub local_info: LocalInfo<'tcx>,
-
-    /// `true` if this is an internal local.
-    ///
-    /// These locals are not based on types in the source code and are only used
-    /// for a few desugarings at the moment.
-    ///
-    /// The generator transformation will sanity check the locals which are live
-    /// across a suspension point against the type components of the generator
-    /// which type checking knows are live across a suspension point. We need to
-    /// flag drop flags to avoid triggering this check as they are introduced
-    /// after typeck.
-    ///
-    /// Unsafety checking will also ignore dereferences of these locals,
-    /// so they can be used for raw pointers only used in a desugaring.
-    ///
-    /// This should be sound because the drop flags are fully algebraic, and
-    /// therefore don't affect the OIBIT or outlives properties of the
-    /// generator.
-    pub internal: bool,
-
-    /// If this local is a temporary and `is_block_tail` is `Some`,
-    /// then it is a temporary created for evaluation of some
-    /// subexpression of some block's tail expression (with no
-    /// intervening statement context).
-    // FIXME(matthewjasper) Don't store in this in `Body`
-    pub is_block_tail: Option<BlockTailInfo>,
-
-    /// The type of this local.
-    pub ty: Ty<'tcx>,
-
-    /// If the user manually ascribed a type to this variable,
-    /// e.g., via `let x: T`, then we carry that type here. The MIR
-    /// borrow checker needs this information since it can affect
-    /// region inference.
-    // FIXME(matthewjasper) Don't store in this in `Body`
-    pub user_ty: UserTypeProjections,
-
-    /// The *syntactic* (i.e., not visibility) source scope the local is defined
-    /// in. If the local was defined in a let-statement, this
-    /// is *within* the let-statement, rather than outside
-    /// of it.
-    ///
-    /// This is needed because the visibility source scope of locals within
-    /// a let-statement is weird.
-    ///
-    /// The reason is that we want the local to be *within* the let-statement
-    /// for lint purposes, but we want the local to be *after* the let-statement
-    /// for names-in-scope purposes.
-    ///
-    /// That's it, if we have a let-statement like the one in this
-    /// function:
-    ///
-    /// ```
-    /// fn foo(x: &str) {
-    ///     #[allow(unused_mut)]
-    ///     let mut x: u32 = { // <- one unused mut
-    ///         let mut y: u32 = x.parse().unwrap();
-    ///         y + 2
-    ///     };
-    ///     drop(x);
-    /// }
-    /// ```
-    ///
-    /// Then, from a lint point of view, the declaration of `x: u32`
-    /// (and `y: u32`) are within the `#[allow(unused_mut)]` scope - the
-    /// lint scopes are the same as the AST/HIR nesting.
-    ///
-    /// However, from a name lookup point of view, the scopes look more like
-    /// as if the let-statements were `match` expressions:
-    ///
-    /// ```
-    /// fn foo(x: &str) {
-    ///     match {
-    ///         match x.parse().unwrap() {
-    ///             y => y + 2
-    ///         }
-    ///     } {
-    ///         x => drop(x)
-    ///     };
-    /// }
-    /// ```
-    ///
-    /// We care about the name-lookup scopes for debuginfo - if the
-    /// debuginfo instruction pointer is at the call to `x.parse()`, we
-    /// want `x` to refer to `x: &str`, but if it is at the call to
-    /// `drop(x)`, we want it to refer to `x: u32`.
-    ///
-    /// To allow both uses to work, we need to have more than a single scope
-    /// for a local. We have the `source_info.scope` represent the "syntactic"
-    /// lint scope (with a variable being under its let block) while the
-    /// `var_debug_info.source_info.scope` represents the "local variable"
-    /// scope (where the "rest" of a block is under all prior let-statements).
-    ///
-    /// The end result looks like this:
-    ///
-    /// ```text
-    /// ROOT SCOPE
-    ///  │{ argument x: &str }
-    ///  │
-    ///  │ │{ #[allow(unused_mut)] } // This is actually split into 2 scopes
-    ///  │ │                         // in practice because I'm lazy.
-    ///  │ │
-    ///  │ │← x.source_info.scope
-    ///  │ │← `x.parse().unwrap()`
-    ///  │ │
-    ///  │ │ │← y.source_info.scope
-    ///  │ │
-    ///  │ │ │{ let y: u32 }
-    ///  │ │ │
-    ///  │ │ │← y.var_debug_info.source_info.scope
-    ///  │ │ │← `y + 2`
-    ///  │
-    ///  │ │{ let x: u32 }
-    ///  │ │← x.var_debug_info.source_info.scope
-    ///  │ │← `drop(x)` // This accesses `x: u32`.
-    /// ```
-    pub source_info: SourceInfo,
-}
-
-/// Extra information about a local that's used for diagnostics.
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
-pub enum LocalInfo<'tcx> {
-    /// A user-defined local variable or function parameter
-    ///
-    /// The `BindingForm` is solely used for local diagnostics when generating
-    /// warnings/errors when compiling the current crate, and therefore it need
-    /// not be visible across crates.
-    User(ClearCrossCrate<BindingForm<'tcx>>),
-    /// A temporary created that references the static with the given `DefId`.
-    StaticRef { def_id: DefId, is_thread_local: bool },
-    /// Any other temporary, the return place, or an anonymous function parameter.
-    Other,
-}
-
-impl<'tcx> LocalDecl<'tcx> {
-    /// Returns `true` only if local is a binding that can itself be
-    /// made mutable via the addition of the `mut` keyword, namely
-    /// something like the occurrences of `x` in:
-    /// - `fn foo(x: Type) { ... }`,
-    /// - `let x = ...`,
-    /// - or `match ... { C(x) => ... }`
-    pub fn can_be_made_mutable(&self) -> bool {
-        match self.local_info {
-            LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(VarBindingForm {
-                binding_mode: ty::BindingMode::BindByValue(_),
-                opt_ty_info: _,
-                opt_match_place: _,
-                pat_span: _,
-            }))) => true,
-
-            LocalInfo::User(ClearCrossCrate::Set(BindingForm::ImplicitSelf(
-                ImplicitSelfKind::Imm,
-            ))) => true,
-
-            _ => false,
-        }
-    }
-
-    /// Returns `true` if local is definitely not a `ref ident` or
-    /// `ref mut ident` binding. (Such bindings cannot be made into
-    /// mutable bindings, but the inverse does not necessarily hold).
-    pub fn is_nonref_binding(&self) -> bool {
-        match self.local_info {
-            LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(VarBindingForm {
-                binding_mode: ty::BindingMode::BindByValue(_),
-                opt_ty_info: _,
-                opt_match_place: _,
-                pat_span: _,
-            }))) => true,
-
-            LocalInfo::User(ClearCrossCrate::Set(BindingForm::ImplicitSelf(_))) => true,
-
-            _ => false,
-        }
-    }
-
-    /// Returns `true` if this variable is a named variable or function
-    /// parameter declared by the user.
-    #[inline]
-    pub fn is_user_variable(&self) -> bool {
-        match self.local_info {
-            LocalInfo::User(_) => true,
-            _ => false,
-        }
-    }
-
-    /// Returns `true` if this is a reference to a variable bound in a `match`
-    /// expression that is used to access said variable for the guard of the
-    /// match arm.
-    pub fn is_ref_for_guard(&self) -> bool {
-        match self.local_info {
-            LocalInfo::User(ClearCrossCrate::Set(BindingForm::RefForGuard)) => true,
-            _ => false,
-        }
-    }
-
-    /// Returns `Some` if this is a reference to a static item that is used to
-    /// access that static
-    pub fn is_ref_to_static(&self) -> bool {
-        match self.local_info {
-            LocalInfo::StaticRef { .. } => true,
-            _ => false,
-        }
-    }
-
-    /// Returns `Some` if this is a reference to a static item that is used to
-    /// access that static
-    pub fn is_ref_to_thread_local(&self) -> bool {
-        match self.local_info {
-            LocalInfo::StaticRef { is_thread_local, .. } => is_thread_local,
-            _ => false,
-        }
-    }
-
-    /// Returns `true` is the local is from a compiler desugaring, e.g.,
-    /// `__next` from a `for` loop.
-    #[inline]
-    pub fn from_compiler_desugaring(&self) -> bool {
-        self.source_info.span.desugaring_kind().is_some()
-    }
-
-    /// Creates a new `LocalDecl` for a temporary.
-    #[inline]
-    pub fn new_temp(ty: Ty<'tcx>, span: Span) -> Self {
-        Self::new_local(ty, Mutability::Mut, false, span)
-    }
-
-    /// Converts `self` into same `LocalDecl` except tagged as immutable.
-    #[inline]
-    pub fn immutable(mut self) -> Self {
-        self.mutability = Mutability::Not;
-        self
-    }
-
-    /// Converts `self` into same `LocalDecl` except tagged as internal temporary.
-    #[inline]
-    pub fn block_tail(mut self, info: BlockTailInfo) -> Self {
-        assert!(self.is_block_tail.is_none());
-        self.is_block_tail = Some(info);
-        self
-    }
-
-    /// Creates a new `LocalDecl` for a internal temporary.
-    #[inline]
-    pub fn new_internal(ty: Ty<'tcx>, span: Span) -> Self {
-        Self::new_local(ty, Mutability::Mut, true, span)
-    }
-
-    #[inline]
-    fn new_local(ty: Ty<'tcx>, mutability: Mutability, internal: bool, span: Span) -> Self {
-        LocalDecl {
-            mutability,
-            ty,
-            user_ty: UserTypeProjections::none(),
-            source_info: SourceInfo { span, scope: OUTERMOST_SOURCE_SCOPE },
-            internal,
-            local_info: LocalInfo::Other,
-            is_block_tail: None,
-        }
-    }
-
-    /// Builds a `LocalDecl` for the return place.
-    ///
-    /// This must be inserted into the `local_decls` list as the first local.
-    #[inline]
-    pub fn new_return_place(return_ty: Ty<'_>, span: Span) -> LocalDecl<'_> {
-        LocalDecl {
-            mutability: Mutability::Mut,
-            ty: return_ty,
-            user_ty: UserTypeProjections::none(),
-            source_info: SourceInfo { span, scope: OUTERMOST_SOURCE_SCOPE },
-            internal: false,
-            is_block_tail: None,
-            local_info: LocalInfo::Other,
-        }
-    }
-}
-
-/// Debug information pertaining to a user variable.
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
-pub struct VarDebugInfo<'tcx> {
-    pub name: Name,
-
-    /// Source info of the user variable, including the scope
-    /// within which the variable is visible (to debuginfo)
-    /// (see `LocalDecl`'s `source_info` field for more details).
-    pub source_info: SourceInfo,
-
-    /// Where the data for this user variable is to be found.
-    /// NOTE(eddyb) There's an unenforced invariant that this `Place` is
-    /// based on a `Local`, not a `Static`, and contains no indexing.
-    pub place: Place<'tcx>,
-}
-
-///////////////////////////////////////////////////////////////////////////
-// BasicBlock
-
-rustc_index::newtype_index! {
-    pub struct BasicBlock {
-        derive [HashStable]
-        DEBUG_FORMAT = "bb{}",
-        const START_BLOCK = 0,
-    }
-}
-
-impl BasicBlock {
-    pub fn start_location(self) -> Location {
-        Location { block: self, statement_index: 0 }
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////
-// BasicBlockData and Terminator
-
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
-pub struct BasicBlockData<'tcx> {
-    /// List of statements in this block.
-    pub statements: Vec<Statement<'tcx>>,
-
-    /// Terminator for this block.
-    ///
-    /// N.B., this should generally ONLY be `None` during construction.
-    /// Therefore, you should generally access it via the
-    /// `terminator()` or `terminator_mut()` methods. The only
-    /// exception is that certain passes, such as `simplify_cfg`, swap
-    /// out the terminator temporarily with `None` while they continue
-    /// to recurse over the set of basic blocks.
-    pub terminator: Option<Terminator<'tcx>>,
-
-    /// If true, this block lies on an unwind path. This is used
-    /// during codegen where distinct kinds of basic blocks may be
-    /// generated (particularly for MSVC cleanup). Unwind blocks must
-    /// only branch to other unwind blocks.
-    pub is_cleanup: bool,
-}
-
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
-pub struct Terminator<'tcx> {
-    pub source_info: SourceInfo,
-    pub kind: TerminatorKind<'tcx>,
-}
-
-#[derive(Clone, RustcEncodable, RustcDecodable, HashStable, PartialEq)]
-pub enum TerminatorKind<'tcx> {
-    /// Block should have one successor in the graph; we jump there.
-    Goto { target: BasicBlock },
-
-    /// Operand evaluates to an integer; jump depending on its value
-    /// to one of the targets, and otherwise fallback to `otherwise`.
-    SwitchInt {
-        /// The discriminant value being tested.
-        discr: Operand<'tcx>,
-
-        /// The type of value being tested.
-        switch_ty: Ty<'tcx>,
-
-        /// Possible values. The locations to branch to in each case
-        /// are found in the corresponding indices from the `targets` vector.
-        values: Cow<'tcx, [u128]>,
-
-        /// Possible branch sites. The last element of this vector is used
-        /// for the otherwise branch, so targets.len() == values.len() + 1
-        /// should hold.
-        //
-        // This invariant is quite non-obvious and also could be improved.
-        // One way to make this invariant is to have something like this instead:
-        //
-        // branches: Vec<(ConstInt, BasicBlock)>,
-        // otherwise: Option<BasicBlock> // exhaustive if None
-        //
-        // However we’ve decided to keep this as-is until we figure a case
-        // where some other approach seems to be strictly better than other.
-        targets: Vec<BasicBlock>,
-    },
-
-    /// Indicates that the landing pad is finished and unwinding should
-    /// continue. Emitted by `build::scope::diverge_cleanup`.
-    Resume,
-
-    /// Indicates that the landing pad is finished and that the process
-    /// should abort. Used to prevent unwinding for foreign items.
-    Abort,
-
-    /// Indicates a normal return. The return place should have
-    /// been filled in by now. This should occur at most once.
-    Return,
-
-    /// Indicates a terminator that can never be reached.
-    Unreachable,
-
-    /// Drop the `Place`.
-    Drop { location: Place<'tcx>, target: BasicBlock, unwind: Option<BasicBlock> },
-
-    /// Drop the `Place` and assign the new value over it. This ensures
-    /// that the assignment to `P` occurs *even if* the destructor for
-    /// place unwinds. Its semantics are best explained by the
-    /// elaboration:
-    ///
-    /// ```
-    /// BB0 {
-    ///   DropAndReplace(P <- V, goto BB1, unwind BB2)
-    /// }
-    /// ```
-    ///
-    /// becomes
-    ///
-    /// ```
-    /// BB0 {
-    ///   Drop(P, goto BB1, unwind BB2)
-    /// }
-    /// BB1 {
-    ///   // P is now uninitialized
-    ///   P <- V
-    /// }
-    /// BB2 {
-    ///   // P is now uninitialized -- its dtor panicked
-    ///   P <- V
-    /// }
-    /// ```
-    DropAndReplace {
-        location: Place<'tcx>,
-        value: Operand<'tcx>,
-        target: BasicBlock,
-        unwind: Option<BasicBlock>,
-    },
-
-    /// Block ends with a call of a converging function.
-    Call {
-        /// The function that’s being called.
-        func: Operand<'tcx>,
-        /// Arguments the function is called with.
-        /// These are owned by the callee, which is free to modify them.
-        /// This allows the memory occupied by "by-value" arguments to be
-        /// reused across function calls without duplicating the contents.
-        args: Vec<Operand<'tcx>>,
-        /// Destination for the return value. If some, the call is converging.
-        destination: Option<(Place<'tcx>, BasicBlock)>,
-        /// Cleanups to be done if the call unwinds.
-        cleanup: Option<BasicBlock>,
-        /// `true` if this is from a call in HIR rather than from an overloaded
-        /// operator. True for overloaded function call.
-        from_hir_call: bool,
-    },
-
-    /// Jump to the target if the condition has the expected value,
-    /// otherwise panic with a message and a cleanup target.
-    Assert {
-        cond: Operand<'tcx>,
-        expected: bool,
-        msg: AssertMessage<'tcx>,
-        target: BasicBlock,
-        cleanup: Option<BasicBlock>,
-    },
-
-    /// A suspend point.
-    Yield {
-        /// The value to return.
-        value: Operand<'tcx>,
-        /// Where to resume to.
-        resume: BasicBlock,
-        /// The place to store the resume argument in.
-        resume_arg: Place<'tcx>,
-        /// Cleanup to be done if the generator is dropped at this suspend point.
-        drop: Option<BasicBlock>,
-    },
-
-    /// Indicates the end of the dropping of a generator.
-    GeneratorDrop,
-
-    /// A block where control flow only ever takes one real path, but borrowck
-    /// needs to be more conservative.
-    FalseEdges {
-        /// The target normal control flow will take.
-        real_target: BasicBlock,
-        /// A block control flow could conceptually jump to, but won't in
-        /// practice.
-        imaginary_target: BasicBlock,
-    },
-    /// A terminator for blocks that only take one path in reality, but where we
-    /// reserve the right to unwind in borrowck, even if it won't happen in practice.
-    /// This can arise in infinite loops with no function calls for example.
-    FalseUnwind {
-        /// The target normal control flow will take.
-        real_target: BasicBlock,
-        /// The imaginary cleanup block link. This particular path will never be taken
-        /// in practice, but in order to avoid fragility we want to always
-        /// consider it in borrowck. We don't want to accept programs which
-        /// pass borrowck only when `panic=abort` or some assertions are disabled
-        /// due to release vs. debug mode builds. This needs to be an `Option` because
-        /// of the `remove_noop_landing_pads` and `no_landing_pads` passes.
-        unwind: Option<BasicBlock>,
-    },
-}
-
-/// Information about an assertion failure.
-#[derive(Clone, RustcEncodable, RustcDecodable, HashStable, PartialEq)]
-pub enum AssertKind<O> {
-    BoundsCheck { len: O, index: O },
-    Overflow(BinOp),
-    OverflowNeg,
-    DivisionByZero,
-    RemainderByZero,
-    ResumedAfterReturn(GeneratorKind),
-    ResumedAfterPanic(GeneratorKind),
-}
-
-/// Type for MIR `Assert` terminator error messages.
-pub type AssertMessage<'tcx> = AssertKind<Operand<'tcx>>;
-
-pub type Successors<'a> =
-    iter::Chain<option::IntoIter<&'a BasicBlock>, slice::Iter<'a, BasicBlock>>;
-pub type SuccessorsMut<'a> =
-    iter::Chain<option::IntoIter<&'a mut BasicBlock>, slice::IterMut<'a, BasicBlock>>;
-
-impl<'tcx> Terminator<'tcx> {
-    pub fn successors(&self) -> Successors<'_> {
-        self.kind.successors()
-    }
-
-    pub fn successors_mut(&mut self) -> SuccessorsMut<'_> {
-        self.kind.successors_mut()
-    }
-
-    pub fn unwind(&self) -> Option<&Option<BasicBlock>> {
-        self.kind.unwind()
-    }
-
-    pub fn unwind_mut(&mut self) -> Option<&mut Option<BasicBlock>> {
-        self.kind.unwind_mut()
-    }
-}
-
-impl<'tcx> TerminatorKind<'tcx> {
-    pub fn if_(
-        tcx: TyCtxt<'tcx>,
-        cond: Operand<'tcx>,
-        t: BasicBlock,
-        f: BasicBlock,
-    ) -> TerminatorKind<'tcx> {
-        static BOOL_SWITCH_FALSE: &'static [u128] = &[0];
-        TerminatorKind::SwitchInt {
-            discr: cond,
-            switch_ty: tcx.types.bool,
-            values: From::from(BOOL_SWITCH_FALSE),
-            targets: vec![f, t],
-        }
-    }
-
-    pub fn successors(&self) -> Successors<'_> {
-        use self::TerminatorKind::*;
-        match *self {
-            Resume
-            | Abort
-            | GeneratorDrop
-            | Return
-            | Unreachable
-            | Call { destination: None, cleanup: None, .. } => None.into_iter().chain(&[]),
-            Goto { target: ref t }
-            | Call { destination: None, cleanup: Some(ref t), .. }
-            | Call { destination: Some((_, ref t)), cleanup: None, .. }
-            | Yield { resume: ref t, drop: None, .. }
-            | DropAndReplace { target: ref t, unwind: None, .. }
-            | Drop { target: ref t, unwind: None, .. }
-            | Assert { target: ref t, cleanup: None, .. }
-            | FalseUnwind { real_target: ref t, unwind: None } => Some(t).into_iter().chain(&[]),
-            Call { destination: Some((_, ref t)), cleanup: Some(ref u), .. }
-            | Yield { resume: ref t, drop: Some(ref u), .. }
-            | DropAndReplace { target: ref t, unwind: Some(ref u), .. }
-            | Drop { target: ref t, unwind: Some(ref u), .. }
-            | Assert { target: ref t, cleanup: Some(ref u), .. }
-            | FalseUnwind { real_target: ref t, unwind: Some(ref u) } => {
-                Some(t).into_iter().chain(slice::from_ref(u))
-            }
-            SwitchInt { ref targets, .. } => None.into_iter().chain(&targets[..]),
-            FalseEdges { ref real_target, ref imaginary_target } => {
-                Some(real_target).into_iter().chain(slice::from_ref(imaginary_target))
-            }
-        }
-    }
-
-    pub fn successors_mut(&mut self) -> SuccessorsMut<'_> {
-        use self::TerminatorKind::*;
-        match *self {
-            Resume
-            | Abort
-            | GeneratorDrop
-            | Return
-            | Unreachable
-            | Call { destination: None, cleanup: None, .. } => None.into_iter().chain(&mut []),
-            Goto { target: ref mut t }
-            | Call { destination: None, cleanup: Some(ref mut t), .. }
-            | Call { destination: Some((_, ref mut t)), cleanup: None, .. }
-            | Yield { resume: ref mut t, drop: None, .. }
-            | DropAndReplace { target: ref mut t, unwind: None, .. }
-            | Drop { target: ref mut t, unwind: None, .. }
-            | Assert { target: ref mut t, cleanup: None, .. }
-            | FalseUnwind { real_target: ref mut t, unwind: None } => {
-                Some(t).into_iter().chain(&mut [])
-            }
-            Call { destination: Some((_, ref mut t)), cleanup: Some(ref mut u), .. }
-            | Yield { resume: ref mut t, drop: Some(ref mut u), .. }
-            | DropAndReplace { target: ref mut t, unwind: Some(ref mut u), .. }
-            | Drop { target: ref mut t, unwind: Some(ref mut u), .. }
-            | Assert { target: ref mut t, cleanup: Some(ref mut u), .. }
-            | FalseUnwind { real_target: ref mut t, unwind: Some(ref mut u) } => {
-                Some(t).into_iter().chain(slice::from_mut(u))
-            }
-            SwitchInt { ref mut targets, .. } => None.into_iter().chain(&mut targets[..]),
-            FalseEdges { ref mut real_target, ref mut imaginary_target } => {
-                Some(real_target).into_iter().chain(slice::from_mut(imaginary_target))
-            }
-        }
-    }
-
-    pub fn unwind(&self) -> Option<&Option<BasicBlock>> {
-        match *self {
-            TerminatorKind::Goto { .. }
-            | TerminatorKind::Resume
-            | TerminatorKind::Abort
-            | TerminatorKind::Return
-            | TerminatorKind::Unreachable
-            | TerminatorKind::GeneratorDrop
-            | TerminatorKind::Yield { .. }
-            | TerminatorKind::SwitchInt { .. }
-            | TerminatorKind::FalseEdges { .. } => None,
-            TerminatorKind::Call { cleanup: ref unwind, .. }
-            | TerminatorKind::Assert { cleanup: ref unwind, .. }
-            | TerminatorKind::DropAndReplace { ref unwind, .. }
-            | TerminatorKind::Drop { ref unwind, .. }
-            | TerminatorKind::FalseUnwind { ref unwind, .. } => Some(unwind),
-        }
-    }
-
-    pub fn unwind_mut(&mut self) -> Option<&mut Option<BasicBlock>> {
-        match *self {
-            TerminatorKind::Goto { .. }
-            | TerminatorKind::Resume
-            | TerminatorKind::Abort
-            | TerminatorKind::Return
-            | TerminatorKind::Unreachable
-            | TerminatorKind::GeneratorDrop
-            | TerminatorKind::Yield { .. }
-            | TerminatorKind::SwitchInt { .. }
-            | TerminatorKind::FalseEdges { .. } => None,
-            TerminatorKind::Call { cleanup: ref mut unwind, .. }
-            | TerminatorKind::Assert { cleanup: ref mut unwind, .. }
-            | TerminatorKind::DropAndReplace { ref mut unwind, .. }
-            | TerminatorKind::Drop { ref mut unwind, .. }
-            | TerminatorKind::FalseUnwind { ref mut unwind, .. } => Some(unwind),
-        }
-    }
-}
-
-impl<'tcx> BasicBlockData<'tcx> {
-    pub fn new(terminator: Option<Terminator<'tcx>>) -> BasicBlockData<'tcx> {
-        BasicBlockData { statements: vec![], terminator, is_cleanup: false }
-    }
-
-    /// Accessor for terminator.
-    ///
-    /// Terminator may not be None after construction of the basic block is complete. This accessor
-    /// provides a convenience way to reach the terminator.
-    pub fn terminator(&self) -> &Terminator<'tcx> {
-        self.terminator.as_ref().expect("invalid terminator state")
-    }
-
-    pub fn terminator_mut(&mut self) -> &mut Terminator<'tcx> {
-        self.terminator.as_mut().expect("invalid terminator state")
-    }
-
-    pub fn retain_statements<F>(&mut self, mut f: F)
-    where
-        F: FnMut(&mut Statement<'_>) -> bool,
-    {
-        for s in &mut self.statements {
-            if !f(s) {
-                s.make_nop();
-            }
-        }
-    }
-
-    pub fn expand_statements<F, I>(&mut self, mut f: F)
-    where
-        F: FnMut(&mut Statement<'tcx>) -> Option<I>,
-        I: iter::TrustedLen<Item = Statement<'tcx>>,
-    {
-        // Gather all the iterators we'll need to splice in, and their positions.
-        let mut splices: Vec<(usize, I)> = vec![];
-        let mut extra_stmts = 0;
-        for (i, s) in self.statements.iter_mut().enumerate() {
-            if let Some(mut new_stmts) = f(s) {
-                if let Some(first) = new_stmts.next() {
-                    // We can already store the first new statement.
-                    *s = first;
-
-                    // Save the other statements for optimized splicing.
-                    let remaining = new_stmts.size_hint().0;
-                    if remaining > 0 {
-                        splices.push((i + 1 + extra_stmts, new_stmts));
-                        extra_stmts += remaining;
-                    }
-                } else {
-                    s.make_nop();
-                }
-            }
-        }
-
-        // Splice in the new statements, from the end of the block.
-        // FIXME(eddyb) This could be more efficient with a "gap buffer"
-        // where a range of elements ("gap") is left uninitialized, with
-        // splicing adding new elements to the end of that gap and moving
-        // existing elements from before the gap to the end of the gap.
-        // For now, this is safe code, emulating a gap but initializing it.
-        let mut gap = self.statements.len()..self.statements.len() + extra_stmts;
-        self.statements.resize(
-            gap.end,
-            Statement {
-                source_info: SourceInfo { span: DUMMY_SP, scope: OUTERMOST_SOURCE_SCOPE },
-                kind: StatementKind::Nop,
-            },
-        );
-        for (splice_start, new_stmts) in splices.into_iter().rev() {
-            let splice_end = splice_start + new_stmts.size_hint().0;
-            while gap.end > splice_end {
-                gap.start -= 1;
-                gap.end -= 1;
-                self.statements.swap(gap.start, gap.end);
-            }
-            self.statements.splice(splice_start..splice_end, new_stmts);
-            gap.end = splice_start;
-        }
-    }
-
-    pub fn visitable(&self, index: usize) -> &dyn MirVisitable<'tcx> {
-        if index < self.statements.len() { &self.statements[index] } else { &self.terminator }
-    }
-}
-
-impl<O> AssertKind<O> {
-    /// Getting a description does not require `O` to be printable, and does not
-    /// require allocation.
-    /// The caller is expected to handle `BoundsCheck` separately.
-    pub fn description(&self) -> &'static str {
-        use AssertKind::*;
-        match self {
-            Overflow(BinOp::Add) => "attempt to add with overflow",
-            Overflow(BinOp::Sub) => "attempt to subtract with overflow",
-            Overflow(BinOp::Mul) => "attempt to multiply with overflow",
-            Overflow(BinOp::Div) => "attempt to divide with overflow",
-            Overflow(BinOp::Rem) => "attempt to calculate the remainder with overflow",
-            OverflowNeg => "attempt to negate with overflow",
-            Overflow(BinOp::Shr) => "attempt to shift right with overflow",
-            Overflow(BinOp::Shl) => "attempt to shift left with overflow",
-            Overflow(op) => bug!("{:?} cannot overflow", op),
-            DivisionByZero => "attempt to divide by zero",
-            RemainderByZero => "attempt to calculate the remainder with a divisor of zero",
-            ResumedAfterReturn(GeneratorKind::Gen) => "generator resumed after completion",
-            ResumedAfterReturn(GeneratorKind::Async(_)) => "`async fn` resumed after completion",
-            ResumedAfterPanic(GeneratorKind::Gen) => "generator resumed after panicking",
-            ResumedAfterPanic(GeneratorKind::Async(_)) => "`async fn` resumed after panicking",
-            BoundsCheck { .. } => bug!("Unexpected AssertKind"),
-        }
-    }
-}
-
-impl<O: fmt::Debug> fmt::Debug for AssertKind<O> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        use AssertKind::*;
-        match self {
-            BoundsCheck { ref len, ref index } => {
-                write!(f, "index out of bounds: the len is {:?} but the index is {:?}", len, index)
-            }
-            _ => write!(f, "{}", self.description()),
-        }
-    }
-}
-
-impl<'tcx> Debug for TerminatorKind<'tcx> {
-    fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
-        self.fmt_head(fmt)?;
-        let successor_count = self.successors().count();
-        let labels = self.fmt_successor_labels();
-        assert_eq!(successor_count, labels.len());
-
-        match successor_count {
-            0 => Ok(()),
-
-            1 => write!(fmt, " -> {:?}", self.successors().nth(0).unwrap()),
-
-            _ => {
-                write!(fmt, " -> [")?;
-                for (i, target) in self.successors().enumerate() {
-                    if i > 0 {
-                        write!(fmt, ", ")?;
-                    }
-                    write!(fmt, "{}: {:?}", labels[i], target)?;
-                }
-                write!(fmt, "]")
-            }
-        }
-    }
-}
-
-impl<'tcx> TerminatorKind<'tcx> {
-    /// Writes the "head" part of the terminator; that is, its name and the data it uses to pick the
-    /// successor basic block, if any. The only information not included is the list of possible
-    /// successors, which may be rendered differently between the text and the graphviz format.
-    pub fn fmt_head<W: Write>(&self, fmt: &mut W) -> fmt::Result {
-        use self::TerminatorKind::*;
-        match self {
-            Goto { .. } => write!(fmt, "goto"),
-            SwitchInt { discr, .. } => write!(fmt, "switchInt({:?})", discr),
-            Return => write!(fmt, "return"),
-            GeneratorDrop => write!(fmt, "generator_drop"),
-            Resume => write!(fmt, "resume"),
-            Abort => write!(fmt, "abort"),
-            Yield { value, resume_arg, .. } => write!(fmt, "{:?} = yield({:?})", resume_arg, value),
-            Unreachable => write!(fmt, "unreachable"),
-            Drop { location, .. } => write!(fmt, "drop({:?})", location),
-            DropAndReplace { location, value, .. } => {
-                write!(fmt, "replace({:?} <- {:?})", location, value)
-            }
-            Call { func, args, destination, .. } => {
-                if let Some((destination, _)) = destination {
-                    write!(fmt, "{:?} = ", destination)?;
-                }
-                write!(fmt, "{:?}(", func)?;
-                for (index, arg) in args.iter().enumerate() {
-                    if index > 0 {
-                        write!(fmt, ", ")?;
-                    }
-                    write!(fmt, "{:?}", arg)?;
-                }
-                write!(fmt, ")")
-            }
-            Assert { cond, expected, msg, .. } => {
-                write!(fmt, "assert(")?;
-                if !expected {
-                    write!(fmt, "!")?;
-                }
-                write!(fmt, "{:?}, \"{:?}\")", cond, msg)
-            }
-            FalseEdges { .. } => write!(fmt, "falseEdges"),
-            FalseUnwind { .. } => write!(fmt, "falseUnwind"),
-        }
-    }
-
-    /// Returns the list of labels for the edges to the successor basic blocks.
-    pub fn fmt_successor_labels(&self) -> Vec<Cow<'static, str>> {
-        use self::TerminatorKind::*;
-        match *self {
-            Return | Resume | Abort | Unreachable | GeneratorDrop => vec![],
-            Goto { .. } => vec!["".into()],
-            SwitchInt { ref values, switch_ty, .. } => ty::tls::with(|tcx| {
-                let param_env = ty::ParamEnv::empty();
-                let switch_ty = tcx.lift(&switch_ty).unwrap();
-                let size = tcx.layout_of(param_env.and(switch_ty)).unwrap().size;
-                values
-                    .iter()
-                    .map(|&u| {
-                        ty::Const::from_scalar(tcx, Scalar::from_uint(u, size).into(), switch_ty)
-                            .to_string()
-                            .into()
-                    })
-                    .chain(iter::once("otherwise".into()))
-                    .collect()
-            }),
-            Call { destination: Some(_), cleanup: Some(_), .. } => {
-                vec!["return".into(), "unwind".into()]
-            }
-            Call { destination: Some(_), cleanup: None, .. } => vec!["return".into()],
-            Call { destination: None, cleanup: Some(_), .. } => vec!["unwind".into()],
-            Call { destination: None, cleanup: None, .. } => vec![],
-            Yield { drop: Some(_), .. } => vec!["resume".into(), "drop".into()],
-            Yield { drop: None, .. } => vec!["resume".into()],
-            DropAndReplace { unwind: None, .. } | Drop { unwind: None, .. } => {
-                vec!["return".into()]
-            }
-            DropAndReplace { unwind: Some(_), .. } | Drop { unwind: Some(_), .. } => {
-                vec!["return".into(), "unwind".into()]
-            }
-            Assert { cleanup: None, .. } => vec!["".into()],
-            Assert { .. } => vec!["success".into(), "unwind".into()],
-            FalseEdges { .. } => vec!["real".into(), "imaginary".into()],
-            FalseUnwind { unwind: Some(_), .. } => vec!["real".into(), "cleanup".into()],
-            FalseUnwind { unwind: None, .. } => vec!["real".into()],
-        }
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////
-// Statements
-
-#[derive(Clone, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
-pub struct Statement<'tcx> {
-    pub source_info: SourceInfo,
-    pub kind: StatementKind<'tcx>,
-}
-
-// `Statement` is used a lot. Make sure it doesn't unintentionally get bigger.
-#[cfg(target_arch = "x86_64")]
-static_assert_size!(Statement<'_>, 32);
-
-impl Statement<'_> {
-    /// Changes a statement to a nop. This is both faster than deleting instructions and avoids
-    /// invalidating statement indices in `Location`s.
-    pub fn make_nop(&mut self) {
-        self.kind = StatementKind::Nop
-    }
-
-    /// Changes a statement to a nop and returns the original statement.
-    pub fn replace_nop(&mut self) -> Self {
-        Statement {
-            source_info: self.source_info,
-            kind: mem::replace(&mut self.kind, StatementKind::Nop),
-        }
-    }
-}
-
-#[derive(Clone, Debug, PartialEq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
-pub enum StatementKind<'tcx> {
-    /// Write the RHS Rvalue to the LHS Place.
-    Assign(Box<(Place<'tcx>, Rvalue<'tcx>)>),
-
-    /// This represents all the reading that a pattern match may do
-    /// (e.g., inspecting constants and discriminant values), and the
-    /// kind of pattern it comes from. This is in order to adapt potential
-    /// error messages to these specific patterns.
-    ///
-    /// Note that this also is emitted for regular `let` bindings to ensure that locals that are
-    /// never accessed still get some sanity checks for, e.g., `let x: ! = ..;`
-    FakeRead(FakeReadCause, Box<Place<'tcx>>),
-
-    /// Write the discriminant for a variant to the enum Place.
-    SetDiscriminant { place: Box<Place<'tcx>>, variant_index: VariantIdx },
-
-    /// Start a live range for the storage of the local.
-    StorageLive(Local),
-
-    /// End the current live range for the storage of the local.
-    StorageDead(Local),
-
-    /// Executes a piece of inline Assembly. Stored in a Box to keep the size
-    /// of `StatementKind` low.
-    InlineAsm(Box<InlineAsm<'tcx>>),
-
-    /// Retag references in the given place, ensuring they got fresh tags. This is
-    /// part of the Stacked Borrows model. These statements are currently only interpreted
-    /// by miri and only generated when "-Z mir-emit-retag" is passed.
-    /// See <https://internals.rust-lang.org/t/stacked-borrows-an-aliasing-model-for-rust/8153/>
-    /// for more details.
-    Retag(RetagKind, Box<Place<'tcx>>),
-
-    /// Encodes a user's type ascription. These need to be preserved
-    /// intact so that NLL can respect them. For example:
-    ///
-    ///     let a: T = y;
-    ///
-    /// The effect of this annotation is to relate the type `T_y` of the place `y`
-    /// to the user-given type `T`. The effect depends on the specified variance:
-    ///
-    /// - `Covariant` -- requires that `T_y <: T`
-    /// - `Contravariant` -- requires that `T_y :> T`
-    /// - `Invariant` -- requires that `T_y == T`
-    /// - `Bivariant` -- no effect
-    AscribeUserType(Box<(Place<'tcx>, UserTypeProjection)>, ty::Variance),
-
-    /// No-op. Useful for deleting instructions without affecting statement indices.
-    Nop,
-}
-
-/// Describes what kind of retag is to be performed.
-#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, PartialEq, Eq, HashStable)]
-pub enum RetagKind {
-    /// The initial retag when entering a function.
-    FnEntry,
-    /// Retag preparing for a two-phase borrow.
-    TwoPhase,
-    /// Retagging raw pointers.
-    Raw,
-    /// A "normal" retag.
-    Default,
-}
-
-/// The `FakeReadCause` describes the type of pattern why a FakeRead statement exists.
-#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable, PartialEq)]
-pub enum FakeReadCause {
-    /// Inject a fake read of the borrowed input at the end of each guards
-    /// code.
-    ///
-    /// This should ensure that you cannot change the variant for an enum while
-    /// you are in the midst of matching on it.
-    ForMatchGuard,
-
-    /// `let x: !; match x {}` doesn't generate any read of x so we need to
-    /// generate a read of x to check that it is initialized and safe.
-    ForMatchedPlace,
-
-    /// A fake read of the RefWithinGuard version of a bind-by-value variable
-    /// in a match guard to ensure that it's value hasn't change by the time
-    /// we create the OutsideGuard version.
-    ForGuardBinding,
-
-    /// Officially, the semantics of
-    ///
-    /// `let pattern = <expr>;`
-    ///
-    /// is that `<expr>` is evaluated into a temporary and then this temporary is
-    /// into the pattern.
-    ///
-    /// However, if we see the simple pattern `let var = <expr>`, we optimize this to
-    /// evaluate `<expr>` directly into the variable `var`. This is mostly unobservable,
-    /// but in some cases it can affect the borrow checker, as in #53695.
-    /// Therefore, we insert a "fake read" here to ensure that we get
-    /// appropriate errors.
-    ForLet,
-
-    /// If we have an index expression like
-    ///
-    /// (*x)[1][{ x = y; 4}]
-    ///
-    /// then the first bounds check is invalidated when we evaluate the second
-    /// index expression. Thus we create a fake borrow of `x` across the second
-    /// indexer, which will cause a borrow check error.
-    ForIndex,
-}
-
-#[derive(Clone, Debug, PartialEq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
-pub struct InlineAsm<'tcx> {
-    pub asm: hir::InlineAsmInner,
-    pub outputs: Box<[Place<'tcx>]>,
-    pub inputs: Box<[(Span, Operand<'tcx>)]>,
-}
-
-impl Debug for Statement<'_> {
-    fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
-        use self::StatementKind::*;
-        match self.kind {
-            Assign(box (ref place, ref rv)) => write!(fmt, "{:?} = {:?}", place, rv),
-            FakeRead(ref cause, ref place) => write!(fmt, "FakeRead({:?}, {:?})", cause, place),
-            Retag(ref kind, ref place) => write!(
-                fmt,
-                "Retag({}{:?})",
-                match kind {
-                    RetagKind::FnEntry => "[fn entry] ",
-                    RetagKind::TwoPhase => "[2phase] ",
-                    RetagKind::Raw => "[raw] ",
-                    RetagKind::Default => "",
-                },
-                place,
-            ),
-            StorageLive(ref place) => write!(fmt, "StorageLive({:?})", place),
-            StorageDead(ref place) => write!(fmt, "StorageDead({:?})", place),
-            SetDiscriminant { ref place, variant_index } => {
-                write!(fmt, "discriminant({:?}) = {:?}", place, variant_index)
-            }
-            InlineAsm(ref asm) => {
-                write!(fmt, "asm!({:?} : {:?} : {:?})", asm.asm, asm.outputs, asm.inputs)
-            }
-            AscribeUserType(box (ref place, ref c_ty), ref variance) => {
-                write!(fmt, "AscribeUserType({:?}, {:?}, {:?})", place, variance, c_ty)
-            }
-            Nop => write!(fmt, "nop"),
-        }
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////
-// Places
-
-/// A path to a value; something that can be evaluated without
-/// changing or disturbing program state.
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, HashStable)]
-pub struct Place<'tcx> {
-    pub local: Local,
-
-    /// projection out of a place (access a field, deref a pointer, etc)
-    pub projection: &'tcx List<PlaceElem<'tcx>>,
-}
-
-impl<'tcx> rustc_serialize::UseSpecializedDecodable for Place<'tcx> {}
-
-#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
-#[derive(RustcEncodable, RustcDecodable, HashStable)]
-pub enum ProjectionElem<V, T> {
-    Deref,
-    Field(Field, T),
-    Index(V),
-
-    /// These indices are generated by slice patterns. Easiest to explain
-    /// by example:
-    ///
-    /// ```
-    /// [X, _, .._, _, _] => { offset: 0, min_length: 4, from_end: false },
-    /// [_, X, .._, _, _] => { offset: 1, min_length: 4, from_end: false },
-    /// [_, _, .._, X, _] => { offset: 2, min_length: 4, from_end: true },
-    /// [_, _, .._, _, X] => { offset: 1, min_length: 4, from_end: true },
-    /// ```
-    ConstantIndex {
-        /// index or -index (in Python terms), depending on from_end
-        offset: u32,
-        /// The thing being indexed must be at least this long. For arrays this
-        /// is always the exact length.
-        min_length: u32,
-        /// Counting backwards from end? This is always false when indexing an
-        /// array.
-        from_end: bool,
-    },
-
-    /// These indices are generated by slice patterns.
-    ///
-    /// If `from_end` is true `slice[from..slice.len() - to]`.
-    /// Otherwise `array[from..to]`.
-    Subslice {
-        from: u32,
-        to: u32,
-        /// Whether `to` counts from the start or end of the array/slice.
-        /// For `PlaceElem`s this is `true` if and only if the base is a slice.
-        /// For `ProjectionKind`, this can also be `true` for arrays.
-        from_end: bool,
-    },
-
-    /// "Downcast" to a variant of an ADT. Currently, we only introduce
-    /// this for ADTs with more than one variant. It may be better to
-    /// just introduce it always, or always for enums.
-    ///
-    /// The included Symbol is the name of the variant, used for printing MIR.
-    Downcast(Option<Symbol>, VariantIdx),
-}
-
-impl<V, T> ProjectionElem<V, T> {
-    /// Returns `true` if the target of this projection may refer to a different region of memory
-    /// than the base.
-    fn is_indirect(&self) -> bool {
-        match self {
-            Self::Deref => true,
-
-            Self::Field(_, _)
-            | Self::Index(_)
-            | Self::ConstantIndex { .. }
-            | Self::Subslice { .. }
-            | Self::Downcast(_, _) => false,
-        }
-    }
-}
-
-/// Alias for projections as they appear in places, where the base is a place
-/// and the index is a local.
-pub type PlaceElem<'tcx> = ProjectionElem<Local, Ty<'tcx>>;
-
-impl<'tcx> Copy for PlaceElem<'tcx> {}
-
-// At least on 64 bit systems, `PlaceElem` should not be larger than two pointers.
-#[cfg(target_arch = "x86_64")]
-static_assert_size!(PlaceElem<'_>, 16);
-
-/// Alias for projections as they appear in `UserTypeProjection`, where we
-/// need neither the `V` parameter for `Index` nor the `T` for `Field`.
-pub type ProjectionKind = ProjectionElem<(), ()>;
-
-rustc_index::newtype_index! {
-    pub struct Field {
-        derive [HashStable]
-        DEBUG_FORMAT = "field[{}]"
-    }
-}
-
-#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
-pub struct PlaceRef<'a, 'tcx> {
-    pub local: Local,
-    pub projection: &'a [PlaceElem<'tcx>],
-}
-
-impl<'tcx> Place<'tcx> {
-    // FIXME change this to a const fn by also making List::empty a const fn.
-    pub fn return_place() -> Place<'tcx> {
-        Place { local: RETURN_PLACE, projection: List::empty() }
-    }
-
-    /// Returns `true` if this `Place` contains a `Deref` projection.
-    ///
-    /// If `Place::is_indirect` returns false, the caller knows that the `Place` refers to the
-    /// same region of memory as its base.
-    pub fn is_indirect(&self) -> bool {
-        self.projection.iter().any(|elem| elem.is_indirect())
-    }
-
-    /// Finds the innermost `Local` from this `Place`, *if* it is either a local itself or
-    /// a single deref of a local.
-    //
-    // FIXME: can we safely swap the semantics of `fn base_local` below in here instead?
-    pub fn local_or_deref_local(&self) -> Option<Local> {
-        match self.as_ref() {
-            PlaceRef { local, projection: [] }
-            | PlaceRef { local, projection: [ProjectionElem::Deref] } => Some(local),
-            _ => None,
-        }
-    }
-
-    /// If this place represents a local variable like `_X` with no
-    /// projections, return `Some(_X)`.
-    pub fn as_local(&self) -> Option<Local> {
-        self.as_ref().as_local()
-    }
-
-    pub fn as_ref(&self) -> PlaceRef<'_, 'tcx> {
-        PlaceRef { local: self.local, projection: &self.projection }
-    }
-}
-
-impl From<Local> for Place<'_> {
-    fn from(local: Local) -> Self {
-        Place { local, projection: List::empty() }
-    }
-}
-
-impl<'a, 'tcx> PlaceRef<'a, 'tcx> {
-    /// Finds the innermost `Local` from this `Place`, *if* it is either a local itself or
-    /// a single deref of a local.
-    //
-    // FIXME: can we safely swap the semantics of `fn base_local` below in here instead?
-    pub fn local_or_deref_local(&self) -> Option<Local> {
-        match *self {
-            PlaceRef { local, projection: [] }
-            | PlaceRef { local, projection: [ProjectionElem::Deref] } => Some(local),
-            _ => None,
-        }
-    }
-
-    /// If this place represents a local variable like `_X` with no
-    /// projections, return `Some(_X)`.
-    pub fn as_local(&self) -> Option<Local> {
-        match *self {
-            PlaceRef { local, projection: [] } => Some(local),
-            _ => None,
-        }
-    }
-}
-
-impl Debug for Place<'_> {
-    fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
-        for elem in self.projection.iter().rev() {
-            match elem {
-                ProjectionElem::Downcast(_, _) | ProjectionElem::Field(_, _) => {
-                    write!(fmt, "(").unwrap();
-                }
-                ProjectionElem::Deref => {
-                    write!(fmt, "(*").unwrap();
-                }
-                ProjectionElem::Index(_)
-                | ProjectionElem::ConstantIndex { .. }
-                | ProjectionElem::Subslice { .. } => {}
-            }
-        }
-
-        write!(fmt, "{:?}", self.local)?;
-
-        for elem in self.projection.iter() {
-            match elem {
-                ProjectionElem::Downcast(Some(name), _index) => {
-                    write!(fmt, " as {})", name)?;
-                }
-                ProjectionElem::Downcast(None, index) => {
-                    write!(fmt, " as variant#{:?})", index)?;
-                }
-                ProjectionElem::Deref => {
-                    write!(fmt, ")")?;
-                }
-                ProjectionElem::Field(field, ty) => {
-                    write!(fmt, ".{:?}: {:?})", field.index(), ty)?;
-                }
-                ProjectionElem::Index(ref index) => {
-                    write!(fmt, "[{:?}]", index)?;
-                }
-                ProjectionElem::ConstantIndex { offset, min_length, from_end: false } => {
-                    write!(fmt, "[{:?} of {:?}]", offset, min_length)?;
-                }
-                ProjectionElem::ConstantIndex { offset, min_length, from_end: true } => {
-                    write!(fmt, "[-{:?} of {:?}]", offset, min_length)?;
-                }
-                ProjectionElem::Subslice { from, to, from_end: true } if *to == 0 => {
-                    write!(fmt, "[{:?}:]", from)?;
-                }
-                ProjectionElem::Subslice { from, to, from_end: true } if *from == 0 => {
-                    write!(fmt, "[:-{:?}]", to)?;
-                }
-                ProjectionElem::Subslice { from, to, from_end: true } => {
-                    write!(fmt, "[{:?}:-{:?}]", from, to)?;
-                }
-                ProjectionElem::Subslice { from, to, from_end: false } => {
-                    write!(fmt, "[{:?}..{:?}]", from, to)?;
-                }
-            }
-        }
-
-        Ok(())
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////
-// Scopes
-
-rustc_index::newtype_index! {
-    pub struct SourceScope {
-        derive [HashStable]
-        DEBUG_FORMAT = "scope[{}]",
-        const OUTERMOST_SOURCE_SCOPE = 0,
-    }
-}
-
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
-pub struct SourceScopeData {
-    pub span: Span,
-    pub parent_scope: Option<SourceScope>,
-
-    /// Crate-local information for this source scope, that can't (and
-    /// needn't) be tracked across crates.
-    pub local_data: ClearCrossCrate<SourceScopeLocalData>,
-}
-
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
-pub struct SourceScopeLocalData {
-    /// An `HirId` with lint levels equivalent to this scope's lint levels.
-    pub lint_root: hir::HirId,
-    /// The unsafe block that contains this node.
-    pub safety: Safety,
-}
-
-///////////////////////////////////////////////////////////////////////////
-// Operands
-
-/// These are values that can appear inside an rvalue. They are intentionally
-/// limited to prevent rvalues from being nested in one another.
-#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, HashStable)]
-pub enum Operand<'tcx> {
-    /// Copy: The value must be available for use afterwards.
-    ///
-    /// This implies that the type of the place must be `Copy`; this is true
-    /// by construction during build, but also checked by the MIR type checker.
-    Copy(Place<'tcx>),
-
-    /// Move: The value (including old borrows of it) will not be used again.
-    ///
-    /// Safe for values of all types (modulo future developments towards `?Move`).
-    /// Correct usage patterns are enforced by the borrow checker for safe code.
-    /// `Copy` may be converted to `Move` to enable "last-use" optimizations.
-    Move(Place<'tcx>),
-
-    /// Synthesizes a constant value.
-    Constant(Box<Constant<'tcx>>),
-}
-
-impl<'tcx> Debug for Operand<'tcx> {
-    fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
-        use self::Operand::*;
-        match *self {
-            Constant(ref a) => write!(fmt, "{:?}", a),
-            Copy(ref place) => write!(fmt, "{:?}", place),
-            Move(ref place) => write!(fmt, "move {:?}", place),
-        }
-    }
-}
-
-impl<'tcx> Operand<'tcx> {
-    /// Convenience helper to make a constant that refers to the fn
-    /// with given `DefId` and substs. Since this is used to synthesize
-    /// MIR, assumes `user_ty` is None.
-    pub fn function_handle(
-        tcx: TyCtxt<'tcx>,
-        def_id: DefId,
-        substs: SubstsRef<'tcx>,
-        span: Span,
-    ) -> Self {
-        let ty = tcx.type_of(def_id).subst(tcx, substs);
-        Operand::Constant(box Constant {
-            span,
-            user_ty: None,
-            literal: ty::Const::zero_sized(tcx, ty),
-        })
-    }
-
-    pub fn to_copy(&self) -> Self {
-        match *self {
-            Operand::Copy(_) | Operand::Constant(_) => self.clone(),
-            Operand::Move(place) => Operand::Copy(place),
-        }
-    }
-
-    /// Returns the `Place` that is the target of this `Operand`, or `None` if this `Operand` is a
-    /// constant.
-    pub fn place(&self) -> Option<&Place<'tcx>> {
-        match self {
-            Operand::Copy(place) | Operand::Move(place) => Some(place),
-            Operand::Constant(_) => None,
-        }
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////
-/// Rvalues
-
-#[derive(Clone, RustcEncodable, RustcDecodable, HashStable, PartialEq)]
-pub enum Rvalue<'tcx> {
-    /// x (either a move or copy, depending on type of x)
-    Use(Operand<'tcx>),
-
-    /// [x; 32]
-    Repeat(Operand<'tcx>, u64),
-
-    /// &x or &mut x
-    Ref(Region<'tcx>, BorrowKind, Place<'tcx>),
-
-    /// Create a raw pointer to the given place
-    /// Can be generated by raw address of expressions (`&raw const x`),
-    /// or when casting a reference to a raw pointer.
-    AddressOf(Mutability, Place<'tcx>),
-
-    /// length of a [X] or [X;n] value
-    Len(Place<'tcx>),
-
-    Cast(CastKind, Operand<'tcx>, Ty<'tcx>),
-
-    BinaryOp(BinOp, Operand<'tcx>, Operand<'tcx>),
-    CheckedBinaryOp(BinOp, Operand<'tcx>, Operand<'tcx>),
-
-    NullaryOp(NullOp, Ty<'tcx>),
-    UnaryOp(UnOp, Operand<'tcx>),
-
-    /// Read the discriminant of an ADT.
-    ///
-    /// Undefined (i.e., no effort is made to make it defined, but there’s no reason why it cannot
-    /// be defined to return, say, a 0) if ADT is not an enum.
-    Discriminant(Place<'tcx>),
-
-    /// Creates an aggregate value, like a tuple or struct. This is
-    /// only needed because we want to distinguish `dest = Foo { x:
-    /// ..., y: ... }` from `dest.x = ...; dest.y = ...;` in the case
-    /// that `Foo` has a destructor. These rvalues can be optimized
-    /// away after type-checking and before lowering.
-    Aggregate(Box<AggregateKind<'tcx>>, Vec<Operand<'tcx>>),
-}
-
-#[derive(Clone, Copy, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
-pub enum CastKind {
-    Misc,
-    Pointer(PointerCast),
-}
-
-#[derive(Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
-pub enum AggregateKind<'tcx> {
-    /// The type is of the element
-    Array(Ty<'tcx>),
-    Tuple,
-
-    /// The second field is the variant index. It's equal to 0 for struct
-    /// and union expressions. The fourth field is
-    /// active field number and is present only for union expressions
-    /// -- e.g., for a union expression `SomeUnion { c: .. }`, the
-    /// active field index would identity the field `c`
-    Adt(&'tcx AdtDef, VariantIdx, SubstsRef<'tcx>, Option<UserTypeAnnotationIndex>, Option<usize>),
-
-    Closure(DefId, SubstsRef<'tcx>),
-    Generator(DefId, SubstsRef<'tcx>, hir::Movability),
-}
-
-#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
-pub enum BinOp {
-    /// The `+` operator (addition)
-    Add,
-    /// The `-` operator (subtraction)
-    Sub,
-    /// The `*` operator (multiplication)
-    Mul,
-    /// The `/` operator (division)
-    Div,
-    /// The `%` operator (modulus)
-    Rem,
-    /// The `^` operator (bitwise xor)
-    BitXor,
-    /// The `&` operator (bitwise and)
-    BitAnd,
-    /// The `|` operator (bitwise or)
-    BitOr,
-    /// The `<<` operator (shift left)
-    Shl,
-    /// The `>>` operator (shift right)
-    Shr,
-    /// The `==` operator (equality)
-    Eq,
-    /// The `<` operator (less than)
-    Lt,
-    /// The `<=` operator (less than or equal to)
-    Le,
-    /// The `!=` operator (not equal to)
-    Ne,
-    /// The `>=` operator (greater than or equal to)
-    Ge,
-    /// The `>` operator (greater than)
-    Gt,
-    /// The `ptr.offset` operator
-    Offset,
-}
-
-impl BinOp {
-    pub fn is_checkable(self) -> bool {
-        use self::BinOp::*;
-        match self {
-            Add | Sub | Mul | Shl | Shr => true,
-            _ => false,
-        }
-    }
-}
-
-#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
-pub enum NullOp {
-    /// Returns the size of a value of that type
-    SizeOf,
-    /// Creates a new uninitialized box for a value of that type
-    Box,
-}
-
-#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
-pub enum UnOp {
-    /// The `!` operator for logical inversion
-    Not,
-    /// The `-` operator for negation
-    Neg,
-}
-
-impl<'tcx> Debug for Rvalue<'tcx> {
-    fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
-        use self::Rvalue::*;
-
-        match *self {
-            Use(ref place) => write!(fmt, "{:?}", place),
-            Repeat(ref a, ref b) => write!(fmt, "[{:?}; {:?}]", a, b),
-            Len(ref a) => write!(fmt, "Len({:?})", a),
-            Cast(ref kind, ref place, ref ty) => {
-                write!(fmt, "{:?} as {:?} ({:?})", place, ty, kind)
-            }
-            BinaryOp(ref op, ref a, ref b) => write!(fmt, "{:?}({:?}, {:?})", op, a, b),
-            CheckedBinaryOp(ref op, ref a, ref b) => {
-                write!(fmt, "Checked{:?}({:?}, {:?})", op, a, b)
-            }
-            UnaryOp(ref op, ref a) => write!(fmt, "{:?}({:?})", op, a),
-            Discriminant(ref place) => write!(fmt, "discriminant({:?})", place),
-            NullaryOp(ref op, ref t) => write!(fmt, "{:?}({:?})", op, t),
-            Ref(region, borrow_kind, ref place) => {
-                let kind_str = match borrow_kind {
-                    BorrowKind::Shared => "",
-                    BorrowKind::Shallow => "shallow ",
-                    BorrowKind::Mut { .. } | BorrowKind::Unique => "mut ",
-                };
-
-                // When printing regions, add trailing space if necessary.
-                let print_region = ty::tls::with(|tcx| {
-                    tcx.sess.verbose() || tcx.sess.opts.debugging_opts.identify_regions
-                });
-                let region = if print_region {
-                    let mut region = region.to_string();
-                    if region.len() > 0 {
-                        region.push(' ');
-                    }
-                    region
-                } else {
-                    // Do not even print 'static
-                    String::new()
-                };
-                write!(fmt, "&{}{}{:?}", region, kind_str, place)
-            }
-
-            AddressOf(mutability, ref place) => {
-                let kind_str = match mutability {
-                    Mutability::Mut => "mut",
-                    Mutability::Not => "const",
-                };
-
-                write!(fmt, "&raw {} {:?}", kind_str, place)
-            }
-
-            Aggregate(ref kind, ref places) => {
-                fn fmt_tuple(fmt: &mut Formatter<'_>, places: &[Operand<'_>]) -> fmt::Result {
-                    let mut tuple_fmt = fmt.debug_tuple("");
-                    for place in places {
-                        tuple_fmt.field(place);
-                    }
-                    tuple_fmt.finish()
-                }
-
-                match **kind {
-                    AggregateKind::Array(_) => write!(fmt, "{:?}", places),
-
-                    AggregateKind::Tuple => match places.len() {
-                        0 => write!(fmt, "()"),
-                        1 => write!(fmt, "({:?},)", places[0]),
-                        _ => fmt_tuple(fmt, places),
-                    },
-
-                    AggregateKind::Adt(adt_def, variant, substs, _user_ty, _) => {
-                        let variant_def = &adt_def.variants[variant];
-
-                        let f = &mut *fmt;
-                        ty::tls::with(|tcx| {
-                            let substs = tcx.lift(&substs).expect("could not lift for printing");
-                            FmtPrinter::new(tcx, f, Namespace::ValueNS)
-                                .print_def_path(variant_def.def_id, substs)?;
-                            Ok(())
-                        })?;
-
-                        match variant_def.ctor_kind {
-                            CtorKind::Const => Ok(()),
-                            CtorKind::Fn => fmt_tuple(fmt, places),
-                            CtorKind::Fictive => {
-                                let mut struct_fmt = fmt.debug_struct("");
-                                for (field, place) in variant_def.fields.iter().zip(places) {
-                                    struct_fmt.field(&field.ident.as_str(), place);
-                                }
-                                struct_fmt.finish()
-                            }
-                        }
-                    }
-
-                    AggregateKind::Closure(def_id, substs) => ty::tls::with(|tcx| {
-                        if let Some(hir_id) = tcx.hir().as_local_hir_id(def_id) {
-                            let name = if tcx.sess.opts.debugging_opts.span_free_formats {
-                                let substs = tcx.lift(&substs).unwrap();
-                                format!(
-                                    "[closure@{}]",
-                                    tcx.def_path_str_with_substs(def_id, substs),
-                                )
-                            } else {
-                                format!("[closure@{:?}]", tcx.hir().span(hir_id))
-                            };
-                            let mut struct_fmt = fmt.debug_struct(&name);
-
-                            if let Some(upvars) = tcx.upvars(def_id) {
-                                for (&var_id, place) in upvars.keys().zip(places) {
-                                    let var_name = tcx.hir().name(var_id);
-                                    struct_fmt.field(&var_name.as_str(), place);
-                                }
-                            }
-
-                            struct_fmt.finish()
-                        } else {
-                            write!(fmt, "[closure]")
-                        }
-                    }),
-
-                    AggregateKind::Generator(def_id, _, _) => ty::tls::with(|tcx| {
-                        if let Some(hir_id) = tcx.hir().as_local_hir_id(def_id) {
-                            let name = format!("[generator@{:?}]", tcx.hir().span(hir_id));
-                            let mut struct_fmt = fmt.debug_struct(&name);
-
-                            if let Some(upvars) = tcx.upvars(def_id) {
-                                for (&var_id, place) in upvars.keys().zip(places) {
-                                    let var_name = tcx.hir().name(var_id);
-                                    struct_fmt.field(&var_name.as_str(), place);
-                                }
-                            }
-
-                            struct_fmt.finish()
-                        } else {
-                            write!(fmt, "[generator]")
-                        }
-                    }),
-                }
-            }
-        }
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////
-/// Constants
-///
-/// Two constants are equal if they are the same constant. Note that
-/// this does not necessarily mean that they are "==" in Rust -- in
-/// particular one must be wary of `NaN`!
-
-#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, HashStable)]
-pub struct Constant<'tcx> {
-    pub span: Span,
-
-    /// Optional user-given type: for something like
-    /// `collect::<Vec<_>>`, this would be present and would
-    /// indicate that `Vec<_>` was explicitly specified.
-    ///
-    /// Needed for NLL to impose user-given type constraints.
-    pub user_ty: Option<UserTypeAnnotationIndex>,
-
-    pub literal: &'tcx ty::Const<'tcx>,
-}
-
-impl Constant<'tcx> {
-    pub fn check_static_ptr(&self, tcx: TyCtxt<'_>) -> Option<DefId> {
-        match self.literal.val.try_to_scalar() {
-            Some(Scalar::Ptr(ptr)) => match tcx.alloc_map.lock().get(ptr.alloc_id) {
-                Some(GlobalAlloc::Static(def_id)) => Some(def_id),
-                Some(_) => None,
-                None => {
-                    tcx.sess.delay_span_bug(DUMMY_SP, "MIR cannot contain dangling const pointers");
-                    None
-                }
-            },
-            _ => None,
-        }
-    }
-}
-
-/// A collection of projections into user types.
-///
-/// They are projections because a binding can occur a part of a
-/// parent pattern that has been ascribed a type.
-///
-/// Its a collection because there can be multiple type ascriptions on
-/// the path from the root of the pattern down to the binding itself.
-///
-/// An example:
-///
-/// ```rust
-/// struct S<'a>((i32, &'a str), String);
-/// let S((_, w): (i32, &'static str), _): S = ...;
-/// //    ------  ^^^^^^^^^^^^^^^^^^^ (1)
-/// //  ---------------------------------  ^ (2)
-/// ```
-///
-/// The highlights labelled `(1)` show the subpattern `(_, w)` being
-/// ascribed the type `(i32, &'static str)`.
-///
-/// The highlights labelled `(2)` show the whole pattern being
-/// ascribed the type `S`.
-///
-/// In this example, when we descend to `w`, we will have built up the
-/// following two projected types:
-///
-///   * base: `S`,                   projection: `(base.0).1`
-///   * base: `(i32, &'static str)`, projection: `base.1`
-///
-/// The first will lead to the constraint `w: &'1 str` (for some
-/// inferred region `'1`). The second will lead to the constraint `w:
-/// &'static str`.
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
-pub struct UserTypeProjections {
-    pub(crate) contents: Vec<(UserTypeProjection, Span)>,
-}
-
-impl<'tcx> UserTypeProjections {
-    pub fn none() -> Self {
-        UserTypeProjections { contents: vec![] }
-    }
-
-    pub fn from_projections(projs: impl Iterator<Item = (UserTypeProjection, Span)>) -> Self {
-        UserTypeProjections { contents: projs.collect() }
-    }
-
-    pub fn projections_and_spans(
-        &self,
-    ) -> impl Iterator<Item = &(UserTypeProjection, Span)> + ExactSizeIterator {
-        self.contents.iter()
-    }
-
-    pub fn projections(&self) -> impl Iterator<Item = &UserTypeProjection> + ExactSizeIterator {
-        self.contents.iter().map(|&(ref user_type, _span)| user_type)
-    }
-
-    pub fn push_projection(mut self, user_ty: &UserTypeProjection, span: Span) -> Self {
-        self.contents.push((user_ty.clone(), span));
-        self
-    }
-
-    fn map_projections(
-        mut self,
-        mut f: impl FnMut(UserTypeProjection) -> UserTypeProjection,
-    ) -> Self {
-        self.contents = self.contents.drain(..).map(|(proj, span)| (f(proj), span)).collect();
-        self
-    }
-
-    pub fn index(self) -> Self {
-        self.map_projections(|pat_ty_proj| pat_ty_proj.index())
-    }
-
-    pub fn subslice(self, from: u32, to: u32) -> Self {
-        self.map_projections(|pat_ty_proj| pat_ty_proj.subslice(from, to))
-    }
-
-    pub fn deref(self) -> Self {
-        self.map_projections(|pat_ty_proj| pat_ty_proj.deref())
-    }
-
-    pub fn leaf(self, field: Field) -> Self {
-        self.map_projections(|pat_ty_proj| pat_ty_proj.leaf(field))
-    }
-
-    pub fn variant(self, adt_def: &'tcx AdtDef, variant_index: VariantIdx, field: Field) -> Self {
-        self.map_projections(|pat_ty_proj| pat_ty_proj.variant(adt_def, variant_index, field))
-    }
-}
-
-/// Encodes the effect of a user-supplied type annotation on the
-/// subcomponents of a pattern. The effect is determined by applying the
-/// given list of proejctions to some underlying base type. Often,
-/// the projection element list `projs` is empty, in which case this
-/// directly encodes a type in `base`. But in the case of complex patterns with
-/// subpatterns and bindings, we want to apply only a *part* of the type to a variable,
-/// in which case the `projs` vector is used.
-///
-/// Examples:
-///
-/// * `let x: T = ...` -- here, the `projs` vector is empty.
-///
-/// * `let (x, _): T = ...` -- here, the `projs` vector would contain
-///   `field[0]` (aka `.0`), indicating that the type of `s` is
-///   determined by finding the type of the `.0` field from `T`.
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable, PartialEq)]
-pub struct UserTypeProjection {
-    pub base: UserTypeAnnotationIndex,
-    pub projs: Vec<ProjectionKind>,
-}
-
-impl Copy for ProjectionKind {}
-
-impl UserTypeProjection {
-    pub(crate) fn index(mut self) -> Self {
-        self.projs.push(ProjectionElem::Index(()));
-        self
-    }
-
-    pub(crate) fn subslice(mut self, from: u32, to: u32) -> Self {
-        self.projs.push(ProjectionElem::Subslice { from, to, from_end: true });
-        self
-    }
-
-    pub(crate) fn deref(mut self) -> Self {
-        self.projs.push(ProjectionElem::Deref);
-        self
-    }
-
-    pub(crate) fn leaf(mut self, field: Field) -> Self {
-        self.projs.push(ProjectionElem::Field(field, ()));
-        self
-    }
-
-    pub(crate) fn variant(
-        mut self,
-        adt_def: &'tcx AdtDef,
-        variant_index: VariantIdx,
-        field: Field,
-    ) -> Self {
-        self.projs.push(ProjectionElem::Downcast(
-            Some(adt_def.variants[variant_index].ident.name),
-            variant_index,
-        ));
-        self.projs.push(ProjectionElem::Field(field, ()));
-        self
-    }
-}
-
-CloneTypeFoldableAndLiftImpls! { ProjectionKind, }
-
-impl<'tcx> TypeFoldable<'tcx> for UserTypeProjection {
-    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
-        use crate::mir::ProjectionElem::*;
-
-        let base = self.base.fold_with(folder);
-        let projs: Vec<_> = self
-            .projs
-            .iter()
-            .map(|&elem| match elem {
-                Deref => Deref,
-                Field(f, ()) => Field(f, ()),
-                Index(()) => Index(()),
-                Downcast(symbol, variantidx) => Downcast(symbol, variantidx),
-                ConstantIndex { offset, min_length, from_end } => {
-                    ConstantIndex { offset, min_length, from_end }
-                }
-                Subslice { from, to, from_end } => Subslice { from, to, from_end },
-            })
-            .collect();
-
-        UserTypeProjection { base, projs }
-    }
-
-    fn super_visit_with<Vs: TypeVisitor<'tcx>>(&self, visitor: &mut Vs) -> bool {
-        self.base.visit_with(visitor)
-        // Note: there's nothing in `self.proj` to visit.
-    }
-}
-
-rustc_index::newtype_index! {
-    pub struct Promoted {
-        derive [HashStable]
-        DEBUG_FORMAT = "promoted[{}]"
-    }
-}
-
-impl<'tcx> Debug for Constant<'tcx> {
-    fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
-        write!(fmt, "{}", self)
-    }
-}
-
-impl<'tcx> Display for Constant<'tcx> {
-    fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
-        write!(fmt, "const ")?;
-        // FIXME make the default pretty printing of raw pointers more detailed. Here we output the
-        // debug representation of raw pointers, so that the raw pointers in the mir dump output are
-        // detailed and just not '{pointer}'.
-        if let ty::RawPtr(_) = self.literal.ty.kind {
-            write!(fmt, "{:?} : {}", self.literal.val, self.literal.ty)
-        } else {
-            write!(fmt, "{}", self.literal)
-        }
-    }
-}
-
-impl<'tcx> graph::DirectedGraph for Body<'tcx> {
-    type Node = BasicBlock;
-}
-
-impl<'tcx> graph::WithNumNodes for Body<'tcx> {
-    fn num_nodes(&self) -> usize {
-        self.basic_blocks.len()
-    }
-}
-
-impl<'tcx> graph::WithStartNode for Body<'tcx> {
-    fn start_node(&self) -> Self::Node {
-        START_BLOCK
-    }
-}
-
-impl<'tcx> graph::WithSuccessors for Body<'tcx> {
-    fn successors(&self, node: Self::Node) -> <Self as GraphSuccessors<'_>>::Iter {
-        self.basic_blocks[node].terminator().successors().cloned()
-    }
-}
-
-impl<'a, 'b> graph::GraphSuccessors<'b> for Body<'a> {
-    type Item = BasicBlock;
-    type Iter = iter::Cloned<Successors<'b>>;
-}
-
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Ord, PartialOrd, HashStable)]
-pub struct Location {
-    /// The block that the location is within.
-    pub block: BasicBlock,
-
-    /// The location is the position of the start of the statement; or, if
-    /// `statement_index` equals the number of statements, then the start of the
-    /// terminator.
-    pub statement_index: usize,
-}
-
-impl fmt::Debug for Location {
-    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(fmt, "{:?}[{}]", self.block, self.statement_index)
-    }
-}
-
-impl Location {
-    pub const START: Location = Location { block: START_BLOCK, statement_index: 0 };
-
-    /// Returns the location immediately after this one within the enclosing block.
-    ///
-    /// Note that if this location represents a terminator, then the
-    /// resulting location would be out of bounds and invalid.
-    pub fn successor_within_block(&self) -> Location {
-        Location { block: self.block, statement_index: self.statement_index + 1 }
-    }
-
-    /// Returns `true` if `other` is earlier in the control flow graph than `self`.
-    pub fn is_predecessor_of<'tcx>(
-        &self,
-        other: Location,
-        body: ReadOnlyBodyAndCache<'_, 'tcx>,
-    ) -> bool {
-        // If we are in the same block as the other location and are an earlier statement
-        // then we are a predecessor of `other`.
-        if self.block == other.block && self.statement_index < other.statement_index {
-            return true;
-        }
-
-        // If we're in another block, then we want to check that block is a predecessor of `other`.
-        let mut queue: Vec<BasicBlock> = body.predecessors_for(other.block).to_vec();
-        let mut visited = FxHashSet::default();
-
-        while let Some(block) = queue.pop() {
-            // If we haven't visited this block before, then make sure we visit it's predecessors.
-            if visited.insert(block) {
-                queue.extend(body.predecessors_for(block).iter().cloned());
-            } else {
-                continue;
-            }
-
-            // If we found the block that `self` is in, then we are a predecessor of `other` (since
-            // we found that block by looking at the predecessors of `other`).
-            if self.block == block {
-                return true;
-            }
-        }
-
-        false
-    }
-
-    pub fn dominates(&self, other: Location, dominators: &Dominators<BasicBlock>) -> bool {
-        if self.block == other.block {
-            self.statement_index <= other.statement_index
-        } else {
-            dominators.is_dominated_by(other.block, self.block)
-        }
-    }
-}
-
-/*
- * `TypeFoldable` implementations for MIR types
-*/
-
-CloneTypeFoldableAndLiftImpls! {
-    BlockTailInfo,
-    MirPhase,
-    SourceInfo,
-    FakeReadCause,
-    RetagKind,
-    SourceScope,
-    SourceScopeData,
-    SourceScopeLocalData,
-    UserTypeAnnotationIndex,
-}
-
-impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
-    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
-        use crate::mir::TerminatorKind::*;
-
-        let kind = match self.kind {
-            Goto { target } => Goto { target },
-            SwitchInt { ref discr, switch_ty, ref values, ref targets } => SwitchInt {
-                discr: discr.fold_with(folder),
-                switch_ty: switch_ty.fold_with(folder),
-                values: values.clone(),
-                targets: targets.clone(),
-            },
-            Drop { ref location, target, unwind } => {
-                Drop { location: location.fold_with(folder), target, unwind }
-            }
-            DropAndReplace { ref location, ref value, target, unwind } => DropAndReplace {
-                location: location.fold_with(folder),
-                value: value.fold_with(folder),
-                target,
-                unwind,
-            },
-            Yield { ref value, resume, ref resume_arg, drop } => Yield {
-                value: value.fold_with(folder),
-                resume,
-                resume_arg: resume_arg.fold_with(folder),
-                drop,
-            },
-            Call { ref func, ref args, ref destination, cleanup, from_hir_call } => {
-                let dest =
-                    destination.as_ref().map(|&(ref loc, dest)| (loc.fold_with(folder), dest));
-
-                Call {
-                    func: func.fold_with(folder),
-                    args: args.fold_with(folder),
-                    destination: dest,
-                    cleanup,
-                    from_hir_call,
-                }
-            }
-            Assert { ref cond, expected, ref msg, target, cleanup } => {
-                use AssertKind::*;
-                let msg = match msg {
-                    BoundsCheck { ref len, ref index } => {
-                        BoundsCheck { len: len.fold_with(folder), index: index.fold_with(folder) }
-                    }
-                    Overflow(_)
-                    | OverflowNeg
-                    | DivisionByZero
-                    | RemainderByZero
-                    | ResumedAfterReturn(_)
-                    | ResumedAfterPanic(_) => msg.clone(),
-                };
-                Assert { cond: cond.fold_with(folder), expected, msg, target, cleanup }
-            }
-            GeneratorDrop => GeneratorDrop,
-            Resume => Resume,
-            Abort => Abort,
-            Return => Return,
-            Unreachable => Unreachable,
-            FalseEdges { real_target, imaginary_target } => {
-                FalseEdges { real_target, imaginary_target }
-            }
-            FalseUnwind { real_target, unwind } => FalseUnwind { real_target, unwind },
-        };
-        Terminator { source_info: self.source_info, kind }
-    }
-
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
-        use crate::mir::TerminatorKind::*;
-
-        match self.kind {
-            SwitchInt { ref discr, switch_ty, .. } => {
-                discr.visit_with(visitor) || switch_ty.visit_with(visitor)
-            }
-            Drop { ref location, .. } => location.visit_with(visitor),
-            DropAndReplace { ref location, ref value, .. } => {
-                location.visit_with(visitor) || value.visit_with(visitor)
-            }
-            Yield { ref value, .. } => value.visit_with(visitor),
-            Call { ref func, ref args, ref destination, .. } => {
-                let dest = if let Some((ref loc, _)) = *destination {
-                    loc.visit_with(visitor)
-                } else {
-                    false
-                };
-                dest || func.visit_with(visitor) || args.visit_with(visitor)
-            }
-            Assert { ref cond, ref msg, .. } => {
-                if cond.visit_with(visitor) {
-                    use AssertKind::*;
-                    match msg {
-                        BoundsCheck { ref len, ref index } => {
-                            len.visit_with(visitor) || index.visit_with(visitor)
-                        }
-                        Overflow(_)
-                        | OverflowNeg
-                        | DivisionByZero
-                        | RemainderByZero
-                        | ResumedAfterReturn(_)
-                        | ResumedAfterPanic(_) => false,
-                    }
-                } else {
-                    false
-                }
-            }
-            Goto { .. }
-            | Resume
-            | Abort
-            | Return
-            | GeneratorDrop
-            | Unreachable
-            | FalseEdges { .. }
-            | FalseUnwind { .. } => false,
-        }
-    }
-}
-
-impl<'tcx> TypeFoldable<'tcx> for GeneratorKind {
-    fn super_fold_with<F: TypeFolder<'tcx>>(&self, _: &mut F) -> Self {
-        *self
-    }
-
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> bool {
-        false
-    }
-}
-
-impl<'tcx> TypeFoldable<'tcx> for Place<'tcx> {
-    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
-        Place { local: self.local.fold_with(folder), projection: self.projection.fold_with(folder) }
-    }
-
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
-        self.local.visit_with(visitor) || self.projection.visit_with(visitor)
-    }
-}
-
-impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<PlaceElem<'tcx>> {
-    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
-        let v = self.iter().map(|t| t.fold_with(folder)).collect::<Vec<_>>();
-        folder.tcx().intern_place_elems(&v)
-    }
-
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
-        self.iter().any(|t| t.visit_with(visitor))
-    }
-}
-
-impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
-    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
-        use crate::mir::Rvalue::*;
-        match *self {
-            Use(ref op) => Use(op.fold_with(folder)),
-            Repeat(ref op, len) => Repeat(op.fold_with(folder), len),
-            Ref(region, bk, ref place) => {
-                Ref(region.fold_with(folder), bk, place.fold_with(folder))
-            }
-            AddressOf(mutability, ref place) => AddressOf(mutability, place.fold_with(folder)),
-            Len(ref place) => Len(place.fold_with(folder)),
-            Cast(kind, ref op, ty) => Cast(kind, op.fold_with(folder), ty.fold_with(folder)),
-            BinaryOp(op, ref rhs, ref lhs) => {
-                BinaryOp(op, rhs.fold_with(folder), lhs.fold_with(folder))
-            }
-            CheckedBinaryOp(op, ref rhs, ref lhs) => {
-                CheckedBinaryOp(op, rhs.fold_with(folder), lhs.fold_with(folder))
-            }
-            UnaryOp(op, ref val) => UnaryOp(op, val.fold_with(folder)),
-            Discriminant(ref place) => Discriminant(place.fold_with(folder)),
-            NullaryOp(op, ty) => NullaryOp(op, ty.fold_with(folder)),
-            Aggregate(ref kind, ref fields) => {
-                let kind = box match **kind {
-                    AggregateKind::Array(ty) => AggregateKind::Array(ty.fold_with(folder)),
-                    AggregateKind::Tuple => AggregateKind::Tuple,
-                    AggregateKind::Adt(def, v, substs, user_ty, n) => AggregateKind::Adt(
-                        def,
-                        v,
-                        substs.fold_with(folder),
-                        user_ty.fold_with(folder),
-                        n,
-                    ),
-                    AggregateKind::Closure(id, substs) => {
-                        AggregateKind::Closure(id, substs.fold_with(folder))
-                    }
-                    AggregateKind::Generator(id, substs, movablity) => {
-                        AggregateKind::Generator(id, substs.fold_with(folder), movablity)
-                    }
-                };
-                Aggregate(kind, fields.fold_with(folder))
-            }
-        }
-    }
-
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
-        use crate::mir::Rvalue::*;
-        match *self {
-            Use(ref op) => op.visit_with(visitor),
-            Repeat(ref op, _) => op.visit_with(visitor),
-            Ref(region, _, ref place) => region.visit_with(visitor) || place.visit_with(visitor),
-            AddressOf(_, ref place) => place.visit_with(visitor),
-            Len(ref place) => place.visit_with(visitor),
-            Cast(_, ref op, ty) => op.visit_with(visitor) || ty.visit_with(visitor),
-            BinaryOp(_, ref rhs, ref lhs) | CheckedBinaryOp(_, ref rhs, ref lhs) => {
-                rhs.visit_with(visitor) || lhs.visit_with(visitor)
-            }
-            UnaryOp(_, ref val) => val.visit_with(visitor),
-            Discriminant(ref place) => place.visit_with(visitor),
-            NullaryOp(_, ty) => ty.visit_with(visitor),
-            Aggregate(ref kind, ref fields) => {
-                (match **kind {
-                    AggregateKind::Array(ty) => ty.visit_with(visitor),
-                    AggregateKind::Tuple => false,
-                    AggregateKind::Adt(_, _, substs, user_ty, _) => {
-                        substs.visit_with(visitor) || user_ty.visit_with(visitor)
-                    }
-                    AggregateKind::Closure(_, substs) => substs.visit_with(visitor),
-                    AggregateKind::Generator(_, substs, _) => substs.visit_with(visitor),
-                }) || fields.visit_with(visitor)
-            }
-        }
-    }
-}
-
-impl<'tcx> TypeFoldable<'tcx> for Operand<'tcx> {
-    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
-        match *self {
-            Operand::Copy(ref place) => Operand::Copy(place.fold_with(folder)),
-            Operand::Move(ref place) => Operand::Move(place.fold_with(folder)),
-            Operand::Constant(ref c) => Operand::Constant(c.fold_with(folder)),
-        }
-    }
-
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
-        match *self {
-            Operand::Copy(ref place) | Operand::Move(ref place) => place.visit_with(visitor),
-            Operand::Constant(ref c) => c.visit_with(visitor),
-        }
-    }
-}
-
-impl<'tcx> TypeFoldable<'tcx> for PlaceElem<'tcx> {
-    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
-        use crate::mir::ProjectionElem::*;
-
-        match *self {
-            Deref => Deref,
-            Field(f, ty) => Field(f, ty.fold_with(folder)),
-            Index(v) => Index(v.fold_with(folder)),
-            Downcast(symbol, variantidx) => Downcast(symbol, variantidx),
-            ConstantIndex { offset, min_length, from_end } => {
-                ConstantIndex { offset, min_length, from_end }
-            }
-            Subslice { from, to, from_end } => Subslice { from, to, from_end },
-        }
-    }
-
-    fn super_visit_with<Vs: TypeVisitor<'tcx>>(&self, visitor: &mut Vs) -> bool {
-        use crate::mir::ProjectionElem::*;
-
-        match self {
-            Field(_, ty) => ty.visit_with(visitor),
-            Index(v) => v.visit_with(visitor),
-            _ => false,
-        }
-    }
-}
-
-impl<'tcx> TypeFoldable<'tcx> for Field {
-    fn super_fold_with<F: TypeFolder<'tcx>>(&self, _: &mut F) -> Self {
-        *self
-    }
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> bool {
-        false
-    }
-}
-
-impl<'tcx> TypeFoldable<'tcx> for GeneratorSavedLocal {
-    fn super_fold_with<F: TypeFolder<'tcx>>(&self, _: &mut F) -> Self {
-        *self
-    }
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> bool {
-        false
-    }
-}
-
-impl<'tcx, R: Idx, C: Idx> TypeFoldable<'tcx> for BitMatrix<R, C> {
-    fn super_fold_with<F: TypeFolder<'tcx>>(&self, _: &mut F) -> Self {
-        self.clone()
-    }
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> bool {
-        false
-    }
-}
-
-impl<'tcx> TypeFoldable<'tcx> for Constant<'tcx> {
-    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
-        Constant {
-            span: self.span,
-            user_ty: self.user_ty.fold_with(folder),
-            literal: self.literal.fold_with(folder),
-        }
-    }
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
-        self.literal.visit_with(visitor)
-    }
-}
diff --git a/src/librustc/mir/mono.rs b/src/librustc/mir/mono.rs
deleted file mode 100644
index 9a3ddfb0e82..00000000000
--- a/src/librustc/mir/mono.rs
+++ /dev/null
@@ -1,494 +0,0 @@
-use crate::dep_graph::{DepConstructor, DepNode, WorkProduct, WorkProductId};
-use crate::ich::{Fingerprint, NodeIdHashingMode, StableHashingContext};
-use crate::session::config::OptLevel;
-use crate::ty::print::obsolete::DefPathBasedNames;
-use crate::ty::{subst::InternalSubsts, Instance, InstanceDef, SymbolName, TyCtxt};
-use rustc_attr::InlineAttr;
-use rustc_data_structures::base_n;
-use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
-use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
-use rustc_hir::HirId;
-use rustc_span::source_map::Span;
-use rustc_span::symbol::Symbol;
-use std::fmt;
-use std::hash::Hash;
-
-/// Describes how a monomorphization will be instantiated in object files.
-#[derive(PartialEq)]
-pub enum InstantiationMode {
-    /// There will be exactly one instance of the given MonoItem. It will have
-    /// external linkage so that it can be linked to from other codegen units.
-    GloballyShared {
-        /// In some compilation scenarios we may decide to take functions that
-        /// are typically `LocalCopy` and instead move them to `GloballyShared`
-        /// to avoid codegenning them a bunch of times. In this situation,
-        /// however, our local copy may conflict with other crates also
-        /// inlining the same function.
-        ///
-        /// This flag indicates that this situation is occurring, and informs
-        /// symbol name calculation that some extra mangling is needed to
-        /// avoid conflicts. Note that this may eventually go away entirely if
-        /// ThinLTO enables us to *always* have a globally shared instance of a
-        /// function within one crate's compilation.
-        may_conflict: bool,
-    },
-
-    /// Each codegen unit containing a reference to the given MonoItem will
-    /// have its own private copy of the function (with internal linkage).
-    LocalCopy,
-}
-
-#[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)]
-pub enum MonoItem<'tcx> {
-    Fn(Instance<'tcx>),
-    Static(DefId),
-    GlobalAsm(HirId),
-}
-
-impl<'tcx> MonoItem<'tcx> {
-    pub fn size_estimate(&self, tcx: TyCtxt<'tcx>) -> usize {
-        match *self {
-            MonoItem::Fn(instance) => {
-                // Estimate the size of a function based on how many statements
-                // it contains.
-                tcx.instance_def_size_estimate(instance.def)
-            }
-            // Conservatively estimate the size of a static declaration
-            // or assembly to be 1.
-            MonoItem::Static(_) | MonoItem::GlobalAsm(_) => 1,
-        }
-    }
-
-    pub fn is_generic_fn(&self) -> bool {
-        match *self {
-            MonoItem::Fn(ref instance) => instance.substs.non_erasable_generics().next().is_some(),
-            MonoItem::Static(..) | MonoItem::GlobalAsm(..) => false,
-        }
-    }
-
-    pub fn symbol_name(&self, tcx: TyCtxt<'tcx>) -> SymbolName {
-        match *self {
-            MonoItem::Fn(instance) => tcx.symbol_name(instance),
-            MonoItem::Static(def_id) => tcx.symbol_name(Instance::mono(tcx, def_id)),
-            MonoItem::GlobalAsm(hir_id) => {
-                let def_id = tcx.hir().local_def_id(hir_id);
-                SymbolName { name: Symbol::intern(&format!("global_asm_{:?}", def_id)) }
-            }
-        }
-    }
-
-    pub fn instantiation_mode(&self, tcx: TyCtxt<'tcx>) -> InstantiationMode {
-        let generate_cgu_internal_copies = tcx
-            .sess
-            .opts
-            .debugging_opts
-            .inline_in_all_cgus
-            .unwrap_or_else(|| tcx.sess.opts.optimize != OptLevel::No)
-            && !tcx.sess.opts.cg.link_dead_code;
-
-        match *self {
-            MonoItem::Fn(ref instance) => {
-                let entry_def_id = tcx.entry_fn(LOCAL_CRATE).map(|(id, _)| id);
-                // If this function isn't inlined or otherwise has explicit
-                // linkage, then we'll be creating a globally shared version.
-                if self.explicit_linkage(tcx).is_some()
-                    || !instance.def.generates_cgu_internal_copy(tcx)
-                    || Some(instance.def_id()) == entry_def_id
-                {
-                    return InstantiationMode::GloballyShared { may_conflict: false };
-                }
-
-                // At this point we don't have explicit linkage and we're an
-                // inlined function. If we're inlining into all CGUs then we'll
-                // be creating a local copy per CGU
-                if generate_cgu_internal_copies {
-                    return InstantiationMode::LocalCopy;
-                }
-
-                // Finally, if this is `#[inline(always)]` we're sure to respect
-                // that with an inline copy per CGU, but otherwise we'll be
-                // creating one copy of this `#[inline]` function which may
-                // conflict with upstream crates as it could be an exported
-                // symbol.
-                match tcx.codegen_fn_attrs(instance.def_id()).inline {
-                    InlineAttr::Always => InstantiationMode::LocalCopy,
-                    _ => InstantiationMode::GloballyShared { may_conflict: true },
-                }
-            }
-            MonoItem::Static(..) | MonoItem::GlobalAsm(..) => {
-                InstantiationMode::GloballyShared { may_conflict: false }
-            }
-        }
-    }
-
-    pub fn explicit_linkage(&self, tcx: TyCtxt<'tcx>) -> Option<Linkage> {
-        let def_id = match *self {
-            MonoItem::Fn(ref instance) => instance.def_id(),
-            MonoItem::Static(def_id) => def_id,
-            MonoItem::GlobalAsm(..) => return None,
-        };
-
-        let codegen_fn_attrs = tcx.codegen_fn_attrs(def_id);
-        codegen_fn_attrs.linkage
-    }
-
-    /// Returns `true` if this instance is instantiable - whether it has no unsatisfied
-    /// predicates.
-    ///
-    /// In order to codegen an item, all of its predicates must hold, because
-    /// otherwise the item does not make sense. Type-checking ensures that
-    /// the predicates of every item that is *used by* a valid item *do*
-    /// hold, so we can rely on that.
-    ///
-    /// However, we codegen collector roots (reachable items) and functions
-    /// in vtables when they are seen, even if they are not used, and so they
-    /// might not be instantiable. For example, a programmer can define this
-    /// public function:
-    ///
-    ///     pub fn foo<'a>(s: &'a mut ()) where &'a mut (): Clone {
-    ///         <&mut () as Clone>::clone(&s);
-    ///     }
-    ///
-    /// That function can't be codegened, because the method `<&mut () as Clone>::clone`
-    /// does not exist. Luckily for us, that function can't ever be used,
-    /// because that would require for `&'a mut (): Clone` to hold, so we
-    /// can just not emit any code, or even a linker reference for it.
-    ///
-    /// Similarly, if a vtable method has such a signature, and therefore can't
-    /// be used, we can just not emit it and have a placeholder (a null pointer,
-    /// which will never be accessed) in its place.
-    pub fn is_instantiable(&self, tcx: TyCtxt<'tcx>) -> bool {
-        debug!("is_instantiable({:?})", self);
-        let (def_id, substs) = match *self {
-            MonoItem::Fn(ref instance) => (instance.def_id(), instance.substs),
-            MonoItem::Static(def_id) => (def_id, InternalSubsts::empty()),
-            // global asm never has predicates
-            MonoItem::GlobalAsm(..) => return true,
-        };
-
-        tcx.substitute_normalize_and_test_predicates((def_id, &substs))
-    }
-
-    pub fn to_string(&self, tcx: TyCtxt<'tcx>, debug: bool) -> String {
-        return match *self {
-            MonoItem::Fn(instance) => to_string_internal(tcx, "fn ", instance, debug),
-            MonoItem::Static(def_id) => {
-                let instance = Instance::new(def_id, tcx.intern_substs(&[]));
-                to_string_internal(tcx, "static ", instance, debug)
-            }
-            MonoItem::GlobalAsm(..) => "global_asm".to_string(),
-        };
-
-        fn to_string_internal<'tcx>(
-            tcx: TyCtxt<'tcx>,
-            prefix: &str,
-            instance: Instance<'tcx>,
-            debug: bool,
-        ) -> String {
-            let mut result = String::with_capacity(32);
-            result.push_str(prefix);
-            let printer = DefPathBasedNames::new(tcx, false, false);
-            printer.push_instance_as_string(instance, &mut result, debug);
-            result
-        }
-    }
-
-    pub fn local_span(&self, tcx: TyCtxt<'tcx>) -> Option<Span> {
-        match *self {
-            MonoItem::Fn(Instance { def, .. }) => tcx.hir().as_local_hir_id(def.def_id()),
-            MonoItem::Static(def_id) => tcx.hir().as_local_hir_id(def_id),
-            MonoItem::GlobalAsm(hir_id) => Some(hir_id),
-        }
-        .map(|hir_id| tcx.hir().span(hir_id))
-    }
-}
-
-impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for MonoItem<'tcx> {
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        ::std::mem::discriminant(self).hash_stable(hcx, hasher);
-
-        match *self {
-            MonoItem::Fn(ref instance) => {
-                instance.hash_stable(hcx, hasher);
-            }
-            MonoItem::Static(def_id) => {
-                def_id.hash_stable(hcx, hasher);
-            }
-            MonoItem::GlobalAsm(node_id) => {
-                hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
-                    node_id.hash_stable(hcx, hasher);
-                })
-            }
-        }
-    }
-}
-
-pub struct CodegenUnit<'tcx> {
-    /// A name for this CGU. Incremental compilation requires that
-    /// name be unique amongst **all** crates. Therefore, it should
-    /// contain something unique to this crate (e.g., a module path)
-    /// as well as the crate name and disambiguator.
-    name: Symbol,
-    items: FxHashMap<MonoItem<'tcx>, (Linkage, Visibility)>,
-    size_estimate: Option<usize>,
-}
-
-#[derive(Copy, Clone, PartialEq, Debug, RustcEncodable, RustcDecodable, HashStable)]
-pub enum Linkage {
-    External,
-    AvailableExternally,
-    LinkOnceAny,
-    LinkOnceODR,
-    WeakAny,
-    WeakODR,
-    Appending,
-    Internal,
-    Private,
-    ExternalWeak,
-    Common,
-}
-
-#[derive(Copy, Clone, PartialEq, Debug, HashStable)]
-pub enum Visibility {
-    Default,
-    Hidden,
-    Protected,
-}
-
-impl<'tcx> CodegenUnit<'tcx> {
-    pub fn new(name: Symbol) -> CodegenUnit<'tcx> {
-        CodegenUnit { name: name, items: Default::default(), size_estimate: None }
-    }
-
-    pub fn name(&self) -> Symbol {
-        self.name
-    }
-
-    pub fn set_name(&mut self, name: Symbol) {
-        self.name = name;
-    }
-
-    pub fn items(&self) -> &FxHashMap<MonoItem<'tcx>, (Linkage, Visibility)> {
-        &self.items
-    }
-
-    pub fn items_mut(&mut self) -> &mut FxHashMap<MonoItem<'tcx>, (Linkage, Visibility)> {
-        &mut self.items
-    }
-
-    pub fn mangle_name(human_readable_name: &str) -> String {
-        // We generate a 80 bit hash from the name. This should be enough to
-        // avoid collisions and is still reasonably short for filenames.
-        let mut hasher = StableHasher::new();
-        human_readable_name.hash(&mut hasher);
-        let hash: u128 = hasher.finish();
-        let hash = hash & ((1u128 << 80) - 1);
-        base_n::encode(hash, base_n::CASE_INSENSITIVE)
-    }
-
-    pub fn estimate_size(&mut self, tcx: TyCtxt<'tcx>) {
-        // Estimate the size of a codegen unit as (approximately) the number of MIR
-        // statements it corresponds to.
-        self.size_estimate = Some(self.items.keys().map(|mi| mi.size_estimate(tcx)).sum());
-    }
-
-    pub fn size_estimate(&self) -> usize {
-        // Should only be called if `estimate_size` has previously been called.
-        self.size_estimate.expect("estimate_size must be called before getting a size_estimate")
-    }
-
-    pub fn modify_size_estimate(&mut self, delta: usize) {
-        assert!(self.size_estimate.is_some());
-        if let Some(size_estimate) = self.size_estimate {
-            self.size_estimate = Some(size_estimate + delta);
-        }
-    }
-
-    pub fn contains_item(&self, item: &MonoItem<'tcx>) -> bool {
-        self.items().contains_key(item)
-    }
-
-    pub fn work_product_id(&self) -> WorkProductId {
-        WorkProductId::from_cgu_name(&self.name().as_str())
-    }
-
-    pub fn work_product(&self, tcx: TyCtxt<'_>) -> WorkProduct {
-        let work_product_id = self.work_product_id();
-        tcx.dep_graph
-            .previous_work_product(&work_product_id)
-            .unwrap_or_else(|| panic!("Could not find work-product for CGU `{}`", self.name()))
-    }
-
-    pub fn items_in_deterministic_order(
-        &self,
-        tcx: TyCtxt<'tcx>,
-    ) -> Vec<(MonoItem<'tcx>, (Linkage, Visibility))> {
-        // The codegen tests rely on items being process in the same order as
-        // they appear in the file, so for local items, we sort by node_id first
-        #[derive(PartialEq, Eq, PartialOrd, Ord)]
-        pub struct ItemSortKey(Option<HirId>, SymbolName);
-
-        fn item_sort_key<'tcx>(tcx: TyCtxt<'tcx>, item: MonoItem<'tcx>) -> ItemSortKey {
-            ItemSortKey(
-                match item {
-                    MonoItem::Fn(ref instance) => {
-                        match instance.def {
-                            // We only want to take HirIds of user-defined
-                            // instances into account. The others don't matter for
-                            // the codegen tests and can even make item order
-                            // unstable.
-                            InstanceDef::Item(def_id) => tcx.hir().as_local_hir_id(def_id),
-                            InstanceDef::VtableShim(..)
-                            | InstanceDef::ReifyShim(..)
-                            | InstanceDef::Intrinsic(..)
-                            | InstanceDef::FnPtrShim(..)
-                            | InstanceDef::Virtual(..)
-                            | InstanceDef::ClosureOnceShim { .. }
-                            | InstanceDef::DropGlue(..)
-                            | InstanceDef::CloneShim(..) => None,
-                        }
-                    }
-                    MonoItem::Static(def_id) => tcx.hir().as_local_hir_id(def_id),
-                    MonoItem::GlobalAsm(hir_id) => Some(hir_id),
-                },
-                item.symbol_name(tcx),
-            )
-        }
-
-        let mut items: Vec<_> = self.items().iter().map(|(&i, &l)| (i, l)).collect();
-        items.sort_by_cached_key(|&(i, _)| item_sort_key(tcx, i));
-        items
-    }
-
-    pub fn codegen_dep_node(&self, tcx: TyCtxt<'tcx>) -> DepNode {
-        DepConstructor::CompileCodegenUnit(tcx, self.name())
-    }
-}
-
-impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for CodegenUnit<'tcx> {
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        let CodegenUnit {
-            ref items,
-            name,
-            // The size estimate is not relevant to the hash
-            size_estimate: _,
-        } = *self;
-
-        name.hash_stable(hcx, hasher);
-
-        let mut items: Vec<(Fingerprint, _)> = items
-            .iter()
-            .map(|(mono_item, &attrs)| {
-                let mut hasher = StableHasher::new();
-                mono_item.hash_stable(hcx, &mut hasher);
-                let mono_item_fingerprint = hasher.finish();
-                (mono_item_fingerprint, attrs)
-            })
-            .collect();
-
-        items.sort_unstable_by_key(|i| i.0);
-        items.hash_stable(hcx, hasher);
-    }
-}
-
-pub struct CodegenUnitNameBuilder<'tcx> {
-    tcx: TyCtxt<'tcx>,
-    cache: FxHashMap<CrateNum, String>,
-}
-
-impl CodegenUnitNameBuilder<'tcx> {
-    pub fn new(tcx: TyCtxt<'tcx>) -> Self {
-        CodegenUnitNameBuilder { tcx, cache: Default::default() }
-    }
-
-    /// CGU names should fulfill the following requirements:
-    /// - They should be able to act as a file name on any kind of file system
-    /// - They should not collide with other CGU names, even for different versions
-    ///   of the same crate.
-    ///
-    /// Consequently, we don't use special characters except for '.' and '-' and we
-    /// prefix each name with the crate-name and crate-disambiguator.
-    ///
-    /// This function will build CGU names of the form:
-    ///
-    /// ```
-    /// <crate-name>.<crate-disambiguator>[-in-<local-crate-id>](-<component>)*[.<special-suffix>]
-    /// <local-crate-id> = <local-crate-name>.<local-crate-disambiguator>
-    /// ```
-    ///
-    /// The '.' before `<special-suffix>` makes sure that names with a special
-    /// suffix can never collide with a name built out of regular Rust
-    /// identifiers (e.g., module paths).
-    pub fn build_cgu_name<I, C, S>(
-        &mut self,
-        cnum: CrateNum,
-        components: I,
-        special_suffix: Option<S>,
-    ) -> Symbol
-    where
-        I: IntoIterator<Item = C>,
-        C: fmt::Display,
-        S: fmt::Display,
-    {
-        let cgu_name = self.build_cgu_name_no_mangle(cnum, components, special_suffix);
-
-        if self.tcx.sess.opts.debugging_opts.human_readable_cgu_names {
-            cgu_name
-        } else {
-            let cgu_name = &cgu_name.as_str();
-            Symbol::intern(&CodegenUnit::mangle_name(cgu_name))
-        }
-    }
-
-    /// Same as `CodegenUnit::build_cgu_name()` but will never mangle the
-    /// resulting name.
-    pub fn build_cgu_name_no_mangle<I, C, S>(
-        &mut self,
-        cnum: CrateNum,
-        components: I,
-        special_suffix: Option<S>,
-    ) -> Symbol
-    where
-        I: IntoIterator<Item = C>,
-        C: fmt::Display,
-        S: fmt::Display,
-    {
-        use std::fmt::Write;
-
-        let mut cgu_name = String::with_capacity(64);
-
-        // Start out with the crate name and disambiguator
-        let tcx = self.tcx;
-        let crate_prefix = self.cache.entry(cnum).or_insert_with(|| {
-            // Whenever the cnum is not LOCAL_CRATE we also mix in the
-            // local crate's ID. Otherwise there can be collisions between CGUs
-            // instantiating stuff for upstream crates.
-            let local_crate_id = if cnum != LOCAL_CRATE {
-                let local_crate_disambiguator = format!("{}", tcx.crate_disambiguator(LOCAL_CRATE));
-                format!("-in-{}.{}", tcx.crate_name(LOCAL_CRATE), &local_crate_disambiguator[0..8])
-            } else {
-                String::new()
-            };
-
-            let crate_disambiguator = tcx.crate_disambiguator(cnum).to_string();
-            // Using a shortened disambiguator of about 40 bits
-            format!("{}.{}{}", tcx.crate_name(cnum), &crate_disambiguator[0..8], local_crate_id)
-        });
-
-        write!(cgu_name, "{}", crate_prefix).unwrap();
-
-        // Add the components
-        for component in components {
-            write!(cgu_name, "-{}", component).unwrap();
-        }
-
-        if let Some(special_suffix) = special_suffix {
-            // We add a dot in here so it cannot clash with anything in a regular
-            // Rust identifier
-            write!(cgu_name, ".{}", special_suffix).unwrap();
-        }
-
-        Symbol::intern(&cgu_name[..])
-    }
-}
diff --git a/src/librustc/mir/query.rs b/src/librustc/mir/query.rs
deleted file mode 100644
index 824cdfe55bf..00000000000
--- a/src/librustc/mir/query.rs
+++ /dev/null
@@ -1,229 +0,0 @@
-//! Values computed by queries that use MIR.
-
-use crate::ty::{self, Ty};
-use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::sync::Lrc;
-use rustc_hir as hir;
-use rustc_hir::def_id::DefId;
-use rustc_index::bit_set::BitMatrix;
-use rustc_index::vec::IndexVec;
-use rustc_span::{Span, Symbol};
-use rustc_target::abi::VariantIdx;
-use smallvec::SmallVec;
-
-use super::{Field, SourceInfo};
-
-#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, HashStable)]
-pub enum UnsafetyViolationKind {
-    General,
-    /// Permitted both in `const fn`s and regular `fn`s.
-    GeneralAndConstFn,
-    BorrowPacked(hir::HirId),
-}
-
-#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, HashStable)]
-pub struct UnsafetyViolation {
-    pub source_info: SourceInfo,
-    pub description: Symbol,
-    pub details: Symbol,
-    pub kind: UnsafetyViolationKind,
-}
-
-#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
-pub struct UnsafetyCheckResult {
-    /// Violations that are propagated *upwards* from this function.
-    pub violations: Lrc<[UnsafetyViolation]>,
-    /// `unsafe` blocks in this function, along with whether they are used. This is
-    /// used for the "unused_unsafe" lint.
-    pub unsafe_blocks: Lrc<[(hir::HirId, bool)]>,
-}
-
-rustc_index::newtype_index! {
-    pub struct GeneratorSavedLocal {
-        derive [HashStable]
-        DEBUG_FORMAT = "_{}",
-    }
-}
-
-/// The layout of generator state.
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
-pub struct GeneratorLayout<'tcx> {
-    /// The type of every local stored inside the generator.
-    pub field_tys: IndexVec<GeneratorSavedLocal, Ty<'tcx>>,
-
-    /// Which of the above fields are in each variant. Note that one field may
-    /// be stored in multiple variants.
-    pub variant_fields: IndexVec<VariantIdx, IndexVec<Field, GeneratorSavedLocal>>,
-
-    /// Which saved locals are storage-live at the same time. Locals that do not
-    /// have conflicts with each other are allowed to overlap in the computed
-    /// layout.
-    pub storage_conflicts: BitMatrix<GeneratorSavedLocal, GeneratorSavedLocal>,
-}
-
-#[derive(Debug, RustcEncodable, RustcDecodable, HashStable)]
-pub struct BorrowCheckResult<'tcx> {
-    /// All the opaque types that are restricted to concrete types
-    /// by this function. Unlike the value in `TypeckTables`, this has
-    /// unerased regions.
-    pub concrete_opaque_types: FxHashMap<DefId, ty::ResolvedOpaqueTy<'tcx>>,
-    pub closure_requirements: Option<ClosureRegionRequirements<'tcx>>,
-    pub used_mut_upvars: SmallVec<[Field; 8]>,
-}
-
-/// The result of the `mir_const_qualif` query.
-///
-/// Each field corresponds to an implementer of the `Qualif` trait in
-/// `librustc_mir/transform/check_consts/qualifs.rs`. See that file for more information on each
-/// `Qualif`.
-#[derive(Clone, Copy, Debug, Default, RustcEncodable, RustcDecodable, HashStable)]
-pub struct ConstQualifs {
-    pub has_mut_interior: bool,
-    pub needs_drop: bool,
-}
-
-/// After we borrow check a closure, we are left with various
-/// requirements that we have inferred between the free regions that
-/// appear in the closure's signature or on its field types. These
-/// requirements are then verified and proved by the closure's
-/// creating function. This struct encodes those requirements.
-///
-/// The requirements are listed as being between various
-/// `RegionVid`. The 0th region refers to `'static`; subsequent region
-/// vids refer to the free regions that appear in the closure (or
-/// generator's) type, in order of appearance. (This numbering is
-/// actually defined by the `UniversalRegions` struct in the NLL
-/// region checker. See for example
-/// `UniversalRegions::closure_mapping`.) Note that we treat the free
-/// regions in the closure's type "as if" they were erased, so their
-/// precise identity is not important, only their position.
-///
-/// Example: If type check produces a closure with the closure substs:
-///
-/// ```text
-/// ClosureSubsts = [
-///     i8,                                  // the "closure kind"
-///     for<'x> fn(&'a &'x u32) -> &'x u32,  // the "closure signature"
-///     &'a String,                          // some upvar
-/// ]
-/// ```
-///
-/// here, there is one unique free region (`'a`) but it appears
-/// twice. We would "renumber" each occurrence to a unique vid, as follows:
-///
-/// ```text
-/// ClosureSubsts = [
-///     i8,                                  // the "closure kind"
-///     for<'x> fn(&'1 &'x u32) -> &'x u32,  // the "closure signature"
-///     &'2 String,                          // some upvar
-/// ]
-/// ```
-///
-/// Now the code might impose a requirement like `'1: '2`. When an
-/// instance of the closure is created, the corresponding free regions
-/// can be extracted from its type and constrained to have the given
-/// outlives relationship.
-///
-/// In some cases, we have to record outlives requirements between
-/// types and regions as well. In that case, if those types include
-/// any regions, those regions are recorded as `ReClosureBound`
-/// instances assigned one of these same indices. Those regions will
-/// be substituted away by the creator. We use `ReClosureBound` in
-/// that case because the regions must be allocated in the global
-/// `TyCtxt`, and hence we cannot use `ReVar` (which is what we use
-/// internally within the rest of the NLL code).
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
-pub struct ClosureRegionRequirements<'tcx> {
-    /// The number of external regions defined on the closure. In our
-    /// example above, it would be 3 -- one for `'static`, then `'1`
-    /// and `'2`. This is just used for a sanity check later on, to
-    /// make sure that the number of regions we see at the callsite
-    /// matches.
-    pub num_external_vids: usize,
-
-    /// Requirements between the various free regions defined in
-    /// indices.
-    pub outlives_requirements: Vec<ClosureOutlivesRequirement<'tcx>>,
-}
-
-/// Indicates an outlives-constraint between a type or between two
-/// free regions declared on the closure.
-#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
-pub struct ClosureOutlivesRequirement<'tcx> {
-    // This region or type ...
-    pub subject: ClosureOutlivesSubject<'tcx>,
-
-    // ... must outlive this one.
-    pub outlived_free_region: ty::RegionVid,
-
-    // If not, report an error here ...
-    pub blame_span: Span,
-
-    // ... due to this reason.
-    pub category: ConstraintCategory,
-}
-
-/// Outlives-constraints can be categorized to determine whether and why they
-/// are interesting (for error reporting). Order of variants indicates sort
-/// order of the category, thereby influencing diagnostic output.
-///
-/// See also [rustc_mir::borrow_check::nll::constraints].
-#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)]
-#[derive(RustcEncodable, RustcDecodable, HashStable)]
-pub enum ConstraintCategory {
-    Return,
-    Yield,
-    UseAsConst,
-    UseAsStatic,
-    TypeAnnotation,
-    Cast,
-
-    /// A constraint that came from checking the body of a closure.
-    ///
-    /// We try to get the category that the closure used when reporting this.
-    ClosureBounds,
-    CallArgument,
-    CopyBound,
-    SizedBound,
-    Assignment,
-    OpaqueType,
-
-    /// A "boring" constraint (caused by the given location) is one that
-    /// the user probably doesn't want to see described in diagnostics,
-    /// because it is kind of an artifact of the type system setup.
-    /// Example: `x = Foo { field: y }` technically creates
-    /// intermediate regions representing the "type of `Foo { field: y
-    /// }`", and data flows from `y` into those variables, but they
-    /// are not very interesting. The assignment into `x` on the other
-    /// hand might be.
-    Boring,
-    // Boring and applicable everywhere.
-    BoringNoLocation,
-
-    /// A constraint that doesn't correspond to anything the user sees.
-    Internal,
-}
-
-/// The subject of a `ClosureOutlivesRequirement` -- that is, the thing
-/// that must outlive some region.
-#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
-pub enum ClosureOutlivesSubject<'tcx> {
-    /// Subject is a type, typically a type parameter, but could also
-    /// be a projection. Indicates a requirement like `T: 'a` being
-    /// passed to the caller, where the type here is `T`.
-    ///
-    /// The type here is guaranteed not to contain any free regions at
-    /// present.
-    Ty(Ty<'tcx>),
-
-    /// Subject is a free region from the closure. Indicates a requirement
-    /// like `'a: 'b` being passed to the caller; the region here is `'a`.
-    Region(ty::RegionVid),
-}
-
-/// The constituent parts of an ADT or array.
-#[derive(Copy, Clone, Debug, HashStable)]
-pub struct DestructuredConst<'tcx> {
-    pub variant: VariantIdx,
-    pub fields: &'tcx [&'tcx ty::Const<'tcx>],
-}
diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs
deleted file mode 100644
index e6c7c84494c..00000000000
--- a/src/librustc/mir/tcx.rs
+++ /dev/null
@@ -1,291 +0,0 @@
-/*!
- * Methods for the various MIR types. These are intended for use after
- * building is complete.
- */
-
-use crate::mir::*;
-use crate::ty::layout::VariantIdx;
-use crate::ty::subst::Subst;
-use crate::ty::util::IntTypeExt;
-use crate::ty::{self, Ty, TyCtxt};
-use rustc_hir as hir;
-
-#[derive(Copy, Clone, Debug, TypeFoldable)]
-pub struct PlaceTy<'tcx> {
-    pub ty: Ty<'tcx>,
-    /// Downcast to a particular variant of an enum, if included.
-    pub variant_index: Option<VariantIdx>,
-}
-
-// At least on 64 bit systems, `PlaceTy` should not be larger than two or three pointers.
-#[cfg(target_arch = "x86_64")]
-static_assert_size!(PlaceTy<'_>, 16);
-
-impl<'tcx> PlaceTy<'tcx> {
-    pub fn from_ty(ty: Ty<'tcx>) -> PlaceTy<'tcx> {
-        PlaceTy { ty, variant_index: None }
-    }
-
-    /// `place_ty.field_ty(tcx, f)` computes the type at a given field
-    /// of a record or enum-variant. (Most clients of `PlaceTy` can
-    /// instead just extract the relevant type directly from their
-    /// `PlaceElem`, but some instances of `ProjectionElem<V, T>` do
-    /// not carry a `Ty` for `T`.)
-    ///
-    /// Note that the resulting type has not been normalized.
-    pub fn field_ty(self, tcx: TyCtxt<'tcx>, f: &Field) -> Ty<'tcx> {
-        let answer = match self.ty.kind {
-            ty::Adt(adt_def, substs) => {
-                let variant_def = match self.variant_index {
-                    None => adt_def.non_enum_variant(),
-                    Some(variant_index) => {
-                        assert!(adt_def.is_enum());
-                        &adt_def.variants[variant_index]
-                    }
-                };
-                let field_def = &variant_def.fields[f.index()];
-                field_def.ty(tcx, substs)
-            }
-            ty::Tuple(ref tys) => tys[f.index()].expect_ty(),
-            _ => bug!("extracting field of non-tuple non-adt: {:?}", self),
-        };
-        debug!("field_ty self: {:?} f: {:?} yields: {:?}", self, f, answer);
-        answer
-    }
-
-    /// Convenience wrapper around `projection_ty_core` for
-    /// `PlaceElem`, where we can just use the `Ty` that is already
-    /// stored inline on field projection elems.
-    pub fn projection_ty(self, tcx: TyCtxt<'tcx>, elem: &PlaceElem<'tcx>) -> PlaceTy<'tcx> {
-        self.projection_ty_core(tcx, ty::ParamEnv::empty(), elem, |_, _, ty| ty)
-    }
-
-    /// `place_ty.projection_ty_core(tcx, elem, |...| { ... })`
-    /// projects `place_ty` onto `elem`, returning the appropriate
-    /// `Ty` or downcast variant corresponding to that projection.
-    /// The `handle_field` callback must map a `Field` to its `Ty`,
-    /// (which should be trivial when `T` = `Ty`).
-    pub fn projection_ty_core<V, T>(
-        self,
-        tcx: TyCtxt<'tcx>,
-        param_env: ty::ParamEnv<'tcx>,
-        elem: &ProjectionElem<V, T>,
-        mut handle_field: impl FnMut(&Self, &Field, &T) -> Ty<'tcx>,
-    ) -> PlaceTy<'tcx>
-    where
-        V: ::std::fmt::Debug,
-        T: ::std::fmt::Debug,
-    {
-        let answer = match *elem {
-            ProjectionElem::Deref => {
-                let ty = self
-                    .ty
-                    .builtin_deref(true)
-                    .unwrap_or_else(|| {
-                        bug!("deref projection of non-dereferenceable ty {:?}", self)
-                    })
-                    .ty;
-                PlaceTy::from_ty(ty)
-            }
-            ProjectionElem::Index(_) | ProjectionElem::ConstantIndex { .. } => {
-                PlaceTy::from_ty(self.ty.builtin_index().unwrap())
-            }
-            ProjectionElem::Subslice { from, to, from_end } => {
-                PlaceTy::from_ty(match self.ty.kind {
-                    ty::Slice(..) => self.ty,
-                    ty::Array(inner, _) if !from_end => tcx.mk_array(inner, (to - from) as u64),
-                    ty::Array(inner, size) if from_end => {
-                        let size = size.eval_usize(tcx, param_env);
-                        let len = size - (from as u64) - (to as u64);
-                        tcx.mk_array(inner, len)
-                    }
-                    _ => bug!("cannot subslice non-array type: `{:?}`", self),
-                })
-            }
-            ProjectionElem::Downcast(_name, index) => {
-                PlaceTy { ty: self.ty, variant_index: Some(index) }
-            }
-            ProjectionElem::Field(ref f, ref fty) => PlaceTy::from_ty(handle_field(&self, f, fty)),
-        };
-        debug!("projection_ty self: {:?} elem: {:?} yields: {:?}", self, elem, answer);
-        answer
-    }
-}
-
-impl<'tcx> Place<'tcx> {
-    pub fn ty_from<D>(
-        local: Local,
-        projection: &[PlaceElem<'tcx>],
-        local_decls: &D,
-        tcx: TyCtxt<'tcx>,
-    ) -> PlaceTy<'tcx>
-    where
-        D: HasLocalDecls<'tcx>,
-    {
-        projection
-            .iter()
-            .fold(PlaceTy::from_ty(local_decls.local_decls()[local].ty), |place_ty, elem| {
-                place_ty.projection_ty(tcx, elem)
-            })
-    }
-
-    pub fn ty<D>(&self, local_decls: &D, tcx: TyCtxt<'tcx>) -> PlaceTy<'tcx>
-    where
-        D: HasLocalDecls<'tcx>,
-    {
-        Place::ty_from(self.local, &self.projection, local_decls, tcx)
-    }
-}
-
-pub enum RvalueInitializationState {
-    Shallow,
-    Deep,
-}
-
-impl<'tcx> Rvalue<'tcx> {
-    pub fn ty<D>(&self, local_decls: &D, tcx: TyCtxt<'tcx>) -> Ty<'tcx>
-    where
-        D: HasLocalDecls<'tcx>,
-    {
-        match *self {
-            Rvalue::Use(ref operand) => operand.ty(local_decls, tcx),
-            Rvalue::Repeat(ref operand, count) => tcx.mk_array(operand.ty(local_decls, tcx), count),
-            Rvalue::Ref(reg, bk, ref place) => {
-                let place_ty = place.ty(local_decls, tcx).ty;
-                tcx.mk_ref(reg, ty::TypeAndMut { ty: place_ty, mutbl: bk.to_mutbl_lossy() })
-            }
-            Rvalue::AddressOf(mutability, ref place) => {
-                let place_ty = place.ty(local_decls, tcx).ty;
-                tcx.mk_ptr(ty::TypeAndMut { ty: place_ty, mutbl: mutability.into() })
-            }
-            Rvalue::Len(..) => tcx.types.usize,
-            Rvalue::Cast(.., ty) => ty,
-            Rvalue::BinaryOp(op, ref lhs, ref rhs) => {
-                let lhs_ty = lhs.ty(local_decls, tcx);
-                let rhs_ty = rhs.ty(local_decls, tcx);
-                op.ty(tcx, lhs_ty, rhs_ty)
-            }
-            Rvalue::CheckedBinaryOp(op, ref lhs, ref rhs) => {
-                let lhs_ty = lhs.ty(local_decls, tcx);
-                let rhs_ty = rhs.ty(local_decls, tcx);
-                let ty = op.ty(tcx, lhs_ty, rhs_ty);
-                tcx.intern_tup(&[ty, tcx.types.bool])
-            }
-            Rvalue::UnaryOp(UnOp::Not, ref operand) | Rvalue::UnaryOp(UnOp::Neg, ref operand) => {
-                operand.ty(local_decls, tcx)
-            }
-            Rvalue::Discriminant(ref place) => {
-                let ty = place.ty(local_decls, tcx).ty;
-                match ty.kind {
-                    ty::Adt(adt_def, _) => adt_def.repr.discr_type().to_ty(tcx),
-                    ty::Generator(_, substs, _) => substs.as_generator().discr_ty(tcx),
-                    _ => {
-                        // This can only be `0`, for now, so `u8` will suffice.
-                        tcx.types.u8
-                    }
-                }
-            }
-            Rvalue::NullaryOp(NullOp::Box, t) => tcx.mk_box(t),
-            Rvalue::NullaryOp(NullOp::SizeOf, _) => tcx.types.usize,
-            Rvalue::Aggregate(ref ak, ref ops) => match **ak {
-                AggregateKind::Array(ty) => tcx.mk_array(ty, ops.len() as u64),
-                AggregateKind::Tuple => tcx.mk_tup(ops.iter().map(|op| op.ty(local_decls, tcx))),
-                AggregateKind::Adt(def, _, substs, _, _) => tcx.type_of(def.did).subst(tcx, substs),
-                AggregateKind::Closure(did, substs) => tcx.mk_closure(did, substs),
-                AggregateKind::Generator(did, substs, movability) => {
-                    tcx.mk_generator(did, substs, movability)
-                }
-            },
-        }
-    }
-
-    #[inline]
-    /// Returns `true` if this rvalue is deeply initialized (most rvalues) or
-    /// whether its only shallowly initialized (`Rvalue::Box`).
-    pub fn initialization_state(&self) -> RvalueInitializationState {
-        match *self {
-            Rvalue::NullaryOp(NullOp::Box, _) => RvalueInitializationState::Shallow,
-            _ => RvalueInitializationState::Deep,
-        }
-    }
-}
-
-impl<'tcx> Operand<'tcx> {
-    pub fn ty<D>(&self, local_decls: &D, tcx: TyCtxt<'tcx>) -> Ty<'tcx>
-    where
-        D: HasLocalDecls<'tcx>,
-    {
-        match self {
-            &Operand::Copy(ref l) | &Operand::Move(ref l) => l.ty(local_decls, tcx).ty,
-            &Operand::Constant(ref c) => c.literal.ty,
-        }
-    }
-}
-
-impl<'tcx> BinOp {
-    pub fn ty(&self, tcx: TyCtxt<'tcx>, lhs_ty: Ty<'tcx>, rhs_ty: Ty<'tcx>) -> Ty<'tcx> {
-        // FIXME: handle SIMD correctly
-        match self {
-            &BinOp::Add
-            | &BinOp::Sub
-            | &BinOp::Mul
-            | &BinOp::Div
-            | &BinOp::Rem
-            | &BinOp::BitXor
-            | &BinOp::BitAnd
-            | &BinOp::BitOr => {
-                // these should be integers or floats of the same size.
-                assert_eq!(lhs_ty, rhs_ty);
-                lhs_ty
-            }
-            &BinOp::Shl | &BinOp::Shr | &BinOp::Offset => {
-                lhs_ty // lhs_ty can be != rhs_ty
-            }
-            &BinOp::Eq | &BinOp::Lt | &BinOp::Le | &BinOp::Ne | &BinOp::Ge | &BinOp::Gt => {
-                tcx.types.bool
-            }
-        }
-    }
-}
-
-impl BorrowKind {
-    pub fn to_mutbl_lossy(self) -> hir::Mutability {
-        match self {
-            BorrowKind::Mut { .. } => hir::Mutability::Mut,
-            BorrowKind::Shared => hir::Mutability::Not,
-
-            // We have no type corresponding to a unique imm borrow, so
-            // use `&mut`. It gives all the capabilities of an `&uniq`
-            // and hence is a safe "over approximation".
-            BorrowKind::Unique => hir::Mutability::Mut,
-
-            // We have no type corresponding to a shallow borrow, so use
-            // `&` as an approximation.
-            BorrowKind::Shallow => hir::Mutability::Not,
-        }
-    }
-}
-
-impl BinOp {
-    pub fn to_hir_binop(self) -> hir::BinOpKind {
-        match self {
-            BinOp::Add => hir::BinOpKind::Add,
-            BinOp::Sub => hir::BinOpKind::Sub,
-            BinOp::Mul => hir::BinOpKind::Mul,
-            BinOp::Div => hir::BinOpKind::Div,
-            BinOp::Rem => hir::BinOpKind::Rem,
-            BinOp::BitXor => hir::BinOpKind::BitXor,
-            BinOp::BitAnd => hir::BinOpKind::BitAnd,
-            BinOp::BitOr => hir::BinOpKind::BitOr,
-            BinOp::Shl => hir::BinOpKind::Shl,
-            BinOp::Shr => hir::BinOpKind::Shr,
-            BinOp::Eq => hir::BinOpKind::Eq,
-            BinOp::Ne => hir::BinOpKind::Ne,
-            BinOp::Lt => hir::BinOpKind::Lt,
-            BinOp::Gt => hir::BinOpKind::Gt,
-            BinOp::Le => hir::BinOpKind::Le,
-            BinOp::Ge => hir::BinOpKind::Ge,
-            BinOp::Offset => unreachable!(),
-        }
-    }
-}
diff --git a/src/librustc/mir/traversal.rs b/src/librustc/mir/traversal.rs
deleted file mode 100644
index ed8129b1e09..00000000000
--- a/src/librustc/mir/traversal.rs
+++ /dev/null
@@ -1,294 +0,0 @@
-use rustc_index::bit_set::BitSet;
-
-use super::*;
-
-/// Preorder traversal of a graph.
-///
-/// Preorder traversal is when each node is visited before any of its
-/// successors
-///
-/// ```text
-///
-///         A
-///        / \
-///       /   \
-///      B     C
-///       \   /
-///        \ /
-///         D
-/// ```
-///
-/// A preorder traversal of this graph is either `A B D C` or `A C D B`
-#[derive(Clone)]
-pub struct Preorder<'a, 'tcx> {
-    body: &'a Body<'tcx>,
-    visited: BitSet<BasicBlock>,
-    worklist: Vec<BasicBlock>,
-    root_is_start_block: bool,
-}
-
-impl<'a, 'tcx> Preorder<'a, 'tcx> {
-    pub fn new(body: &'a Body<'tcx>, root: BasicBlock) -> Preorder<'a, 'tcx> {
-        let worklist = vec![root];
-
-        Preorder {
-            body,
-            visited: BitSet::new_empty(body.basic_blocks().len()),
-            worklist,
-            root_is_start_block: root == START_BLOCK,
-        }
-    }
-}
-
-pub fn preorder<'a, 'tcx>(body: &'a Body<'tcx>) -> Preorder<'a, 'tcx> {
-    Preorder::new(body, START_BLOCK)
-}
-
-impl<'a, 'tcx> Iterator for Preorder<'a, 'tcx> {
-    type Item = (BasicBlock, &'a BasicBlockData<'tcx>);
-
-    fn next(&mut self) -> Option<(BasicBlock, &'a BasicBlockData<'tcx>)> {
-        while let Some(idx) = self.worklist.pop() {
-            if !self.visited.insert(idx) {
-                continue;
-            }
-
-            let data = &self.body[idx];
-
-            if let Some(ref term) = data.terminator {
-                self.worklist.extend(term.successors());
-            }
-
-            return Some((idx, data));
-        }
-
-        None
-    }
-
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        // All the blocks, minus the number of blocks we've visited.
-        let upper = self.body.basic_blocks().len() - self.visited.count();
-
-        let lower = if self.root_is_start_block {
-            // We will visit all remaining blocks exactly once.
-            upper
-        } else {
-            self.worklist.len()
-        };
-
-        (lower, Some(upper))
-    }
-}
-
-/// Postorder traversal of a graph.
-///
-/// Postorder traversal is when each node is visited after all of its
-/// successors, except when the successor is only reachable by a back-edge
-///
-///
-/// ```text
-///
-///         A
-///        / \
-///       /   \
-///      B     C
-///       \   /
-///        \ /
-///         D
-/// ```
-///
-/// A Postorder traversal of this graph is `D B C A` or `D C B A`
-pub struct Postorder<'a, 'tcx> {
-    body: &'a Body<'tcx>,
-    visited: BitSet<BasicBlock>,
-    visit_stack: Vec<(BasicBlock, Successors<'a>)>,
-    root_is_start_block: bool,
-}
-
-impl<'a, 'tcx> Postorder<'a, 'tcx> {
-    pub fn new(body: &'a Body<'tcx>, root: BasicBlock) -> Postorder<'a, 'tcx> {
-        let mut po = Postorder {
-            body,
-            visited: BitSet::new_empty(body.basic_blocks().len()),
-            visit_stack: Vec::new(),
-            root_is_start_block: root == START_BLOCK,
-        };
-
-        let data = &po.body[root];
-
-        if let Some(ref term) = data.terminator {
-            po.visited.insert(root);
-            po.visit_stack.push((root, term.successors()));
-            po.traverse_successor();
-        }
-
-        po
-    }
-
-    fn traverse_successor(&mut self) {
-        // This is quite a complex loop due to 1. the borrow checker not liking it much
-        // and 2. what exactly is going on is not clear
-        //
-        // It does the actual traversal of the graph, while the `next` method on the iterator
-        // just pops off of the stack. `visit_stack` is a stack containing pairs of nodes and
-        // iterators over the successors of those nodes. Each iteration attempts to get the next
-        // node from the top of the stack, then pushes that node and an iterator over the
-        // successors to the top of the stack. This loop only grows `visit_stack`, stopping when
-        // we reach a child that has no children that we haven't already visited.
-        //
-        // For a graph that looks like this:
-        //
-        //         A
-        //        / \
-        //       /   \
-        //      B     C
-        //      |     |
-        //      |     |
-        //      D     |
-        //       \   /
-        //        \ /
-        //         E
-        //
-        // The state of the stack starts out with just the root node (`A` in this case);
-        //     [(A, [B, C])]
-        //
-        // When the first call to `traverse_successor` happens, the following happens:
-        //
-        //     [(B, [D]),  // `B` taken from the successors of `A`, pushed to the
-        //                 // top of the stack along with the successors of `B`
-        //      (A, [C])]
-        //
-        //     [(D, [E]),  // `D` taken from successors of `B`, pushed to stack
-        //      (B, []),
-        //      (A, [C])]
-        //
-        //     [(E, []),   // `E` taken from successors of `D`, pushed to stack
-        //      (D, []),
-        //      (B, []),
-        //      (A, [C])]
-        //
-        // Now that the top of the stack has no successors we can traverse, each item will
-        // be popped off during iteration until we get back to `A`. This yields [E, D, B].
-        //
-        // When we yield `B` and call `traverse_successor`, we push `C` to the stack, but
-        // since we've already visited `E`, that child isn't added to the stack. The last
-        // two iterations yield `C` and finally `A` for a final traversal of [E, D, B, C, A]
-        loop {
-            let bb = if let Some(&mut (_, ref mut iter)) = self.visit_stack.last_mut() {
-                if let Some(&bb) = iter.next() {
-                    bb
-                } else {
-                    break;
-                }
-            } else {
-                break;
-            };
-
-            if self.visited.insert(bb) {
-                if let Some(term) = &self.body[bb].terminator {
-                    self.visit_stack.push((bb, term.successors()));
-                }
-            }
-        }
-    }
-}
-
-pub fn postorder<'a, 'tcx>(body: &'a Body<'tcx>) -> Postorder<'a, 'tcx> {
-    Postorder::new(body, START_BLOCK)
-}
-
-impl<'a, 'tcx> Iterator for Postorder<'a, 'tcx> {
-    type Item = (BasicBlock, &'a BasicBlockData<'tcx>);
-
-    fn next(&mut self) -> Option<(BasicBlock, &'a BasicBlockData<'tcx>)> {
-        let next = self.visit_stack.pop();
-        if next.is_some() {
-            self.traverse_successor();
-        }
-
-        next.map(|(bb, _)| (bb, &self.body[bb]))
-    }
-
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        // All the blocks, minus the number of blocks we've visited.
-        let upper = self.body.basic_blocks().len() - self.visited.count();
-
-        let lower = if self.root_is_start_block {
-            // We will visit all remaining blocks exactly once.
-            upper
-        } else {
-            self.visit_stack.len()
-        };
-
-        (lower, Some(upper))
-    }
-}
-
-/// Reverse postorder traversal of a graph
-///
-/// Reverse postorder is the reverse order of a postorder traversal.
-/// This is different to a preorder traversal and represents a natural
-/// linearization of control-flow.
-///
-/// ```text
-///
-///         A
-///        / \
-///       /   \
-///      B     C
-///       \   /
-///        \ /
-///         D
-/// ```
-///
-/// A reverse postorder traversal of this graph is either `A B C D` or `A C B D`
-/// Note that for a graph containing no loops (i.e., A DAG), this is equivalent to
-/// a topological sort.
-///
-/// Construction of a `ReversePostorder` traversal requires doing a full
-/// postorder traversal of the graph, therefore this traversal should be
-/// constructed as few times as possible. Use the `reset` method to be able
-/// to re-use the traversal
-#[derive(Clone)]
-pub struct ReversePostorder<'a, 'tcx> {
-    body: &'a Body<'tcx>,
-    blocks: Vec<BasicBlock>,
-    idx: usize,
-}
-
-impl<'a, 'tcx> ReversePostorder<'a, 'tcx> {
-    pub fn new(body: &'a Body<'tcx>, root: BasicBlock) -> ReversePostorder<'a, 'tcx> {
-        let blocks: Vec<_> = Postorder::new(body, root).map(|(bb, _)| bb).collect();
-
-        let len = blocks.len();
-
-        ReversePostorder { body, blocks, idx: len }
-    }
-
-    pub fn reset(&mut self) {
-        self.idx = self.blocks.len();
-    }
-}
-
-pub fn reverse_postorder<'a, 'tcx>(body: &'a Body<'tcx>) -> ReversePostorder<'a, 'tcx> {
-    ReversePostorder::new(body, START_BLOCK)
-}
-
-impl<'a, 'tcx> Iterator for ReversePostorder<'a, 'tcx> {
-    type Item = (BasicBlock, &'a BasicBlockData<'tcx>);
-
-    fn next(&mut self) -> Option<(BasicBlock, &'a BasicBlockData<'tcx>)> {
-        if self.idx == 0 {
-            return None;
-        }
-        self.idx -= 1;
-
-        self.blocks.get(self.idx).map(|&bb| (bb, &self.body[bb]))
-    }
-
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        (self.idx, Some(self.idx))
-    }
-}
-
-impl<'a, 'tcx> ExactSizeIterator for ReversePostorder<'a, 'tcx> {}
diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs
deleted file mode 100644
index 409c981801b..00000000000
--- a/src/librustc/mir/visit.rs
+++ /dev/null
@@ -1,1177 +0,0 @@
-use crate::mir::*;
-use crate::ty::subst::SubstsRef;
-use crate::ty::{CanonicalUserTypeAnnotation, Ty};
-use rustc_span::Span;
-
-// # The MIR Visitor
-//
-// ## Overview
-//
-// There are two visitors, one for immutable and one for mutable references,
-// but both are generated by the following macro. The code is written according
-// to the following conventions:
-//
-// - introduce a `visit_foo` and a `super_foo` method for every MIR type
-// - `visit_foo`, by default, calls `super_foo`
-// - `super_foo`, by default, destructures the `foo` and calls `visit_foo`
-//
-// This allows you as a user to override `visit_foo` for types are
-// interested in, and invoke (within that method) call
-// `self.super_foo` to get the default behavior. Just as in an OO
-// language, you should never call `super` methods ordinarily except
-// in that circumstance.
-//
-// For the most part, we do not destructure things external to the
-// MIR, e.g., types, spans, etc, but simply visit them and stop. This
-// avoids duplication with other visitors like `TypeFoldable`.
-//
-// ## Updating
-//
-// The code is written in a very deliberate style intended to minimize
-// the chance of things being overlooked. You'll notice that we always
-// use pattern matching to reference fields and we ensure that all
-// matches are exhaustive.
-//
-// For example, the `super_basic_block_data` method begins like this:
-//
-// ```rust
-// fn super_basic_block_data(&mut self,
-//                           block: BasicBlock,
-//                           data: & $($mutability)? BasicBlockData<'tcx>) {
-//     let BasicBlockData {
-//         statements,
-//         terminator,
-//         is_cleanup: _
-//     } = *data;
-//
-//     for statement in statements {
-//         self.visit_statement(block, statement);
-//     }
-//
-//     ...
-// }
-// ```
-//
-// Here we used `let BasicBlockData { <fields> } = *data` deliberately,
-// rather than writing `data.statements` in the body. This is because if one
-// adds a new field to `BasicBlockData`, one will be forced to revise this code,
-// and hence one will (hopefully) invoke the correct visit methods (if any).
-//
-// For this to work, ALL MATCHES MUST BE EXHAUSTIVE IN FIELDS AND VARIANTS.
-// That means you never write `..` to skip over fields, nor do you write `_`
-// to skip over variants in a `match`.
-//
-// The only place that `_` is acceptable is to match a field (or
-// variant argument) that does not require visiting, as in
-// `is_cleanup` above.
-
-macro_rules! body_cache_type {
-    (mut $a:lifetime, $tcx:lifetime) => {
-        &mut BodyAndCache<$tcx>
-    };
-    ($a:lifetime, $tcx:lifetime) => {
-        ReadOnlyBodyAndCache<$a, $tcx>
-    };
-}
-
-macro_rules! make_mir_visitor {
-    ($visitor_trait_name:ident, $($mutability:ident)?) => {
-        pub trait $visitor_trait_name<'tcx> {
-            // Override these, and call `self.super_xxx` to revert back to the
-            // default behavior.
-
-            fn visit_body(
-                &mut self,
-                body: body_cache_type!($($mutability)? '_, 'tcx)
-            ) {
-                self.super_body(body);
-            }
-
-            fn visit_basic_block_data(&mut self,
-                                      block: BasicBlock,
-                                      data: & $($mutability)? BasicBlockData<'tcx>) {
-                self.super_basic_block_data(block, data);
-            }
-
-            fn visit_source_scope_data(&mut self,
-                                           scope_data: & $($mutability)? SourceScopeData) {
-                self.super_source_scope_data(scope_data);
-            }
-
-            fn visit_statement(&mut self,
-                               statement: & $($mutability)? Statement<'tcx>,
-                               location: Location) {
-                self.super_statement(statement, location);
-            }
-
-            fn visit_assign(&mut self,
-                            place: & $($mutability)? Place<'tcx>,
-                            rvalue: & $($mutability)? Rvalue<'tcx>,
-                            location: Location) {
-                self.super_assign(place, rvalue, location);
-            }
-
-            fn visit_terminator(&mut self,
-                                terminator: & $($mutability)? Terminator<'tcx>,
-                                location: Location) {
-                self.super_terminator(terminator, location);
-            }
-
-            fn visit_terminator_kind(&mut self,
-                                     kind: & $($mutability)? TerminatorKind<'tcx>,
-                                     location: Location) {
-                self.super_terminator_kind(kind, location);
-            }
-
-            fn visit_assert_message(&mut self,
-                                    msg: & $($mutability)? AssertMessage<'tcx>,
-                                    location: Location) {
-                self.super_assert_message(msg, location);
-            }
-
-            fn visit_rvalue(&mut self,
-                            rvalue: & $($mutability)? Rvalue<'tcx>,
-                            location: Location) {
-                self.super_rvalue(rvalue, location);
-            }
-
-            fn visit_operand(&mut self,
-                             operand: & $($mutability)? Operand<'tcx>,
-                             location: Location) {
-                self.super_operand(operand, location);
-            }
-
-            fn visit_ascribe_user_ty(&mut self,
-                                     place: & $($mutability)? Place<'tcx>,
-                                     variance: & $($mutability)? ty::Variance,
-                                     user_ty: & $($mutability)? UserTypeProjection,
-                                     location: Location) {
-                self.super_ascribe_user_ty(place, variance, user_ty, location);
-            }
-
-            fn visit_retag(&mut self,
-                           kind: & $($mutability)? RetagKind,
-                           place: & $($mutability)? Place<'tcx>,
-                           location: Location) {
-                self.super_retag(kind, place, location);
-            }
-
-            fn visit_place(&mut self,
-                            place: & $($mutability)? Place<'tcx>,
-                            context: PlaceContext,
-                            location: Location) {
-                self.super_place(place, context, location);
-            }
-
-            fn visit_place_base(&mut self,
-                                local: & $($mutability)? Local,
-                                context: PlaceContext,
-                                location: Location) {
-                self.super_place_base(local, context, location);
-            }
-
-            visit_place_fns!($($mutability)?);
-
-            fn visit_constant(&mut self,
-                              constant: & $($mutability)? Constant<'tcx>,
-                              location: Location) {
-                self.super_constant(constant, location);
-            }
-
-            fn visit_span(&mut self,
-                          span: & $($mutability)? Span) {
-                self.super_span(span);
-            }
-
-            fn visit_source_info(&mut self,
-                                 source_info: & $($mutability)? SourceInfo) {
-                self.super_source_info(source_info);
-            }
-
-            fn visit_ty(&mut self,
-                        ty: $(& $mutability)? Ty<'tcx>,
-                        _: TyContext) {
-                self.super_ty(ty);
-            }
-
-            fn visit_user_type_projection(
-                &mut self,
-                ty: & $($mutability)? UserTypeProjection,
-            ) {
-                self.super_user_type_projection(ty);
-            }
-
-            fn visit_user_type_annotation(
-                &mut self,
-                index: UserTypeAnnotationIndex,
-                ty: & $($mutability)? CanonicalUserTypeAnnotation<'tcx>,
-            ) {
-                self.super_user_type_annotation(index, ty);
-            }
-
-            fn visit_region(&mut self,
-                            region: & $($mutability)? ty::Region<'tcx>,
-                            _: Location) {
-                self.super_region(region);
-            }
-
-            fn visit_const(&mut self,
-                           constant: & $($mutability)? &'tcx ty::Const<'tcx>,
-                           _: Location) {
-                self.super_const(constant);
-            }
-
-            fn visit_substs(&mut self,
-                            substs: & $($mutability)? SubstsRef<'tcx>,
-                            _: Location) {
-                self.super_substs(substs);
-            }
-
-            fn visit_local_decl(&mut self,
-                                local: Local,
-                                local_decl: & $($mutability)? LocalDecl<'tcx>) {
-                self.super_local_decl(local, local_decl);
-            }
-
-            fn visit_var_debug_info(&mut self,
-                                    var_debug_info: & $($mutability)* VarDebugInfo<'tcx>) {
-                self.super_var_debug_info(var_debug_info);
-            }
-
-            fn visit_local(&mut self,
-                            _local: & $($mutability)? Local,
-                            _context: PlaceContext,
-                            _location: Location) {
-            }
-
-            fn visit_source_scope(&mut self,
-                                      scope: & $($mutability)? SourceScope) {
-                self.super_source_scope(scope);
-            }
-
-            // The `super_xxx` methods comprise the default behavior and are
-            // not meant to be overridden.
-
-            fn super_body(
-                &mut self,
-                $($mutability)? body: body_cache_type!($($mutability)? '_, 'tcx)
-            ) {
-                let span = body.span;
-                if let Some(yield_ty) = &$($mutability)? body.yield_ty {
-                    self.visit_ty(yield_ty, TyContext::YieldTy(SourceInfo {
-                        span,
-                        scope: OUTERMOST_SOURCE_SCOPE,
-                    }));
-                }
-
-                // for best performance, we want to use an iterator rather
-                // than a for-loop, to avoid calling `body::Body::invalidate` for
-                // each basic block.
-                macro_rules! basic_blocks {
-                    (mut) => (body.basic_blocks_mut().iter_enumerated_mut());
-                    () => (body.basic_blocks().iter_enumerated());
-                };
-                for (bb, data) in basic_blocks!($($mutability)?) {
-                    self.visit_basic_block_data(bb, data);
-                }
-
-                let body: & $($mutability)? Body<'_> = & $($mutability)? body;
-                for scope in &$($mutability)? body.source_scopes {
-                    self.visit_source_scope_data(scope);
-                }
-
-                self.visit_ty(&$($mutability)? body.return_ty(), TyContext::ReturnTy(SourceInfo {
-                    span: body.span,
-                    scope: OUTERMOST_SOURCE_SCOPE,
-                }));
-
-                for local in body.local_decls.indices() {
-                    self.visit_local_decl(local, & $($mutability)? body.local_decls[local]);
-                }
-
-                macro_rules! type_annotations {
-                    (mut) => (body.user_type_annotations.iter_enumerated_mut());
-                    () => (body.user_type_annotations.iter_enumerated());
-                };
-
-                for (index, annotation) in type_annotations!($($mutability)?) {
-                    self.visit_user_type_annotation(
-                        index, annotation
-                    );
-                }
-
-                for var_debug_info in &$($mutability)? body.var_debug_info {
-                    self.visit_var_debug_info(var_debug_info);
-                }
-
-                self.visit_span(&$($mutability)? body.span);
-            }
-
-            fn super_basic_block_data(&mut self,
-                                      block: BasicBlock,
-                                      data: & $($mutability)? BasicBlockData<'tcx>) {
-                let BasicBlockData {
-                    statements,
-                    terminator,
-                    is_cleanup: _
-                } = data;
-
-                let mut index = 0;
-                for statement in statements {
-                    let location = Location { block: block, statement_index: index };
-                    self.visit_statement(statement, location);
-                    index += 1;
-                }
-
-                if let Some(terminator) = terminator {
-                    let location = Location { block: block, statement_index: index };
-                    self.visit_terminator(terminator, location);
-                }
-            }
-
-            fn super_source_scope_data(&mut self, scope_data: & $($mutability)? SourceScopeData) {
-                let SourceScopeData {
-                    span,
-                    parent_scope,
-                    local_data: _,
-                } = scope_data;
-
-                self.visit_span(span);
-                if let Some(parent_scope) = parent_scope {
-                    self.visit_source_scope(parent_scope);
-                }
-            }
-
-            fn super_statement(&mut self,
-                               statement: & $($mutability)? Statement<'tcx>,
-                               location: Location) {
-                let Statement {
-                    source_info,
-                    kind,
-                } = statement;
-
-                self.visit_source_info(source_info);
-                match kind {
-                    StatementKind::Assign(
-                        box(ref $($mutability)? place, ref $($mutability)? rvalue)
-                    ) => {
-                        self.visit_assign(place, rvalue, location);
-                    }
-                    StatementKind::FakeRead(_, place) => {
-                        self.visit_place(
-                            place,
-                            PlaceContext::NonMutatingUse(NonMutatingUseContext::Inspect),
-                            location
-                        );
-                    }
-                    StatementKind::SetDiscriminant { place, .. } => {
-                        self.visit_place(
-                            place,
-                            PlaceContext::MutatingUse(MutatingUseContext::Store),
-                            location
-                        );
-                    }
-                    StatementKind::StorageLive(local) => {
-                        self.visit_local(
-                            local,
-                            PlaceContext::NonUse(NonUseContext::StorageLive),
-                            location
-                        );
-                    }
-                    StatementKind::StorageDead(local) => {
-                        self.visit_local(
-                            local,
-                            PlaceContext::NonUse(NonUseContext::StorageDead),
-                            location
-                        );
-                    }
-                    StatementKind::InlineAsm(asm) => {
-                        for output in & $($mutability)? asm.outputs[..] {
-                            self.visit_place(
-                                output,
-                                PlaceContext::MutatingUse(MutatingUseContext::AsmOutput),
-                                location
-                            );
-                        }
-                        for (span, input) in & $($mutability)? asm.inputs[..] {
-                            self.visit_span(span);
-                            self.visit_operand(input, location);
-                        }
-                    }
-                    StatementKind::Retag(kind, place) => {
-                        self.visit_retag(kind, place, location);
-                    }
-                    StatementKind::AscribeUserType(
-                        box(ref $($mutability)? place, ref $($mutability)? user_ty),
-                        variance
-                    ) => {
-                        self.visit_ascribe_user_ty(place, variance, user_ty, location);
-                    }
-                    StatementKind::Nop => {}
-                }
-            }
-
-            fn super_assign(&mut self,
-                            place: &$($mutability)? Place<'tcx>,
-                            rvalue: &$($mutability)? Rvalue<'tcx>,
-                            location: Location) {
-                self.visit_place(
-                    place,
-                    PlaceContext::MutatingUse(MutatingUseContext::Store),
-                    location
-                );
-                self.visit_rvalue(rvalue, location);
-            }
-
-            fn super_terminator(&mut self,
-                                terminator: &$($mutability)? Terminator<'tcx>,
-                                location: Location) {
-                let Terminator { source_info, kind } = terminator;
-
-                self.visit_source_info(source_info);
-                self.visit_terminator_kind(kind, location);
-            }
-
-            fn super_terminator_kind(&mut self,
-                                     kind: & $($mutability)? TerminatorKind<'tcx>,
-                                     source_location: Location) {
-                match kind {
-                    TerminatorKind::Goto { .. } |
-                    TerminatorKind::Resume |
-                    TerminatorKind::Abort |
-                    TerminatorKind::Return |
-                    TerminatorKind::GeneratorDrop |
-                    TerminatorKind::Unreachable |
-                    TerminatorKind::FalseEdges { .. } |
-                    TerminatorKind::FalseUnwind { .. } => {
-                    }
-
-                    TerminatorKind::SwitchInt {
-                        discr,
-                        switch_ty,
-                        values: _,
-                        targets: _
-                    } => {
-                        self.visit_operand(discr, source_location);
-                        self.visit_ty(switch_ty, TyContext::Location(source_location));
-                    }
-
-                    TerminatorKind::Drop {
-                        location,
-                        target: _,
-                        unwind: _,
-                    } => {
-                        self.visit_place(
-                            location,
-                            PlaceContext::MutatingUse(MutatingUseContext::Drop),
-                            source_location
-                        );
-                    }
-
-                    TerminatorKind::DropAndReplace {
-                        location,
-                        value,
-                        target: _,
-                        unwind: _,
-                    } => {
-                        self.visit_place(
-                            location,
-                            PlaceContext::MutatingUse(MutatingUseContext::Drop),
-                            source_location
-                        );
-                        self.visit_operand(value, source_location);
-                    }
-
-                    TerminatorKind::Call {
-                        func,
-                        args,
-                        destination,
-                        cleanup: _,
-                        from_hir_call: _,
-                    } => {
-                        self.visit_operand(func, source_location);
-                        for arg in args {
-                            self.visit_operand(arg, source_location);
-                        }
-                        if let Some((destination, _)) = destination {
-                            self.visit_place(
-                                destination,
-                                PlaceContext::MutatingUse(MutatingUseContext::Call),
-                                source_location
-                            );
-                        }
-                    }
-
-                    TerminatorKind::Assert {
-                        cond,
-                        expected: _,
-                        msg,
-                        target: _,
-                        cleanup: _,
-                    } => {
-                        self.visit_operand(cond, source_location);
-                        self.visit_assert_message(msg, source_location);
-                    }
-
-                    TerminatorKind::Yield {
-                        value,
-                        resume: _,
-                        resume_arg,
-                        drop: _,
-                    } => {
-                        self.visit_operand(value, source_location);
-                        self.visit_place(
-                            resume_arg,
-                            PlaceContext::MutatingUse(MutatingUseContext::Store),
-                            source_location,
-                        );
-                    }
-
-                }
-            }
-
-            fn super_assert_message(&mut self,
-                                    msg: & $($mutability)? AssertMessage<'tcx>,
-                                    location: Location) {
-                use crate::mir::AssertKind::*;
-                match msg {
-                    BoundsCheck { len, index } => {
-                        self.visit_operand(len, location);
-                        self.visit_operand(index, location);
-                    }
-                    Overflow(_) | OverflowNeg | DivisionByZero | RemainderByZero |
-                    ResumedAfterReturn(_) | ResumedAfterPanic(_) => {
-                        // Nothing to visit
-                    }
-                }
-            }
-
-            fn super_rvalue(&mut self,
-                            rvalue: & $($mutability)? Rvalue<'tcx>,
-                            location: Location) {
-                match rvalue {
-                    Rvalue::Use(operand) => {
-                        self.visit_operand(operand, location);
-                    }
-
-                    Rvalue::Repeat(value, _) => {
-                        self.visit_operand(value, location);
-                    }
-
-                    Rvalue::Ref(r, bk, path) => {
-                        self.visit_region(r, location);
-                        let ctx = match bk {
-                            BorrowKind::Shared => PlaceContext::NonMutatingUse(
-                                NonMutatingUseContext::SharedBorrow
-                            ),
-                            BorrowKind::Shallow => PlaceContext::NonMutatingUse(
-                                NonMutatingUseContext::ShallowBorrow
-                            ),
-                            BorrowKind::Unique => PlaceContext::NonMutatingUse(
-                                NonMutatingUseContext::UniqueBorrow
-                            ),
-                            BorrowKind::Mut { .. } =>
-                                PlaceContext::MutatingUse(MutatingUseContext::Borrow),
-                        };
-                        self.visit_place(path, ctx, location);
-                    }
-
-                    Rvalue::AddressOf(m, path) => {
-                        let ctx = match m {
-                            Mutability::Mut => PlaceContext::MutatingUse(
-                                MutatingUseContext::AddressOf
-                            ),
-                            Mutability::Not => PlaceContext::NonMutatingUse(
-                                NonMutatingUseContext::AddressOf
-                            ),
-                        };
-                        self.visit_place(path, ctx, location);
-                    }
-
-                    Rvalue::Len(path) => {
-                        self.visit_place(
-                            path,
-                            PlaceContext::NonMutatingUse(NonMutatingUseContext::Inspect),
-                            location
-                        );
-                    }
-
-                    Rvalue::Cast(_cast_kind, operand, ty) => {
-                        self.visit_operand(operand, location);
-                        self.visit_ty(ty, TyContext::Location(location));
-                    }
-
-                    Rvalue::BinaryOp(_bin_op, lhs, rhs)
-                    | Rvalue::CheckedBinaryOp(_bin_op, lhs, rhs) => {
-                        self.visit_operand(lhs, location);
-                        self.visit_operand(rhs, location);
-                    }
-
-                    Rvalue::UnaryOp(_un_op, op) => {
-                        self.visit_operand(op, location);
-                    }
-
-                    Rvalue::Discriminant(place) => {
-                        self.visit_place(
-                            place,
-                            PlaceContext::NonMutatingUse(NonMutatingUseContext::Inspect),
-                            location
-                        );
-                    }
-
-                    Rvalue::NullaryOp(_op, ty) => {
-                        self.visit_ty(ty, TyContext::Location(location));
-                    }
-
-                    Rvalue::Aggregate(kind, operands) => {
-                        let kind = &$($mutability)? **kind;
-                        match kind {
-                            AggregateKind::Array(ty) => {
-                                self.visit_ty(ty, TyContext::Location(location));
-                            }
-                            AggregateKind::Tuple => {
-                            }
-                            AggregateKind::Adt(
-                                _adt_def,
-                                _variant_index,
-                                substs,
-                                _user_substs,
-                                _active_field_index
-                            ) => {
-                                self.visit_substs(substs, location);
-                            }
-                            AggregateKind::Closure(
-                                _,
-                                closure_substs
-                            ) => {
-                                self.visit_substs(closure_substs, location);
-                            }
-                            AggregateKind::Generator(
-                                _,
-                                generator_substs,
-                                _movability,
-                            ) => {
-                                self.visit_substs(generator_substs, location);
-                            }
-                        }
-
-                        for operand in operands {
-                            self.visit_operand(operand, location);
-                        }
-                    }
-                }
-            }
-
-            fn super_operand(&mut self,
-                             operand: & $($mutability)? Operand<'tcx>,
-                             location: Location) {
-                match operand {
-                    Operand::Copy(place) => {
-                        self.visit_place(
-                            place,
-                            PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy),
-                            location
-                        );
-                    }
-                    Operand::Move(place) => {
-                        self.visit_place(
-                            place,
-                            PlaceContext::NonMutatingUse(NonMutatingUseContext::Move),
-                            location
-                        );
-                    }
-                    Operand::Constant(constant) => {
-                        self.visit_constant(constant, location);
-                    }
-                }
-            }
-
-            fn super_ascribe_user_ty(&mut self,
-                                     place: & $($mutability)? Place<'tcx>,
-                                     _variance: & $($mutability)? ty::Variance,
-                                     user_ty: & $($mutability)? UserTypeProjection,
-                                     location: Location) {
-                self.visit_place(
-                    place,
-                    PlaceContext::NonUse(NonUseContext::AscribeUserTy),
-                    location
-                );
-                self.visit_user_type_projection(user_ty);
-            }
-
-            fn super_retag(&mut self,
-                           _kind: & $($mutability)? RetagKind,
-                           place: & $($mutability)? Place<'tcx>,
-                           location: Location) {
-                self.visit_place(
-                    place,
-                    PlaceContext::MutatingUse(MutatingUseContext::Retag),
-                    location,
-                );
-            }
-
-            fn super_place_base(&mut self,
-                                local: & $($mutability)? Local,
-                                context: PlaceContext,
-                                location: Location) {
-                self.visit_local(local, context, location);
-            }
-
-            fn super_local_decl(&mut self,
-                                local: Local,
-                                local_decl: & $($mutability)? LocalDecl<'tcx>) {
-                let LocalDecl {
-                    mutability: _,
-                    ty,
-                    user_ty,
-                    source_info,
-                    internal: _,
-                    local_info: _,
-                    is_block_tail: _,
-                } = local_decl;
-
-                self.visit_ty(ty, TyContext::LocalDecl {
-                    local,
-                    source_info: *source_info,
-                });
-                for (user_ty, _) in & $($mutability)? user_ty.contents {
-                    self.visit_user_type_projection(user_ty);
-                }
-                self.visit_source_info(source_info);
-            }
-
-            fn super_var_debug_info(&mut self,
-                                    var_debug_info: & $($mutability)? VarDebugInfo<'tcx>) {
-                let VarDebugInfo {
-                    name: _,
-                    source_info,
-                    place,
-                } = var_debug_info;
-
-                self.visit_source_info(source_info);
-                let location = START_BLOCK.start_location();
-                self.visit_place(
-                    place,
-                    PlaceContext::NonUse(NonUseContext::VarDebugInfo),
-                    location,
-                );
-            }
-
-            fn super_source_scope(&mut self,
-                                      _scope: & $($mutability)? SourceScope) {
-            }
-
-            fn super_constant(&mut self,
-                              constant: & $($mutability)? Constant<'tcx>,
-                              location: Location) {
-                let Constant {
-                    span,
-                    user_ty,
-                    literal,
-                } = constant;
-
-                self.visit_span(span);
-                drop(user_ty); // no visit method for this
-                self.visit_const(literal, location);
-            }
-
-            fn super_span(&mut self, _span: & $($mutability)? Span) {
-            }
-
-            fn super_source_info(&mut self, source_info: & $($mutability)? SourceInfo) {
-                let SourceInfo {
-                    span,
-                    scope,
-                } = source_info;
-
-                self.visit_span(span);
-                self.visit_source_scope(scope);
-            }
-
-            fn super_user_type_projection(
-                &mut self,
-                _ty: & $($mutability)? UserTypeProjection,
-            ) {
-            }
-
-            fn super_user_type_annotation(
-                &mut self,
-                _index: UserTypeAnnotationIndex,
-                ty: & $($mutability)? CanonicalUserTypeAnnotation<'tcx>,
-            ) {
-                self.visit_span(& $($mutability)? ty.span);
-                self.visit_ty(& $($mutability)? ty.inferred_ty, TyContext::UserTy(ty.span));
-            }
-
-            fn super_ty(&mut self, _ty: $(& $mutability)? Ty<'tcx>) {
-            }
-
-            fn super_region(&mut self, _region: & $($mutability)? ty::Region<'tcx>) {
-            }
-
-            fn super_const(&mut self, _const: & $($mutability)? &'tcx ty::Const<'tcx>) {
-            }
-
-            fn super_substs(&mut self, _substs: & $($mutability)? SubstsRef<'tcx>) {
-            }
-
-            // Convenience methods
-
-            fn visit_location(
-                &mut self,
-                body: body_cache_type!($($mutability)? '_, 'tcx),
-                location: Location
-            ) {
-                let basic_block = & $($mutability)? body[location.block];
-                if basic_block.statements.len() == location.statement_index {
-                    if let Some(ref $($mutability)? terminator) = basic_block.terminator {
-                        self.visit_terminator(terminator, location)
-                    }
-                } else {
-                    let statement = & $($mutability)?
-                        basic_block.statements[location.statement_index];
-                    self.visit_statement(statement, location)
-                }
-            }
-        }
-    }
-}
-
-macro_rules! visit_place_fns {
-    (mut) => (
-        fn tcx<'a>(&'a self) -> TyCtxt<'tcx>;
-
-        fn super_place(
-            &mut self,
-            place: &mut Place<'tcx>,
-            context: PlaceContext,
-            location: Location,
-        ) {
-            self.visit_place_base(&mut place.local, context, location);
-
-            if let Some(new_projection) = self.process_projection(&place.projection) {
-                place.projection = self.tcx().intern_place_elems(&new_projection);
-            }
-        }
-
-        fn process_projection(
-            &mut self,
-            projection: &'a [PlaceElem<'tcx>],
-        ) -> Option<Vec<PlaceElem<'tcx>>> {
-            let mut projection = Cow::Borrowed(projection);
-
-            for i in 0..projection.len() {
-                if let Some(elem) = projection.get(i) {
-                    if let Some(elem) = self.process_projection_elem(elem) {
-                        // This converts the borrowed projection into `Cow::Owned(_)` and returns a
-                        // clone of the projection so we can mutate and reintern later.
-                        let vec = projection.to_mut();
-                        vec[i] = elem;
-                    }
-                }
-            }
-
-            match projection {
-                Cow::Borrowed(_) => None,
-                Cow::Owned(vec) => Some(vec),
-            }
-        }
-
-        fn process_projection_elem(
-            &mut self,
-            _elem: &PlaceElem<'tcx>,
-        ) -> Option<PlaceElem<'tcx>> {
-            None
-        }
-    );
-
-    () => (
-        fn visit_projection(
-            &mut self,
-            local: &Local,
-            projection: &[PlaceElem<'tcx>],
-            context: PlaceContext,
-            location: Location,
-        ) {
-            self.super_projection(local, projection, context, location);
-        }
-
-        fn visit_projection_elem(
-            &mut self,
-            local: &Local,
-            proj_base: &[PlaceElem<'tcx>],
-            elem: &PlaceElem<'tcx>,
-            context: PlaceContext,
-            location: Location,
-        ) {
-            self.super_projection_elem(local, proj_base, elem, context, location);
-        }
-
-        fn super_place(
-            &mut self,
-            place: &Place<'tcx>,
-            context: PlaceContext,
-            location: Location,
-        ) {
-            let mut context = context;
-
-            if !place.projection.is_empty() {
-                context = if context.is_mutating_use() {
-                    PlaceContext::MutatingUse(MutatingUseContext::Projection)
-                } else {
-                    PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection)
-                };
-            }
-
-            self.visit_place_base(&place.local, context, location);
-
-            self.visit_projection(&place.local,
-                                  &place.projection,
-                                  context,
-                                  location);
-        }
-
-        fn super_projection(
-            &mut self,
-            local: &Local,
-            projection: &[PlaceElem<'tcx>],
-            context: PlaceContext,
-            location: Location,
-        ) {
-            let mut cursor = projection;
-            while let [proj_base @ .., elem] = cursor {
-                cursor = proj_base;
-                self.visit_projection_elem(local, cursor, elem, context, location);
-            }
-        }
-
-        fn super_projection_elem(
-            &mut self,
-            _local: &Local,
-            _proj_base: &[PlaceElem<'tcx>],
-            elem: &PlaceElem<'tcx>,
-            _context: PlaceContext,
-            location: Location,
-        ) {
-            match elem {
-                ProjectionElem::Field(_field, ty) => {
-                    self.visit_ty(ty, TyContext::Location(location));
-                }
-                ProjectionElem::Index(local) => {
-                    self.visit_local(
-                        local,
-                        PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy),
-                        location
-                    );
-                }
-                ProjectionElem::Deref |
-                ProjectionElem::Subslice { from: _, to: _, from_end: _ } |
-                ProjectionElem::ConstantIndex { offset: _,
-                                                min_length: _,
-                                                from_end: _ } |
-                ProjectionElem::Downcast(_, _) => {
-                }
-            }
-        }
-    );
-}
-
-make_mir_visitor!(Visitor,);
-make_mir_visitor!(MutVisitor, mut);
-
-pub trait MirVisitable<'tcx> {
-    fn apply(&self, location: Location, visitor: &mut dyn Visitor<'tcx>);
-}
-
-impl<'tcx> MirVisitable<'tcx> for Statement<'tcx> {
-    fn apply(&self, location: Location, visitor: &mut dyn Visitor<'tcx>) {
-        visitor.visit_statement(self, location)
-    }
-}
-
-impl<'tcx> MirVisitable<'tcx> for Terminator<'tcx> {
-    fn apply(&self, location: Location, visitor: &mut dyn Visitor<'tcx>) {
-        visitor.visit_terminator(self, location)
-    }
-}
-
-impl<'tcx> MirVisitable<'tcx> for Option<Terminator<'tcx>> {
-    fn apply(&self, location: Location, visitor: &mut dyn Visitor<'tcx>) {
-        visitor.visit_terminator(self.as_ref().unwrap(), location)
-    }
-}
-
-/// Extra information passed to `visit_ty` and friends to give context
-/// about where the type etc appears.
-#[derive(Debug)]
-pub enum TyContext {
-    LocalDecl {
-        /// The index of the local variable we are visiting.
-        local: Local,
-
-        /// The source location where this local variable was declared.
-        source_info: SourceInfo,
-    },
-
-    /// The inferred type of a user type annotation.
-    UserTy(Span),
-
-    /// The return type of the function.
-    ReturnTy(SourceInfo),
-
-    YieldTy(SourceInfo),
-
-    /// A type found at some location.
-    Location(Location),
-}
-
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
-pub enum NonMutatingUseContext {
-    /// Being inspected in some way, like loading a len.
-    Inspect,
-    /// Consumed as part of an operand.
-    Copy,
-    /// Consumed as part of an operand.
-    Move,
-    /// Shared borrow.
-    SharedBorrow,
-    /// Shallow borrow.
-    ShallowBorrow,
-    /// Unique borrow.
-    UniqueBorrow,
-    /// AddressOf for *const pointer.
-    AddressOf,
-    /// Used as base for another place, e.g., `x` in `x.y`. Will not mutate the place.
-    /// For example, the projection `x.y` is not marked as a mutation in these cases:
-    ///
-    ///     z = x.y;
-    ///     f(&x.y);
-    ///
-    Projection,
-}
-
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
-pub enum MutatingUseContext {
-    /// Appears as LHS of an assignment.
-    Store,
-    /// Can often be treated as a `Store`, but needs to be separate because
-    /// ASM is allowed to read outputs as well, so a `Store`-`AsmOutput` sequence
-    /// cannot be simplified the way a `Store`-`Store` can be.
-    AsmOutput,
-    /// Destination of a call.
-    Call,
-    /// Being dropped.
-    Drop,
-    /// Mutable borrow.
-    Borrow,
-    /// AddressOf for *mut pointer.
-    AddressOf,
-    /// Used as base for another place, e.g., `x` in `x.y`. Could potentially mutate the place.
-    /// For example, the projection `x.y` is marked as a mutation in these cases:
-    ///
-    ///     x.y = ...;
-    ///     f(&mut x.y);
-    ///
-    Projection,
-    /// Retagging, a "Stacked Borrows" shadow state operation
-    Retag,
-}
-
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
-pub enum NonUseContext {
-    /// Starting a storage live range.
-    StorageLive,
-    /// Ending a storage live range.
-    StorageDead,
-    /// User type annotation assertions for NLL.
-    AscribeUserTy,
-    /// The data of an user variable, for debug info.
-    VarDebugInfo,
-}
-
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
-pub enum PlaceContext {
-    NonMutatingUse(NonMutatingUseContext),
-    MutatingUse(MutatingUseContext),
-    NonUse(NonUseContext),
-}
-
-impl PlaceContext {
-    /// Returns `true` if this place context represents a drop.
-    pub fn is_drop(&self) -> bool {
-        match *self {
-            PlaceContext::MutatingUse(MutatingUseContext::Drop) => true,
-            _ => false,
-        }
-    }
-
-    /// Returns `true` if this place context represents a borrow.
-    pub fn is_borrow(&self) -> bool {
-        match *self {
-            PlaceContext::NonMutatingUse(NonMutatingUseContext::SharedBorrow)
-            | PlaceContext::NonMutatingUse(NonMutatingUseContext::ShallowBorrow)
-            | PlaceContext::NonMutatingUse(NonMutatingUseContext::UniqueBorrow)
-            | PlaceContext::MutatingUse(MutatingUseContext::Borrow) => true,
-            _ => false,
-        }
-    }
-
-    /// Returns `true` if this place context represents a storage live or storage dead marker.
-    pub fn is_storage_marker(&self) -> bool {
-        match *self {
-            PlaceContext::NonUse(NonUseContext::StorageLive)
-            | PlaceContext::NonUse(NonUseContext::StorageDead) => true,
-            _ => false,
-        }
-    }
-
-    /// Returns `true` if this place context represents a storage live marker.
-    pub fn is_storage_live_marker(&self) -> bool {
-        match *self {
-            PlaceContext::NonUse(NonUseContext::StorageLive) => true,
-            _ => false,
-        }
-    }
-
-    /// Returns `true` if this place context represents a storage dead marker.
-    pub fn is_storage_dead_marker(&self) -> bool {
-        match *self {
-            PlaceContext::NonUse(NonUseContext::StorageDead) => true,
-            _ => false,
-        }
-    }
-
-    /// Returns `true` if this place context represents a use that potentially changes the value.
-    pub fn is_mutating_use(&self) -> bool {
-        match *self {
-            PlaceContext::MutatingUse(..) => true,
-            _ => false,
-        }
-    }
-
-    /// Returns `true` if this place context represents a use that does not change the value.
-    pub fn is_nonmutating_use(&self) -> bool {
-        match *self {
-            PlaceContext::NonMutatingUse(..) => true,
-            _ => false,
-        }
-    }
-
-    /// Returns `true` if this place context represents a use.
-    pub fn is_use(&self) -> bool {
-        match *self {
-            PlaceContext::NonUse(..) => false,
-            _ => true,
-        }
-    }
-
-    /// Returns `true` if this place context represents an assignment statement.
-    pub fn is_place_assignment(&self) -> bool {
-        match *self {
-            PlaceContext::MutatingUse(MutatingUseContext::Store)
-            | PlaceContext::MutatingUse(MutatingUseContext::Call)
-            | PlaceContext::MutatingUse(MutatingUseContext::AsmOutput) => true,
-            _ => false,
-        }
-    }
-}
diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs
deleted file mode 100644
index 3a6961660fd..00000000000
--- a/src/librustc/query/mod.rs
+++ /dev/null
@@ -1,1261 +0,0 @@
-use crate::dep_graph::{DepKind, DepNode, RecoverKey, SerializedDepNodeIndex};
-use crate::mir;
-use crate::mir::interpret::{GlobalId, LitToConstInput};
-use crate::traits;
-use crate::traits::query::{
-    CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal,
-    CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpEqGoal, CanonicalTypeOpNormalizeGoal,
-    CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpSubtypeGoal,
-};
-use crate::ty::query::queries;
-use crate::ty::query::QueryDescription;
-use crate::ty::subst::SubstsRef;
-use crate::ty::{self, ParamEnvAnd, Ty, TyCtxt};
-use rustc_hir::def_id::{CrateNum, DefId, DefIndex};
-
-use rustc_span::symbol::Symbol;
-use std::borrow::Cow;
-
-fn describe_as_module(def_id: DefId, tcx: TyCtxt<'_>) -> String {
-    if def_id.is_top_level_module() {
-        format!("top-level module")
-    } else {
-        format!("module `{}`", tcx.def_path_str(def_id))
-    }
-}
-
-// Each of these queries corresponds to a function pointer field in the
-// `Providers` struct for requesting a value of that type, and a method
-// on `tcx: TyCtxt` (and `tcx.at(span)`) for doing that request in a way
-// which memoizes and does dep-graph tracking, wrapping around the actual
-// `Providers` that the driver creates (using several `rustc_*` crates).
-//
-// The result type of each query must implement `Clone`, and additionally
-// `ty::query::values::Value`, which produces an appropriate placeholder
-// (error) value if the query resulted in a query cycle.
-// Queries marked with `fatal_cycle` do not need the latter implementation,
-// as they will raise an fatal error on query cycles instead.
-rustc_queries! {
-    Other {
-        query trigger_delay_span_bug(key: DefId) -> () {
-            desc { "trigger a delay span bug" }
-        }
-    }
-
-    Other {
-        // Represents crate as a whole (as distinct from the top-level crate module).
-        // If you call `hir_crate` (e.g., indirectly by calling `tcx.hir().krate()`),
-        // we will have to assume that any change means that you need to be recompiled.
-        // This is because the `hir_crate` query gives you access to all other items.
-        // To avoid this fate, do not call `tcx.hir().krate()`; instead,
-        // prefer wrappers like `tcx.visit_all_items_in_krate()`.
-        query hir_crate(key: CrateNum) -> &'tcx Crate<'tcx> {
-            eval_always
-            no_hash
-            desc { "get the crate HIR" }
-        }
-
-        /// Records the type of every item.
-        query type_of(key: DefId) -> Ty<'tcx> {
-            cache_on_disk_if { key.is_local() }
-        }
-
-        /// Maps from the `DefId` of an item (trait/struct/enum/fn) to its
-        /// associated generics.
-        query generics_of(key: DefId) -> &'tcx ty::Generics {
-            cache_on_disk_if { key.is_local() }
-            load_cached(tcx, id) {
-                let generics: Option<ty::Generics> = tcx.queries.on_disk_cache
-                                                        .try_load_query_result(tcx, id);
-                generics.map(|x| &*tcx.arena.alloc(x))
-            }
-        }
-
-        /// Maps from the `DefId` of an item (trait/struct/enum/fn) to the
-        /// predicates (where-clauses) that must be proven true in order
-        /// to reference it. This is almost always the "predicates query"
-        /// that you want.
-        ///
-        /// `predicates_of` builds on `predicates_defined_on` -- in fact,
-        /// it is almost always the same as that query, except for the
-        /// case of traits. For traits, `predicates_of` contains
-        /// an additional `Self: Trait<...>` predicate that users don't
-        /// actually write. This reflects the fact that to invoke the
-        /// trait (e.g., via `Default::default`) you must supply types
-        /// that actually implement the trait. (However, this extra
-        /// predicate gets in the way of some checks, which are intended
-        /// to operate over only the actual where-clauses written by the
-        /// user.)
-        query predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> {
-            cache_on_disk_if { key.is_local() }
-        }
-
-        query native_libraries(_: CrateNum) -> Lrc<Vec<NativeLibrary>> {
-            desc { "looking up the native libraries of a linked crate" }
-        }
-
-        query lint_levels(_: CrateNum) -> &'tcx LintLevelMap {
-            eval_always
-            desc { "computing the lint levels for items in this crate" }
-        }
-    }
-
-    Codegen {
-        query is_panic_runtime(_: CrateNum) -> bool {
-            fatal_cycle
-            desc { "checking if the crate is_panic_runtime" }
-        }
-    }
-
-    Codegen {
-        /// Set of all the `DefId`s in this crate that have MIR associated with
-        /// them. This includes all the body owners, but also things like struct
-        /// constructors.
-        query mir_keys(_: CrateNum) -> &'tcx DefIdSet {
-            desc { "getting a list of all mir_keys" }
-        }
-
-        /// Maps DefId's that have an associated `mir::Body` to the result
-        /// of the MIR const-checking pass. This is the set of qualifs in
-        /// the final value of a `const`.
-        query mir_const_qualif(key: DefId) -> mir::ConstQualifs {
-            desc { |tcx| "const checking `{}`", tcx.def_path_str(key) }
-            cache_on_disk_if { key.is_local() }
-        }
-
-        /// Fetch the MIR for a given `DefId` right after it's built - this includes
-        /// unreachable code.
-        query mir_built(_: DefId) -> &'tcx Steal<mir::BodyAndCache<'tcx>> {
-            desc { "building MIR for" }
-        }
-
-        /// Fetch the MIR for a given `DefId` up till the point where it is
-        /// ready for const evaluation.
-        ///
-        /// See the README for the `mir` module for details.
-        query mir_const(_: DefId) -> &'tcx Steal<mir::BodyAndCache<'tcx>> {
-            no_hash
-        }
-
-        query mir_validated(_: DefId) ->
-            (
-                &'tcx Steal<mir::BodyAndCache<'tcx>>,
-                &'tcx Steal<IndexVec<mir::Promoted, mir::BodyAndCache<'tcx>>>
-            ) {
-            no_hash
-        }
-
-        /// MIR after our optimization passes have run. This is MIR that is ready
-        /// for codegen. This is also the only query that can fetch non-local MIR, at present.
-        query optimized_mir(key: DefId) -> &'tcx mir::BodyAndCache<'tcx> {
-            cache_on_disk_if { key.is_local() }
-            load_cached(tcx, id) {
-                let mir: Option<crate::mir::BodyAndCache<'tcx>>
-                    = tcx.queries.on_disk_cache.try_load_query_result(tcx, id);
-                mir.map(|x| {
-                    let cache = tcx.arena.alloc(x);
-                    cache.ensure_predecessors();
-                    &*cache
-                })
-            }
-        }
-
-        query promoted_mir(key: DefId) -> &'tcx IndexVec<mir::Promoted, mir::BodyAndCache<'tcx>> {
-            cache_on_disk_if { key.is_local() }
-            load_cached(tcx, id) {
-                let promoted: Option<
-                    rustc_index::vec::IndexVec<
-                        crate::mir::Promoted,
-                        crate::mir::BodyAndCache<'tcx>
-                    >> = tcx.queries.on_disk_cache.try_load_query_result(tcx, id);
-                promoted.map(|p| {
-                    let cache = tcx.arena.alloc(p);
-                    for body in cache.iter_mut() {
-                        body.ensure_predecessors();
-                    }
-                    &*cache
-                })
-            }
-        }
-    }
-
-    TypeChecking {
-        // Erases regions from `ty` to yield a new type.
-        // Normally you would just use `tcx.erase_regions(&value)`,
-        // however, which uses this query as a kind of cache.
-        query erase_regions_ty(ty: Ty<'tcx>) -> Ty<'tcx> {
-            // This query is not expected to have input -- as a result, it
-            // is not a good candidates for "replay" because it is essentially a
-            // pure function of its input (and hence the expectation is that
-            // no caller would be green **apart** from just these
-            // queries). Making it anonymous avoids hashing the result, which
-            // may save a bit of time.
-            anon
-            no_force
-            desc { "erasing regions from `{:?}`", ty }
-        }
-
-        query program_clauses_for(_: DefId) -> Clauses<'tcx> {
-            desc { "generating chalk-style clauses" }
-        }
-
-        query program_clauses_for_env(_: traits::Environment<'tcx>) -> Clauses<'tcx> {
-            no_force
-            desc { "generating chalk-style clauses for environment" }
-        }
-
-        // Get the chalk-style environment of the given item.
-        query environment(_: DefId) -> traits::Environment<'tcx> {
-            desc { "return a chalk-style environment" }
-        }
-    }
-
-    Linking {
-        query wasm_import_module_map(_: CrateNum) -> &'tcx FxHashMap<DefId, String> {
-            desc { "wasm import module map" }
-        }
-    }
-
-    Other {
-        /// Maps from the `DefId` of an item (trait/struct/enum/fn) to the
-        /// predicates (where-clauses) directly defined on it. This is
-        /// equal to the `explicit_predicates_of` predicates plus the
-        /// `inferred_outlives_of` predicates.
-        query predicates_defined_on(_: DefId) -> ty::GenericPredicates<'tcx> {}
-
-        /// Returns the predicates written explicitly by the user.
-        query explicit_predicates_of(_: DefId) -> ty::GenericPredicates<'tcx> {}
-
-        /// Returns the inferred outlives predicates (e.g., for `struct
-        /// Foo<'a, T> { x: &'a T }`, this would return `T: 'a`).
-        query inferred_outlives_of(_: DefId) -> &'tcx [(ty::Predicate<'tcx>, Span)] {}
-
-        /// Maps from the `DefId` of a trait to the list of
-        /// super-predicates. This is a subset of the full list of
-        /// predicates. We store these in a separate map because we must
-        /// evaluate them even during type conversion, often before the
-        /// full predicates are available (note that supertraits have
-        /// additional acyclicity requirements).
-        query super_predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> {
-            desc { |tcx| "computing the supertraits of `{}`", tcx.def_path_str(key) }
-        }
-
-        /// To avoid cycles within the predicates of a single item we compute
-        /// per-type-parameter predicates for resolving `T::AssocTy`.
-        query type_param_predicates(key: (DefId, DefId)) -> ty::GenericPredicates<'tcx> {
-            no_force
-            desc { |tcx| "computing the bounds for type parameter `{}`", {
-                let id = tcx.hir().as_local_hir_id(key.1).unwrap();
-                tcx.hir().ty_param_name(id)
-            }}
-        }
-
-        query trait_def(_: DefId) -> &'tcx ty::TraitDef {}
-        query adt_def(_: DefId) -> &'tcx ty::AdtDef {}
-        query adt_destructor(_: DefId) -> Option<ty::Destructor> {}
-
-        // The cycle error here should be reported as an error by `check_representable`.
-        // We consider the type as Sized in the meanwhile to avoid
-        // further errors (done in impl Value for AdtSizedConstraint).
-        // Use `cycle_delay_bug` to delay the cycle error here to be emitted later
-        // in case we accidentally otherwise don't emit an error.
-        query adt_sized_constraint(
-            _: DefId
-        ) -> AdtSizedConstraint<'tcx> {
-            cycle_delay_bug
-        }
-
-        query adt_dtorck_constraint(
-            _: DefId
-        ) -> Result<DtorckConstraint<'tcx>, NoSolution> {}
-
-        /// Returns `true` if this is a const fn, use the `is_const_fn` to know whether your crate
-        /// actually sees it as const fn (e.g., the const-fn-ness might be unstable and you might
-        /// not have the feature gate active).
-        ///
-        /// **Do not call this function manually.** It is only meant to cache the base data for the
-        /// `is_const_fn` function.
-        query is_const_fn_raw(key: DefId) -> bool {
-            desc { |tcx| "checking if item is const fn: `{}`", tcx.def_path_str(key) }
-        }
-
-        /// Returns `true` if this is a const `impl`. **Do not call this function manually.**
-        ///
-        /// This query caches the base data for the `is_const_impl` helper function, which also
-        /// takes into account stability attributes (e.g., `#[rustc_const_unstable]`).
-        query is_const_impl_raw(key: DefId) -> bool {
-            desc { |tcx| "checking if item is const impl: `{}`", tcx.def_path_str(key) }
-        }
-
-        query asyncness(key: DefId) -> hir::IsAsync {
-            desc { |tcx| "checking if the function is async: `{}`", tcx.def_path_str(key) }
-        }
-
-        /// Returns `true` if calls to the function may be promoted.
-        ///
-        /// This is either because the function is e.g., a tuple-struct or tuple-variant
-        /// constructor, or because it has the `#[rustc_promotable]` attribute. The attribute should
-        /// be removed in the future in favour of some form of check which figures out whether the
-        /// function does not inspect the bits of any of its arguments (so is essentially just a
-        /// constructor function).
-        query is_promotable_const_fn(_: DefId) -> bool {}
-
-        query const_fn_is_allowed_fn_ptr(_: DefId) -> bool {}
-
-        /// Returns `true` if this is a foreign item (i.e., linked via `extern { ... }`).
-        query is_foreign_item(_: DefId) -> bool {}
-
-        /// Returns `Some(mutability)` if the node pointed to by `def_id` is a static item.
-        query static_mutability(_: DefId) -> Option<hir::Mutability> {}
-
-        /// Returns `Some(generator_kind)` if the node pointed to by `def_id` is a generator.
-        query generator_kind(_: DefId) -> Option<hir::GeneratorKind> {}
-
-        /// Gets a map with the variance of every item; use `item_variance` instead.
-        query crate_variances(_: CrateNum) -> &'tcx ty::CrateVariancesMap<'tcx> {
-            desc { "computing the variances for items in this crate" }
-        }
-
-        /// Maps from the `DefId` of a type or region parameter to its (inferred) variance.
-        query variances_of(_: DefId) -> &'tcx [ty::Variance] {}
-    }
-
-    TypeChecking {
-        /// Maps from thee `DefId` of a type to its (inferred) outlives.
-        query inferred_outlives_crate(_: CrateNum)
-            -> &'tcx ty::CratePredicatesMap<'tcx> {
-            desc { "computing the inferred outlives predicates for items in this crate" }
-        }
-    }
-
-    Other {
-        /// Maps from an impl/trait `DefId to a list of the `DefId`s of its items.
-        query associated_item_def_ids(_: DefId) -> &'tcx [DefId] {}
-
-        /// Maps from a trait item to the trait item "descriptor".
-        query associated_item(_: DefId) -> ty::AssocItem {}
-
-        /// Collects the associated items defined on a trait or impl.
-        query associated_items(key: DefId) -> &'tcx ty::AssociatedItems {
-            desc { |tcx| "collecting associated items of {}", tcx.def_path_str(key) }
-        }
-
-        query impl_trait_ref(_: DefId) -> Option<ty::TraitRef<'tcx>> {}
-        query impl_polarity(_: DefId) -> ty::ImplPolarity {}
-
-        query issue33140_self_ty(_: DefId) -> Option<ty::Ty<'tcx>> {}
-    }
-
-    TypeChecking {
-        /// Maps a `DefId` of a type to a list of its inherent impls.
-        /// Contains implementations of methods that are inherent to a type.
-        /// Methods in these implementations don't need to be exported.
-        query inherent_impls(_: DefId) -> &'tcx [DefId] {
-            eval_always
-        }
-    }
-
-    TypeChecking {
-        /// The result of unsafety-checking this `DefId`.
-        query unsafety_check_result(key: DefId) -> mir::UnsafetyCheckResult {
-            desc { |tcx| "unsafety-checking `{}`", tcx.def_path_str(key) }
-            cache_on_disk_if { key.is_local() }
-        }
-
-        /// HACK: when evaluated, this reports a "unsafe derive on repr(packed)" error
-        query unsafe_derive_on_repr_packed(_: DefId) -> () {}
-
-        /// The signature of functions and closures.
-        query fn_sig(_: DefId) -> ty::PolyFnSig<'tcx> {}
-    }
-
-    Other {
-        query lint_mod(key: DefId) -> () {
-            desc { |tcx| "linting {}", describe_as_module(key, tcx) }
-        }
-
-        /// Checks the attributes in the module.
-        query check_mod_attrs(key: DefId) -> () {
-            desc { |tcx| "checking attributes in {}", describe_as_module(key, tcx) }
-        }
-
-        query check_mod_unstable_api_usage(key: DefId) -> () {
-            desc { |tcx| "checking for unstable API usage in {}", describe_as_module(key, tcx) }
-        }
-
-        /// Checks the const bodies in the module for illegal operations (e.g. `if` or `loop`).
-        query check_mod_const_bodies(key: DefId) -> () {
-            desc { |tcx| "checking consts in {}", describe_as_module(key, tcx) }
-        }
-
-        /// Checks the loops in the module.
-        query check_mod_loops(key: DefId) -> () {
-            desc { |tcx| "checking loops in {}", describe_as_module(key, tcx) }
-        }
-
-        query check_mod_item_types(key: DefId) -> () {
-            desc { |tcx| "checking item types in {}", describe_as_module(key, tcx) }
-        }
-
-        query check_mod_privacy(key: DefId) -> () {
-            desc { |tcx| "checking privacy in {}", describe_as_module(key, tcx) }
-        }
-
-        query check_mod_intrinsics(key: DefId) -> () {
-            desc { |tcx| "checking intrinsics in {}", describe_as_module(key, tcx) }
-        }
-
-        query check_mod_liveness(key: DefId) -> () {
-            desc { |tcx| "checking liveness of variables in {}", describe_as_module(key, tcx) }
-        }
-
-        query check_mod_impl_wf(key: DefId) -> () {
-            desc { |tcx| "checking that impls are well-formed in {}", describe_as_module(key, tcx) }
-        }
-
-        query collect_mod_item_types(key: DefId) -> () {
-            desc { |tcx| "collecting item types in {}", describe_as_module(key, tcx) }
-        }
-
-        /// Caches `CoerceUnsized` kinds for impls on custom types.
-        query coerce_unsized_info(_: DefId)
-            -> ty::adjustment::CoerceUnsizedInfo {}
-    }
-
-    TypeChecking {
-        query typeck_item_bodies(_: CrateNum) -> () {
-            desc { "type-checking all item bodies" }
-        }
-
-        query typeck_tables_of(key: DefId) -> &'tcx ty::TypeckTables<'tcx> {
-            desc { |tcx| "type-checking `{}`", tcx.def_path_str(key) }
-            cache_on_disk_if { key.is_local() }
-        }
-        query diagnostic_only_typeck_tables_of(key: DefId) -> &'tcx ty::TypeckTables<'tcx> {
-            cache_on_disk_if { key.is_local() }
-            load_cached(tcx, id) {
-                let typeck_tables: Option<ty::TypeckTables<'tcx>> = tcx
-                    .queries.on_disk_cache
-                    .try_load_query_result(tcx, id);
-
-                typeck_tables.map(|tables| &*tcx.arena.alloc(tables))
-            }
-        }
-    }
-
-    Other {
-        query used_trait_imports(key: DefId) -> &'tcx DefIdSet {
-            cache_on_disk_if { key.is_local() }
-        }
-    }
-
-    TypeChecking {
-        query has_typeck_tables(_: DefId) -> bool {}
-
-        query coherent_trait(def_id: DefId) -> () {
-            desc { |tcx| "coherence checking all impls of trait `{}`", tcx.def_path_str(def_id) }
-        }
-    }
-
-    BorrowChecking {
-        /// Borrow-checks the function body. If this is a closure, returns
-        /// additional requirements that the closure's creator must verify.
-        query mir_borrowck(key: DefId) -> &'tcx mir::BorrowCheckResult<'tcx> {
-            desc { |tcx| "borrow-checking `{}`", tcx.def_path_str(key) }
-            cache_on_disk_if(tcx, opt_result) {
-                key.is_local()
-                    && (tcx.is_closure(key)
-                        || opt_result.map_or(false, |r| !r.concrete_opaque_types.is_empty()))
-            }
-        }
-    }
-
-    TypeChecking {
-        /// Gets a complete map from all types to their inherent impls.
-        /// Not meant to be used directly outside of coherence.
-        /// (Defined only for `LOCAL_CRATE`.)
-        query crate_inherent_impls(k: CrateNum)
-            -> &'tcx CrateInherentImpls {
-            eval_always
-            desc { "all inherent impls defined in crate `{:?}`", k }
-        }
-
-        /// Checks all types in the crate for overlap in their inherent impls. Reports errors.
-        /// Not meant to be used directly outside of coherence.
-        /// (Defined only for `LOCAL_CRATE`.)
-        query crate_inherent_impls_overlap_check(_: CrateNum)
-            -> () {
-            eval_always
-            desc { "check for overlap between inherent impls defined in this crate" }
-        }
-    }
-
-    Other {
-        /// Evaluates a constant without running sanity checks.
-        ///
-        /// **Do not use this** outside const eval. Const eval uses this to break query cycles
-        /// during validation. Please add a comment to every use site explaining why using
-        /// `const_eval_validated` isn't sufficient. The returned constant also isn't in a suitable
-        /// form to be used outside of const eval.
-        query const_eval_raw(key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>)
-            -> ConstEvalRawResult<'tcx> {
-            no_force
-            desc { |tcx|
-                "const-evaluating `{}`",
-                tcx.def_path_str(key.value.instance.def.def_id())
-            }
-        }
-
-        /// Results of evaluating const items or constants embedded in
-        /// other items (such as enum variant explicit discriminants).
-        ///
-        /// In contrast to `const_eval_raw` this performs some validation on the constant, and
-        /// returns a proper constant that is usable by the rest of the compiler.
-        ///
-        /// **Do not use this** directly, use one of the following wrappers: `tcx.const_eval_poly`,
-        /// `tcx.const_eval_resolve`, `tcx.const_eval_instance`, or `tcx.const_eval_promoted`.
-        query const_eval_validated(key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>)
-            -> ConstEvalResult<'tcx> {
-            no_force
-            desc { |tcx|
-                "const-evaluating + checking `{}`",
-                tcx.def_path_str(key.value.instance.def.def_id())
-            }
-            cache_on_disk_if(_, opt_result) {
-                // Only store results without errors
-                opt_result.map_or(true, |r| r.is_ok())
-            }
-        }
-
-        /// Extracts a field of a (variant of a) const.
-        query const_field(
-            key: ty::ParamEnvAnd<'tcx, (&'tcx ty::Const<'tcx>, mir::Field)>
-        ) -> ConstValue<'tcx> {
-            no_force
-            desc { "extract field of const" }
-        }
-
-        /// Destructure a constant ADT or array into its variant indent and its
-        /// field values.
-        query destructure_const(
-            key: ty::ParamEnvAnd<'tcx, &'tcx ty::Const<'tcx>>
-        ) -> mir::DestructuredConst<'tcx> {
-            no_force
-            desc { "destructure constant" }
-        }
-
-        query const_caller_location(key: (rustc_span::Symbol, u32, u32)) -> ConstValue<'tcx> {
-            no_force
-            desc { "get a &core::panic::Location referring to a span" }
-        }
-
-        query lit_to_const(
-            key: LitToConstInput<'tcx>
-        ) -> Result<&'tcx ty::Const<'tcx>, LitToConstError> {
-            no_force
-            desc { "converting literal to const" }
-        }
-    }
-
-    TypeChecking {
-        query check_match(key: DefId) {
-            cache_on_disk_if { key.is_local() }
-        }
-
-        /// Performs part of the privacy check and computes "access levels".
-        query privacy_access_levels(_: CrateNum) -> &'tcx AccessLevels {
-            eval_always
-            desc { "privacy access levels" }
-        }
-        query check_private_in_public(_: CrateNum) -> () {
-            eval_always
-            desc { "checking for private elements in public interfaces" }
-        }
-    }
-
-    Other {
-        query reachable_set(_: CrateNum) -> Lrc<HirIdSet> {
-            desc { "reachability" }
-        }
-
-        /// Per-body `region::ScopeTree`. The `DefId` should be the owner `DefId` for the body;
-        /// in the case of closures, this will be redirected to the enclosing function.
-        query region_scope_tree(_: DefId) -> &'tcx region::ScopeTree {}
-
-        query mir_shims(key: ty::InstanceDef<'tcx>) -> &'tcx mir::BodyAndCache<'tcx> {
-            no_force
-            desc { |tcx| "generating MIR shim for `{}`", tcx.def_path_str(key.def_id()) }
-        }
-
-        /// The `symbol_name` query provides the symbol name for calling a
-        /// given instance from the local crate. In particular, it will also
-        /// look up the correct symbol name of instances from upstream crates.
-        query symbol_name(key: ty::Instance<'tcx>) -> ty::SymbolName {
-            no_force
-            desc { "computing the symbol for `{}`", key }
-            cache_on_disk_if { true }
-        }
-
-        query def_kind(_: DefId) -> Option<DefKind> {}
-        query def_span(_: DefId) -> Span {
-            // FIXME(mw): DefSpans are not really inputs since they are derived from
-            // HIR. But at the moment HIR hashing still contains some hacks that allow
-            // to make type debuginfo to be source location independent. Declaring
-            // DefSpan an input makes sure that changes to these are always detected
-            // regardless of HIR hashing.
-            eval_always
-        }
-        query lookup_stability(_: DefId) -> Option<&'tcx attr::Stability> {}
-        query lookup_const_stability(_: DefId) -> Option<&'tcx attr::ConstStability> {}
-        query lookup_deprecation_entry(_: DefId) -> Option<DeprecationEntry> {}
-        query item_attrs(_: DefId) -> Lrc<[ast::Attribute]> {}
-    }
-
-    Codegen {
-        query codegen_fn_attrs(_: DefId) -> CodegenFnAttrs {
-            cache_on_disk_if { true }
-        }
-    }
-
-    Other {
-        query fn_arg_names(_: DefId) -> Vec<ast::Name> {}
-        /// Gets the rendered value of the specified constant or associated constant.
-        /// Used by rustdoc.
-        query rendered_const(_: DefId) -> String {}
-        query impl_parent(_: DefId) -> Option<DefId> {}
-    }
-
-    TypeChecking {
-        query trait_of_item(_: DefId) -> Option<DefId> {}
-    }
-
-    Codegen {
-        query is_mir_available(key: DefId) -> bool {
-            desc { |tcx| "checking if item has mir available: `{}`", tcx.def_path_str(key) }
-        }
-    }
-
-    Other {
-        query vtable_methods(key: ty::PolyTraitRef<'tcx>)
-                            -> &'tcx [Option<(DefId, SubstsRef<'tcx>)>] {
-            no_force
-            desc { |tcx| "finding all methods for trait {}", tcx.def_path_str(key.def_id()) }
-        }
-    }
-
-    Codegen {
-        query codegen_fulfill_obligation(
-            key: (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>)
-        ) -> Vtable<'tcx, ()> {
-            no_force
-            cache_on_disk_if { true }
-            desc { |tcx|
-                "checking if `{}` fulfills its obligations",
-                tcx.def_path_str(key.1.def_id())
-            }
-        }
-    }
-
-    TypeChecking {
-        query trait_impls_of(key: DefId) -> &'tcx ty::trait_def::TraitImpls {
-            desc { |tcx| "trait impls of `{}`", tcx.def_path_str(key) }
-        }
-        query specialization_graph_of(key: DefId) -> &'tcx specialization_graph::Graph {
-            desc { |tcx| "building specialization graph of trait `{}`", tcx.def_path_str(key) }
-            cache_on_disk_if { true }
-        }
-        query object_safety_violations(key: DefId) -> Vec<traits::ObjectSafetyViolation> {
-            desc { |tcx| "determine object safety of trait `{}`", tcx.def_path_str(key) }
-        }
-
-        /// Gets the ParameterEnvironment for a given item; this environment
-        /// will be in "user-facing" mode, meaning that it is suitabe for
-        /// type-checking etc, and it does not normalize specializable
-        /// associated types. This is almost always what you want,
-        /// unless you are doing MIR optimizations, in which case you
-        /// might want to use `reveal_all()` method to change modes.
-        query param_env(_: DefId) -> ty::ParamEnv<'tcx> {}
-
-        /// Trait selection queries. These are best used by invoking `ty.is_copy_modulo_regions()`,
-        /// `ty.is_copy()`, etc, since that will prune the environment where possible.
-        query is_copy_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
-            no_force
-            desc { "computing whether `{}` is `Copy`", env.value }
-        }
-        /// Query backing `TyS::is_sized`.
-        query is_sized_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
-            no_force
-            desc { "computing whether `{}` is `Sized`", env.value }
-        }
-        /// Query backing `TyS::is_freeze`.
-        query is_freeze_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
-            no_force
-            desc { "computing whether `{}` is freeze", env.value }
-        }
-        /// Query backing `TyS::needs_drop`.
-        query needs_drop_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
-            no_force
-            desc { "computing whether `{}` needs drop", env.value }
-        }
-
-        /// A list of types where the ADT requires drop if and only if any of
-        /// those types require drop. If the ADT is known to always need drop
-        /// then `Err(AlwaysRequiresDrop)` is returned.
-        query adt_drop_tys(_: DefId) -> Result<&'tcx ty::List<Ty<'tcx>>, AlwaysRequiresDrop> {
-            cache_on_disk_if { true }
-        }
-
-        query layout_raw(
-            env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>
-        ) -> Result<&'tcx ty::layout::LayoutDetails, ty::layout::LayoutError<'tcx>> {
-            no_force
-            desc { "computing layout of `{}`", env.value }
-        }
-    }
-
-    Other {
-        query dylib_dependency_formats(_: CrateNum)
-                                        -> &'tcx [(CrateNum, LinkagePreference)] {
-            desc { "dylib dependency formats of crate" }
-        }
-
-        query dependency_formats(_: CrateNum)
-            -> Lrc<crate::middle::dependency_format::Dependencies>
-        {
-            desc { "get the linkage format of all dependencies" }
-        }
-    }
-
-    Codegen {
-        query is_compiler_builtins(_: CrateNum) -> bool {
-            fatal_cycle
-            desc { "checking if the crate is_compiler_builtins" }
-        }
-        query has_global_allocator(_: CrateNum) -> bool {
-            fatal_cycle
-            desc { "checking if the crate has_global_allocator" }
-        }
-        query has_panic_handler(_: CrateNum) -> bool {
-            fatal_cycle
-            desc { "checking if the crate has_panic_handler" }
-        }
-        query is_profiler_runtime(_: CrateNum) -> bool {
-            fatal_cycle
-            desc { "query a crate is `#![profiler_runtime]`" }
-        }
-        query panic_strategy(_: CrateNum) -> PanicStrategy {
-            fatal_cycle
-            desc { "query a crate's configured panic strategy" }
-        }
-        query is_no_builtins(_: CrateNum) -> bool {
-            fatal_cycle
-            desc { "test whether a crate has `#![no_builtins]`" }
-        }
-        query symbol_mangling_version(_: CrateNum) -> SymbolManglingVersion {
-            fatal_cycle
-            desc { "query a crate's symbol mangling version" }
-        }
-
-        query extern_crate(_: DefId) -> Option<&'tcx ExternCrate> {
-            eval_always
-            desc { "getting crate's ExternCrateData" }
-        }
-    }
-
-    TypeChecking {
-        query specializes(_: (DefId, DefId)) -> bool {
-            no_force
-            desc { "computing whether impls specialize one another" }
-        }
-        query in_scope_traits_map(_: DefIndex)
-            -> Option<&'tcx FxHashMap<ItemLocalId, StableVec<TraitCandidate>>> {
-            eval_always
-            desc { "traits in scope at a block" }
-        }
-    }
-
-    Other {
-        query module_exports(_: DefId) -> Option<&'tcx [Export<hir::HirId>]> {
-            eval_always
-        }
-    }
-
-    TypeChecking {
-        query impl_defaultness(_: DefId) -> hir::Defaultness {}
-
-        query check_item_well_formed(_: DefId) -> () {}
-        query check_trait_item_well_formed(_: DefId) -> () {}
-        query check_impl_item_well_formed(_: DefId) -> () {}
-    }
-
-    Linking {
-        // The `DefId`s of all non-generic functions and statics in the given crate
-        // that can be reached from outside the crate.
-        //
-        // We expect this items to be available for being linked to.
-        //
-        // This query can also be called for `LOCAL_CRATE`. In this case it will
-        // compute which items will be reachable to other crates, taking into account
-        // the kind of crate that is currently compiled. Crates with only a
-        // C interface have fewer reachable things.
-        //
-        // Does not include external symbols that don't have a corresponding DefId,
-        // like the compiler-generated `main` function and so on.
-        query reachable_non_generics(_: CrateNum)
-            -> &'tcx DefIdMap<SymbolExportLevel> {
-            desc { "looking up the exported symbols of a crate" }
-        }
-        query is_reachable_non_generic(_: DefId) -> bool {}
-        query is_unreachable_local_definition(_: DefId) -> bool {}
-    }
-
-    Codegen {
-        /// The entire set of monomorphizations the local crate can safely link
-        /// to because they are exported from upstream crates. Do not depend on
-        /// this directly, as its value changes anytime a monomorphization gets
-        /// added or removed in any upstream crate. Instead use the narrower
-        /// `upstream_monomorphizations_for`, `upstream_drop_glue_for`, or, even
-        /// better, `Instance::upstream_monomorphization()`.
-        query upstream_monomorphizations(
-            k: CrateNum
-        ) -> &'tcx DefIdMap<FxHashMap<SubstsRef<'tcx>, CrateNum>> {
-            desc { "collecting available upstream monomorphizations `{:?}`", k }
-        }
-
-        /// Returns the set of upstream monomorphizations available for the
-        /// generic function identified by the given `def_id`. The query makes
-        /// sure to make a stable selection if the same monomorphization is
-        /// available in multiple upstream crates.
-        ///
-        /// You likely want to call `Instance::upstream_monomorphization()`
-        /// instead of invoking this query directly.
-        query upstream_monomorphizations_for(_: DefId)
-            -> Option<&'tcx FxHashMap<SubstsRef<'tcx>, CrateNum>> {}
-
-        /// Returns the upstream crate that exports drop-glue for the given
-        /// type (`substs` is expected to be a single-item list containing the
-        /// type one wants drop-glue for).
-        ///
-        /// This is a subset of `upstream_monomorphizations_for` in order to
-        /// increase dep-tracking granularity. Otherwise adding or removing any
-        /// type with drop-glue in any upstream crate would invalidate all
-        /// functions calling drop-glue of an upstream type.
-        ///
-        /// You likely want to call `Instance::upstream_monomorphization()`
-        /// instead of invoking this query directly.
-        ///
-        /// NOTE: This query could easily be extended to also support other
-        ///       common functions that have are large set of monomorphizations
-        ///       (like `Clone::clone` for example).
-        query upstream_drop_glue_for(substs: SubstsRef<'tcx>) -> Option<CrateNum> {
-            desc { "available upstream drop-glue for `{:?}`", substs }
-            no_force
-        }
-    }
-
-    Other {
-        query foreign_modules(_: CrateNum) -> &'tcx [ForeignModule] {
-            desc { "looking up the foreign modules of a linked crate" }
-        }
-
-        /// Identifies the entry-point (e.g., the `main` function) for a given
-        /// crate, returning `None` if there is no entry point (such as for library crates).
-        query entry_fn(_: CrateNum) -> Option<(DefId, EntryFnType)> {
-            desc { "looking up the entry function of a crate" }
-        }
-        query plugin_registrar_fn(_: CrateNum) -> Option<DefId> {
-            desc { "looking up the plugin registrar for a crate" }
-        }
-        query proc_macro_decls_static(_: CrateNum) -> Option<DefId> {
-            desc { "looking up the derive registrar for a crate" }
-        }
-        query crate_disambiguator(_: CrateNum) -> CrateDisambiguator {
-            eval_always
-            desc { "looking up the disambiguator a crate" }
-        }
-        query crate_hash(_: CrateNum) -> Svh {
-            eval_always
-            desc { "looking up the hash a crate" }
-        }
-        query crate_host_hash(_: CrateNum) -> Option<Svh> {
-            eval_always
-            desc { "looking up the hash of a host version of a crate" }
-        }
-        query original_crate_name(_: CrateNum) -> Symbol {
-            eval_always
-            desc { "looking up the original name a crate" }
-        }
-        query extra_filename(_: CrateNum) -> String {
-            eval_always
-            desc { "looking up the extra filename for a crate" }
-        }
-    }
-
-    TypeChecking {
-        query implementations_of_trait(_: (CrateNum, DefId))
-            -> &'tcx [DefId] {
-            no_force
-            desc { "looking up implementations of a trait in a crate" }
-        }
-        query all_trait_implementations(_: CrateNum)
-            -> &'tcx [DefId] {
-            desc { "looking up all (?) trait implementations" }
-        }
-    }
-
-    Other {
-        query dllimport_foreign_items(_: CrateNum)
-            -> &'tcx FxHashSet<DefId> {
-            desc { "dllimport_foreign_items" }
-        }
-        query is_dllimport_foreign_item(_: DefId) -> bool {}
-        query is_statically_included_foreign_item(_: DefId) -> bool {}
-        query native_library_kind(_: DefId)
-            -> Option<NativeLibraryKind> {}
-    }
-
-    Linking {
-        query link_args(_: CrateNum) -> Lrc<Vec<String>> {
-            eval_always
-            desc { "looking up link arguments for a crate" }
-        }
-    }
-
-    BorrowChecking {
-        /// Lifetime resolution. See `middle::resolve_lifetimes`.
-        query resolve_lifetimes(_: CrateNum) -> &'tcx ResolveLifetimes {
-            desc { "resolving lifetimes" }
-        }
-        query named_region_map(_: DefIndex) ->
-            Option<&'tcx FxHashMap<ItemLocalId, Region>> {
-            desc { "looking up a named region" }
-        }
-        query is_late_bound_map(_: DefIndex) ->
-            Option<&'tcx FxHashSet<ItemLocalId>> {
-            desc { "testing if a region is late bound" }
-        }
-        query object_lifetime_defaults_map(_: DefIndex)
-            -> Option<&'tcx FxHashMap<ItemLocalId, Vec<ObjectLifetimeDefault>>> {
-            desc { "looking up lifetime defaults for a region" }
-        }
-    }
-
-    TypeChecking {
-        query visibility(_: DefId) -> ty::Visibility {}
-    }
-
-    Other {
-        query dep_kind(_: CrateNum) -> DepKind {
-            eval_always
-            desc { "fetching what a dependency looks like" }
-        }
-        query crate_name(_: CrateNum) -> Symbol {
-            eval_always
-            desc { "fetching what a crate is named" }
-        }
-        query item_children(_: DefId) -> &'tcx [Export<hir::HirId>] {}
-        query extern_mod_stmt_cnum(_: DefId) -> Option<CrateNum> {}
-
-        query get_lib_features(_: CrateNum) -> &'tcx LibFeatures {
-            eval_always
-            desc { "calculating the lib features map" }
-        }
-        query defined_lib_features(_: CrateNum)
-            -> &'tcx [(Symbol, Option<Symbol>)] {
-            desc { "calculating the lib features defined in a crate" }
-        }
-        /// Returns the lang items defined in another crate by loading it from metadata.
-        // FIXME: It is illegal to pass a `CrateNum` other than `LOCAL_CRATE` here, just get rid
-        // of that argument?
-        query get_lang_items(_: CrateNum) -> &'tcx LanguageItems {
-            eval_always
-            desc { "calculating the lang items map" }
-        }
-
-        /// Returns all diagnostic items defined in all crates.
-        query all_diagnostic_items(_: CrateNum) -> &'tcx FxHashMap<Symbol, DefId> {
-            eval_always
-            desc { "calculating the diagnostic items map" }
-        }
-
-        /// Returns the lang items defined in another crate by loading it from metadata.
-        query defined_lang_items(_: CrateNum) -> &'tcx [(DefId, usize)] {
-            desc { "calculating the lang items defined in a crate" }
-        }
-
-        /// Returns the diagnostic items defined in a crate.
-        query diagnostic_items(_: CrateNum) -> &'tcx FxHashMap<Symbol, DefId> {
-            desc { "calculating the diagnostic items map in a crate" }
-        }
-
-        query missing_lang_items(_: CrateNum) -> &'tcx [LangItem] {
-            desc { "calculating the missing lang items in a crate" }
-        }
-        query visible_parent_map(_: CrateNum)
-            -> &'tcx DefIdMap<DefId> {
-            desc { "calculating the visible parent map" }
-        }
-        query missing_extern_crate_item(_: CrateNum) -> bool {
-            eval_always
-            desc { "seeing if we're missing an `extern crate` item for this crate" }
-        }
-        query used_crate_source(_: CrateNum) -> Lrc<CrateSource> {
-            eval_always
-            desc { "looking at the source for a crate" }
-        }
-        query postorder_cnums(_: CrateNum) -> &'tcx [CrateNum] {
-            eval_always
-            desc { "generating a postorder list of CrateNums" }
-        }
-
-        query upvars(_: DefId) -> Option<&'tcx FxIndexMap<hir::HirId, hir::Upvar>> {
-            eval_always
-        }
-        query maybe_unused_trait_import(_: DefId) -> bool {
-            eval_always
-        }
-        query maybe_unused_extern_crates(_: CrateNum)
-            -> &'tcx [(DefId, Span)] {
-            eval_always
-            desc { "looking up all possibly unused extern crates" }
-        }
-        query names_imported_by_glob_use(_: DefId)
-            -> Lrc<FxHashSet<ast::Name>> {
-            eval_always
-        }
-
-        query stability_index(_: CrateNum) -> &'tcx stability::Index<'tcx> {
-            eval_always
-            desc { "calculating the stability index for the local crate" }
-        }
-        query all_crate_nums(_: CrateNum) -> &'tcx [CrateNum] {
-            eval_always
-            desc { "fetching all foreign CrateNum instances" }
-        }
-
-        /// A vector of every trait accessible in the whole crate
-        /// (i.e., including those from subcrates). This is used only for
-        /// error reporting.
-        query all_traits(_: CrateNum) -> &'tcx [DefId] {
-            desc { "fetching all foreign and local traits" }
-        }
-    }
-
-    Linking {
-        /// The list of symbols exported from the given crate.
-        ///
-        /// - All names contained in `exported_symbols(cnum)` are guaranteed to
-        ///   correspond to a publicly visible symbol in `cnum` machine code.
-        /// - The `exported_symbols` sets of different crates do not intersect.
-        query exported_symbols(_: CrateNum)
-            -> Arc<Vec<(ExportedSymbol<'tcx>, SymbolExportLevel)>> {
-            desc { "exported_symbols" }
-        }
-    }
-
-    Codegen {
-        query collect_and_partition_mono_items(_: CrateNum)
-            -> (Arc<DefIdSet>, Arc<Vec<Arc<CodegenUnit<'tcx>>>>) {
-            eval_always
-            desc { "collect_and_partition_mono_items" }
-        }
-        query is_codegened_item(_: DefId) -> bool {}
-        query codegen_unit(_: Symbol) -> Arc<CodegenUnit<'tcx>> {
-            no_force
-            desc { "codegen_unit" }
-        }
-        query backend_optimization_level(_: CrateNum) -> OptLevel {
-            desc { "optimization level used by backend" }
-        }
-    }
-
-    Other {
-        query output_filenames(_: CrateNum) -> Arc<OutputFilenames> {
-            eval_always
-            desc { "output_filenames" }
-        }
-    }
-
-    TypeChecking {
-        /// Do not call this query directly: invoke `normalize` instead.
-        query normalize_projection_ty(
-            goal: CanonicalProjectionGoal<'tcx>
-        ) -> Result<
-            &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, NormalizationResult<'tcx>>>,
-            NoSolution,
-        > {
-            no_force
-            desc { "normalizing `{:?}`", goal }
-        }
-
-        /// Do not call this query directly: invoke `normalize_erasing_regions` instead.
-        query normalize_ty_after_erasing_regions(
-            goal: ParamEnvAnd<'tcx, Ty<'tcx>>
-        ) -> Ty<'tcx> {
-            no_force
-            desc { "normalizing `{:?}`", goal }
-        }
-
-        query implied_outlives_bounds(
-            goal: CanonicalTyGoal<'tcx>
-        ) -> Result<
-            &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, Vec<OutlivesBound<'tcx>>>>,
-            NoSolution,
-        > {
-            no_force
-            desc { "computing implied outlives bounds for `{:?}`", goal }
-        }
-
-        /// Do not call this query directly: invoke `infcx.at().dropck_outlives()` instead.
-        query dropck_outlives(
-            goal: CanonicalTyGoal<'tcx>
-        ) -> Result<
-            &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, DropckOutlivesResult<'tcx>>>,
-            NoSolution,
-        > {
-            no_force
-            desc { "computing dropck types for `{:?}`", goal }
-        }
-
-        /// Do not call this query directly: invoke `infcx.predicate_may_hold()` or
-        /// `infcx.predicate_must_hold()` instead.
-        query evaluate_obligation(
-            goal: CanonicalPredicateGoal<'tcx>
-        ) -> Result<traits::EvaluationResult, traits::OverflowError> {
-            no_force
-            desc { "evaluating trait selection obligation `{}`", goal.value.value }
-        }
-
-        query evaluate_goal(
-            goal: traits::ChalkCanonicalGoal<'tcx>
-        ) -> Result<
-            &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>,
-            NoSolution
-        > {
-            no_force
-            desc { "evaluating trait selection obligation `{}`", goal.value.goal }
-        }
-
-        /// Do not call this query directly: part of the `Eq` type-op
-        query type_op_ascribe_user_type(
-            goal: CanonicalTypeOpAscribeUserTypeGoal<'tcx>
-        ) -> Result<
-            &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>,
-            NoSolution,
-        > {
-            no_force
-            desc { "evaluating `type_op_ascribe_user_type` `{:?}`", goal }
-        }
-
-        /// Do not call this query directly: part of the `Eq` type-op
-        query type_op_eq(
-            goal: CanonicalTypeOpEqGoal<'tcx>
-        ) -> Result<
-            &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>,
-            NoSolution,
-        > {
-            no_force
-            desc { "evaluating `type_op_eq` `{:?}`", goal }
-        }
-
-        /// Do not call this query directly: part of the `Subtype` type-op
-        query type_op_subtype(
-            goal: CanonicalTypeOpSubtypeGoal<'tcx>
-        ) -> Result<
-            &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>,
-            NoSolution,
-        > {
-            no_force
-            desc { "evaluating `type_op_subtype` `{:?}`", goal }
-        }
-
-        /// Do not call this query directly: part of the `ProvePredicate` type-op
-        query type_op_prove_predicate(
-            goal: CanonicalTypeOpProvePredicateGoal<'tcx>
-        ) -> Result<
-            &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>,
-            NoSolution,
-        > {
-            no_force
-            desc { "evaluating `type_op_prove_predicate` `{:?}`", goal }
-        }
-
-        /// Do not call this query directly: part of the `Normalize` type-op
-        query type_op_normalize_ty(
-            goal: CanonicalTypeOpNormalizeGoal<'tcx, Ty<'tcx>>
-        ) -> Result<
-            &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, Ty<'tcx>>>,
-            NoSolution,
-        > {
-            no_force
-            desc { "normalizing `{:?}`", goal }
-        }
-
-        /// Do not call this query directly: part of the `Normalize` type-op
-        query type_op_normalize_predicate(
-            goal: CanonicalTypeOpNormalizeGoal<'tcx, ty::Predicate<'tcx>>
-        ) -> Result<
-            &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ty::Predicate<'tcx>>>,
-            NoSolution,
-        > {
-            no_force
-            desc { "normalizing `{:?}`", goal }
-        }
-
-        /// Do not call this query directly: part of the `Normalize` type-op
-        query type_op_normalize_poly_fn_sig(
-            goal: CanonicalTypeOpNormalizeGoal<'tcx, ty::PolyFnSig<'tcx>>
-        ) -> Result<
-            &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ty::PolyFnSig<'tcx>>>,
-            NoSolution,
-        > {
-            no_force
-            desc { "normalizing `{:?}`", goal }
-        }
-
-        /// Do not call this query directly: part of the `Normalize` type-op
-        query type_op_normalize_fn_sig(
-            goal: CanonicalTypeOpNormalizeGoal<'tcx, ty::FnSig<'tcx>>
-        ) -> Result<
-            &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ty::FnSig<'tcx>>>,
-            NoSolution,
-        > {
-            no_force
-            desc { "normalizing `{:?}`", goal }
-        }
-
-        query substitute_normalize_and_test_predicates(key: (DefId, SubstsRef<'tcx>)) -> bool {
-            no_force
-            desc { |tcx|
-                "testing substituted normalized predicates:`{}`",
-                tcx.def_path_str(key.0)
-            }
-        }
-
-        query method_autoderef_steps(
-            goal: CanonicalTyGoal<'tcx>
-        ) -> MethodAutoderefStepsResult<'tcx> {
-            no_force
-            desc { "computing autoderef types for `{:?}`", goal }
-        }
-    }
-
-    Other {
-        query target_features_whitelist(_: CrateNum) -> &'tcx FxHashMap<String, Option<Symbol>> {
-            eval_always
-            desc { "looking up the whitelist of target features" }
-        }
-
-        // Get an estimate of the size of an InstanceDef based on its MIR for CGU partitioning.
-        query instance_def_size_estimate(def: ty::InstanceDef<'tcx>)
-            -> usize {
-            no_force
-            desc { |tcx| "estimating size for `{}`", tcx.def_path_str(def.def_id()) }
-        }
-
-        query features_query(_: CrateNum) -> &'tcx rustc_feature::Features {
-            eval_always
-            desc { "looking up enabled feature gates" }
-        }
-    }
-}
diff --git a/src/librustc/tests.rs b/src/librustc/tests.rs
deleted file mode 100644
index cf3ea2ffa93..00000000000
--- a/src/librustc/tests.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-use super::*;
-
-// FIXME(#27438): right now the unit tests of librustc don't refer to any actual
-//                functions generated in librustc_data_structures (all
-//                references are through generic functions), but statics are
-//                referenced from time to time. Due to this bug we won't
-//                actually correctly link in the statics unless we also
-//                reference a function, so be sure to reference a dummy
-//                function.
-#[test]
-fn noop() {
-    rustc_data_structures::__noop_fix_for_27438();
-}
diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs
deleted file mode 100644
index de2ec53e51e..00000000000
--- a/src/librustc/traits/mod.rs
+++ /dev/null
@@ -1,871 +0,0 @@
-//! Trait Resolution. See the [rustc guide] for more information on how this works.
-//!
-//! [rustc guide]: https://rust-lang.github.io/rustc-guide/traits/resolution.html
-
-pub mod query;
-pub mod select;
-pub mod specialization_graph;
-mod structural_impls;
-
-use crate::infer::canonical::Canonical;
-use crate::mir::interpret::ErrorHandled;
-use crate::ty::fold::{TypeFolder, TypeVisitor};
-use crate::ty::subst::SubstsRef;
-use crate::ty::{self, AdtKind, List, Ty, TyCtxt};
-
-use rustc_hir as hir;
-use rustc_hir::def_id::DefId;
-use rustc_span::{Span, DUMMY_SP};
-use smallvec::SmallVec;
-use syntax::ast;
-
-use std::borrow::Cow;
-use std::fmt::Debug;
-use std::rc::Rc;
-
-pub use self::select::{EvaluationCache, EvaluationResult, OverflowError, SelectionCache};
-
-pub type ChalkCanonicalGoal<'tcx> = Canonical<'tcx, InEnvironment<'tcx, ty::Predicate<'tcx>>>;
-
-pub use self::ObligationCauseCode::*;
-pub use self::SelectionError::*;
-pub use self::Vtable::*;
-
-/// Depending on the stage of compilation, we want projection to be
-/// more or less conservative.
-#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, HashStable)]
-pub enum Reveal {
-    /// At type-checking time, we refuse to project any associated
-    /// type that is marked `default`. Non-`default` ("final") types
-    /// are always projected. This is necessary in general for
-    /// soundness of specialization. However, we *could* allow
-    /// projections in fully-monomorphic cases. We choose not to,
-    /// because we prefer for `default type` to force the type
-    /// definition to be treated abstractly by any consumers of the
-    /// impl. Concretely, that means that the following example will
-    /// fail to compile:
-    ///
-    /// ```
-    /// trait Assoc {
-    ///     type Output;
-    /// }
-    ///
-    /// impl<T> Assoc for T {
-    ///     default type Output = bool;
-    /// }
-    ///
-    /// fn main() {
-    ///     let <() as Assoc>::Output = true;
-    /// }
-    /// ```
-    UserFacing,
-
-    /// At codegen time, all monomorphic projections will succeed.
-    /// Also, `impl Trait` is normalized to the concrete type,
-    /// which has to be already collected by type-checking.
-    ///
-    /// NOTE: as `impl Trait`'s concrete type should *never*
-    /// be observable directly by the user, `Reveal::All`
-    /// should not be used by checks which may expose
-    /// type equality or type contents to the user.
-    /// There are some exceptions, e.g., around OIBITS and
-    /// transmute-checking, which expose some details, but
-    /// not the whole concrete type of the `impl Trait`.
-    All,
-}
-
-/// The reason why we incurred this obligation; used for error reporting.
-#[derive(Clone, Debug, PartialEq, Eq, Hash)]
-pub struct ObligationCause<'tcx> {
-    pub span: Span,
-
-    /// The ID of the fn body that triggered this obligation. This is
-    /// used for region obligations to determine the precise
-    /// environment in which the region obligation should be evaluated
-    /// (in particular, closures can add new assumptions). See the
-    /// field `region_obligations` of the `FulfillmentContext` for more
-    /// information.
-    pub body_id: hir::HirId,
-
-    pub code: ObligationCauseCode<'tcx>,
-}
-
-impl<'tcx> ObligationCause<'tcx> {
-    #[inline]
-    pub fn new(
-        span: Span,
-        body_id: hir::HirId,
-        code: ObligationCauseCode<'tcx>,
-    ) -> ObligationCause<'tcx> {
-        ObligationCause { span, body_id, code }
-    }
-
-    pub fn misc(span: Span, body_id: hir::HirId) -> ObligationCause<'tcx> {
-        ObligationCause { span, body_id, code: MiscObligation }
-    }
-
-    pub fn dummy() -> ObligationCause<'tcx> {
-        ObligationCause { span: DUMMY_SP, body_id: hir::CRATE_HIR_ID, code: MiscObligation }
-    }
-
-    pub fn span(&self, tcx: TyCtxt<'tcx>) -> Span {
-        match self.code {
-            ObligationCauseCode::CompareImplMethodObligation { .. }
-            | ObligationCauseCode::MainFunctionType
-            | ObligationCauseCode::StartFunctionType => tcx.sess.source_map().def_span(self.span),
-            ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause {
-                arm_span,
-                ..
-            }) => arm_span,
-            _ => self.span,
-        }
-    }
-}
-
-#[derive(Clone, Debug, PartialEq, Eq, Hash)]
-pub enum ObligationCauseCode<'tcx> {
-    /// Not well classified or should be obvious from the span.
-    MiscObligation,
-
-    /// A slice or array is WF only if `T: Sized`.
-    SliceOrArrayElem,
-
-    /// A tuple is WF only if its middle elements are `Sized`.
-    TupleElem,
-
-    /// This is the trait reference from the given projection.
-    ProjectionWf(ty::ProjectionTy<'tcx>),
-
-    /// In an impl of trait `X` for type `Y`, type `Y` must
-    /// also implement all supertraits of `X`.
-    ItemObligation(DefId),
-
-    /// Like `ItemObligation`, but with extra detail on the source of the obligation.
-    BindingObligation(DefId, Span),
-
-    /// A type like `&'a T` is WF only if `T: 'a`.
-    ReferenceOutlivesReferent(Ty<'tcx>),
-
-    /// A type like `Box<Foo<'a> + 'b>` is WF only if `'b: 'a`.
-    ObjectTypeBound(Ty<'tcx>, ty::Region<'tcx>),
-
-    /// Obligation incurred due to an object cast.
-    ObjectCastObligation(/* Object type */ Ty<'tcx>),
-
-    /// Obligation incurred due to a coercion.
-    Coercion {
-        source: Ty<'tcx>,
-        target: Ty<'tcx>,
-    },
-
-    /// Various cases where expressions must be `Sized` / `Copy` / etc.
-    /// `L = X` implies that `L` is `Sized`.
-    AssignmentLhsSized,
-    /// `(x1, .., xn)` must be `Sized`.
-    TupleInitializerSized,
-    /// `S { ... }` must be `Sized`.
-    StructInitializerSized,
-    /// Type of each variable must be `Sized`.
-    VariableType(hir::HirId),
-    /// Argument type must be `Sized`.
-    SizedArgumentType,
-    /// Return type must be `Sized`.
-    SizedReturnType,
-    /// Yield type must be `Sized`.
-    SizedYieldType,
-    /// `[T, ..n]` implies that `T` must be `Copy`.
-    /// If `true`, suggest `const_in_array_repeat_expressions` feature flag.
-    RepeatVec(bool),
-
-    /// Types of fields (other than the last, except for packed structs) in a struct must be sized.
-    FieldSized {
-        adt_kind: AdtKind,
-        last: bool,
-    },
-
-    /// Constant expressions must be sized.
-    ConstSized,
-
-    /// `static` items must have `Sync` type.
-    SharedStatic,
-
-    BuiltinDerivedObligation(DerivedObligationCause<'tcx>),
-
-    ImplDerivedObligation(DerivedObligationCause<'tcx>),
-
-    /// Error derived when matching traits/impls; see ObligationCause for more details
-    CompareImplMethodObligation {
-        item_name: ast::Name,
-        impl_item_def_id: DefId,
-        trait_item_def_id: DefId,
-    },
-
-    /// Error derived when matching traits/impls; see ObligationCause for more details
-    CompareImplTypeObligation {
-        item_name: ast::Name,
-        impl_item_def_id: DefId,
-        trait_item_def_id: DefId,
-    },
-
-    /// Checking that this expression can be assigned where it needs to be
-    // FIXME(eddyb) #11161 is the original Expr required?
-    ExprAssignable,
-
-    /// Computing common supertype in the arms of a match expression
-    MatchExpressionArm(Box<MatchExpressionArmCause<'tcx>>),
-
-    /// Type error arising from type checking a pattern against an expected type.
-    Pattern {
-        /// The span of the scrutinee or type expression which caused the `root_ty` type.
-        span: Option<Span>,
-        /// The root expected type induced by a scrutinee or type expression.
-        root_ty: Ty<'tcx>,
-        /// Whether the `Span` came from an expression or a type expression.
-        origin_expr: bool,
-    },
-
-    /// Constants in patterns must have `Structural` type.
-    ConstPatternStructural,
-
-    /// Computing common supertype in an if expression
-    IfExpression(Box<IfExpressionCause>),
-
-    /// Computing common supertype of an if expression with no else counter-part
-    IfExpressionWithNoElse,
-
-    /// `main` has wrong type
-    MainFunctionType,
-
-    /// `start` has wrong type
-    StartFunctionType,
-
-    /// Intrinsic has wrong type
-    IntrinsicType,
-
-    /// Method receiver
-    MethodReceiver,
-
-    /// `return` with no expression
-    ReturnNoExpression,
-
-    /// `return` with an expression
-    ReturnValue(hir::HirId),
-
-    /// Return type of this function
-    ReturnType,
-
-    /// Block implicit return
-    BlockTailExpression(hir::HirId),
-
-    /// #[feature(trivial_bounds)] is not enabled
-    TrivialBound,
-
-    AssocTypeBound(Box<AssocTypeBoundData>),
-}
-
-impl ObligationCauseCode<'_> {
-    // Return the base obligation, ignoring derived obligations.
-    pub fn peel_derives(&self) -> &Self {
-        let mut base_cause = self;
-        while let BuiltinDerivedObligation(cause) | ImplDerivedObligation(cause) = base_cause {
-            base_cause = &cause.parent_code;
-        }
-        base_cause
-    }
-}
-
-#[derive(Clone, Debug, PartialEq, Eq, Hash)]
-pub struct AssocTypeBoundData {
-    pub impl_span: Option<Span>,
-    pub original: Span,
-    pub bounds: Vec<Span>,
-}
-
-// `ObligationCauseCode` is used a lot. Make sure it doesn't unintentionally get bigger.
-#[cfg(target_arch = "x86_64")]
-static_assert_size!(ObligationCauseCode<'_>, 32);
-
-#[derive(Clone, Debug, PartialEq, Eq, Hash)]
-pub struct MatchExpressionArmCause<'tcx> {
-    pub arm_span: Span,
-    pub source: hir::MatchSource,
-    pub prior_arms: Vec<Span>,
-    pub last_ty: Ty<'tcx>,
-    pub scrut_hir_id: hir::HirId,
-}
-
-#[derive(Clone, Debug, PartialEq, Eq, Hash)]
-pub struct IfExpressionCause {
-    pub then: Span,
-    pub outer: Option<Span>,
-    pub semicolon: Option<Span>,
-}
-
-#[derive(Clone, Debug, PartialEq, Eq, Hash)]
-pub struct DerivedObligationCause<'tcx> {
-    /// The trait reference of the parent obligation that led to the
-    /// current obligation. Note that only trait obligations lead to
-    /// derived obligations, so we just store the trait reference here
-    /// directly.
-    pub parent_trait_ref: ty::PolyTraitRef<'tcx>,
-
-    /// The parent trait had this cause.
-    pub parent_code: Rc<ObligationCauseCode<'tcx>>,
-}
-
-/// The following types:
-/// * `WhereClause`,
-/// * `WellFormed`,
-/// * `FromEnv`,
-/// * `DomainGoal`,
-/// * `Goal`,
-/// * `Clause`,
-/// * `Environment`,
-/// * `InEnvironment`,
-/// are used for representing the trait system in the form of
-/// logic programming clauses. They are part of the interface
-/// for the chalk SLG solver.
-#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable, Lift)]
-pub enum WhereClause<'tcx> {
-    Implemented(ty::TraitPredicate<'tcx>),
-    ProjectionEq(ty::ProjectionPredicate<'tcx>),
-    RegionOutlives(ty::RegionOutlivesPredicate<'tcx>),
-    TypeOutlives(ty::TypeOutlivesPredicate<'tcx>),
-}
-
-#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable, Lift)]
-pub enum WellFormed<'tcx> {
-    Trait(ty::TraitPredicate<'tcx>),
-    Ty(Ty<'tcx>),
-}
-
-#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable, Lift)]
-pub enum FromEnv<'tcx> {
-    Trait(ty::TraitPredicate<'tcx>),
-    Ty(Ty<'tcx>),
-}
-
-#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable, Lift)]
-pub enum DomainGoal<'tcx> {
-    Holds(WhereClause<'tcx>),
-    WellFormed(WellFormed<'tcx>),
-    FromEnv(FromEnv<'tcx>),
-    Normalize(ty::ProjectionPredicate<'tcx>),
-}
-
-pub type PolyDomainGoal<'tcx> = ty::Binder<DomainGoal<'tcx>>;
-
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable)]
-pub enum QuantifierKind {
-    Universal,
-    Existential,
-}
-
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable, Lift)]
-pub enum GoalKind<'tcx> {
-    Implies(Clauses<'tcx>, Goal<'tcx>),
-    And(Goal<'tcx>, Goal<'tcx>),
-    Not(Goal<'tcx>),
-    DomainGoal(DomainGoal<'tcx>),
-    Quantified(QuantifierKind, ty::Binder<Goal<'tcx>>),
-    Subtype(Ty<'tcx>, Ty<'tcx>),
-    CannotProve,
-}
-
-pub type Goal<'tcx> = &'tcx GoalKind<'tcx>;
-
-pub type Goals<'tcx> = &'tcx List<Goal<'tcx>>;
-
-impl<'tcx> DomainGoal<'tcx> {
-    pub fn into_goal(self) -> GoalKind<'tcx> {
-        GoalKind::DomainGoal(self)
-    }
-
-    pub fn into_program_clause(self) -> ProgramClause<'tcx> {
-        ProgramClause {
-            goal: self,
-            hypotheses: ty::List::empty(),
-            category: ProgramClauseCategory::Other,
-        }
-    }
-}
-
-impl<'tcx> GoalKind<'tcx> {
-    pub fn from_poly_domain_goal(
-        domain_goal: PolyDomainGoal<'tcx>,
-        tcx: TyCtxt<'tcx>,
-    ) -> GoalKind<'tcx> {
-        match domain_goal.no_bound_vars() {
-            Some(p) => p.into_goal(),
-            None => GoalKind::Quantified(
-                QuantifierKind::Universal,
-                domain_goal.map_bound(|p| tcx.mk_goal(p.into_goal())),
-            ),
-        }
-    }
-}
-
-/// This matches the definition from Page 7 of "A Proof Procedure for the Logic of Hereditary
-/// Harrop Formulas".
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable)]
-pub enum Clause<'tcx> {
-    Implies(ProgramClause<'tcx>),
-    ForAll(ty::Binder<ProgramClause<'tcx>>),
-}
-
-impl Clause<'tcx> {
-    pub fn category(self) -> ProgramClauseCategory {
-        match self {
-            Clause::Implies(clause) => clause.category,
-            Clause::ForAll(clause) => clause.skip_binder().category,
-        }
-    }
-}
-
-/// Multiple clauses.
-pub type Clauses<'tcx> = &'tcx List<Clause<'tcx>>;
-
-/// A "program clause" has the form `D :- G1, ..., Gn`. It is saying
-/// that the domain goal `D` is true if `G1...Gn` are provable. This
-/// is equivalent to the implication `G1..Gn => D`; we usually write
-/// it with the reverse implication operator `:-` to emphasize the way
-/// that programs are actually solved (via backchaining, which starts
-/// with the goal to solve and proceeds from there).
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable)]
-pub struct ProgramClause<'tcx> {
-    /// This goal will be considered true ...
-    pub goal: DomainGoal<'tcx>,
-
-    /// ... if we can prove these hypotheses (there may be no hypotheses at all):
-    pub hypotheses: Goals<'tcx>,
-
-    /// Useful for filtering clauses.
-    pub category: ProgramClauseCategory,
-}
-
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable)]
-pub enum ProgramClauseCategory {
-    ImpliedBound,
-    WellFormed,
-    Other,
-}
-
-/// A set of clauses that we assume to be true.
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable)]
-pub struct Environment<'tcx> {
-    pub clauses: Clauses<'tcx>,
-}
-
-impl Environment<'tcx> {
-    pub fn with<G>(self, goal: G) -> InEnvironment<'tcx, G> {
-        InEnvironment { environment: self, goal }
-    }
-}
-
-/// Something (usually a goal), along with an environment.
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable)]
-pub struct InEnvironment<'tcx, G> {
-    pub environment: Environment<'tcx>,
-    pub goal: G,
-}
-
-#[derive(Clone, Debug, TypeFoldable)]
-pub enum SelectionError<'tcx> {
-    Unimplemented,
-    OutputTypeParameterMismatch(
-        ty::PolyTraitRef<'tcx>,
-        ty::PolyTraitRef<'tcx>,
-        ty::error::TypeError<'tcx>,
-    ),
-    TraitNotObjectSafe(DefId),
-    ConstEvalFailure(ErrorHandled),
-    Overflow,
-}
-
-/// When performing resolution, it is typically the case that there
-/// can be one of three outcomes:
-///
-/// - `Ok(Some(r))`: success occurred with result `r`
-/// - `Ok(None)`: could not definitely determine anything, usually due
-///   to inconclusive type inference.
-/// - `Err(e)`: error `e` occurred
-pub type SelectionResult<'tcx, T> = Result<Option<T>, SelectionError<'tcx>>;
-
-/// Given the successful resolution of an obligation, the `Vtable`
-/// indicates where the vtable comes from. Note that while we call this
-/// a "vtable", it does not necessarily indicate dynamic dispatch at
-/// runtime. `Vtable` instances just tell the compiler where to find
-/// methods, but in generic code those methods are typically statically
-/// dispatched -- only when an object is constructed is a `Vtable`
-/// instance reified into an actual vtable.
-///
-/// For example, the vtable may be tied to a specific impl (case A),
-/// or it may be relative to some bound that is in scope (case B).
-///
-/// ```
-/// impl<T:Clone> Clone<T> for Option<T> { ... } // Impl_1
-/// impl<T:Clone> Clone<T> for Box<T> { ... }    // Impl_2
-/// impl Clone for int { ... }             // Impl_3
-///
-/// fn foo<T:Clone>(concrete: Option<Box<int>>,
-///                 param: T,
-///                 mixed: Option<T>) {
-///
-///    // Case A: Vtable points at a specific impl. Only possible when
-///    // type is concretely known. If the impl itself has bounded
-///    // type parameters, Vtable will carry resolutions for those as well:
-///    concrete.clone(); // Vtable(Impl_1, [Vtable(Impl_2, [Vtable(Impl_3)])])
-///
-///    // Case B: Vtable must be provided by caller. This applies when
-///    // type is a type parameter.
-///    param.clone();    // VtableParam
-///
-///    // Case C: A mix of cases A and B.
-///    mixed.clone();    // Vtable(Impl_1, [VtableParam])
-/// }
-/// ```
-///
-/// ### The type parameter `N`
-///
-/// See explanation on `VtableImplData`.
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
-pub enum Vtable<'tcx, N> {
-    /// Vtable identifying a particular impl.
-    VtableImpl(VtableImplData<'tcx, N>),
-
-    /// Vtable for auto trait implementations.
-    /// This carries the information and nested obligations with regards
-    /// to an auto implementation for a trait `Trait`. The nested obligations
-    /// ensure the trait implementation holds for all the constituent types.
-    VtableAutoImpl(VtableAutoImplData<N>),
-
-    /// Successful resolution to an obligation provided by the caller
-    /// for some type parameter. The `Vec<N>` represents the
-    /// obligations incurred from normalizing the where-clause (if
-    /// any).
-    VtableParam(Vec<N>),
-
-    /// Virtual calls through an object.
-    VtableObject(VtableObjectData<'tcx, N>),
-
-    /// Successful resolution for a builtin trait.
-    VtableBuiltin(VtableBuiltinData<N>),
-
-    /// Vtable automatically generated for a closure. The `DefId` is the ID
-    /// of the closure expression. This is a `VtableImpl` in spirit, but the
-    /// impl is generated by the compiler and does not appear in the source.
-    VtableClosure(VtableClosureData<'tcx, N>),
-
-    /// Same as above, but for a function pointer type with the given signature.
-    VtableFnPointer(VtableFnPointerData<'tcx, N>),
-
-    /// Vtable automatically generated for a generator.
-    VtableGenerator(VtableGeneratorData<'tcx, N>),
-
-    /// Vtable for a trait alias.
-    VtableTraitAlias(VtableTraitAliasData<'tcx, N>),
-}
-
-impl<'tcx, N> Vtable<'tcx, N> {
-    pub fn nested_obligations(self) -> Vec<N> {
-        match self {
-            VtableImpl(i) => i.nested,
-            VtableParam(n) => n,
-            VtableBuiltin(i) => i.nested,
-            VtableAutoImpl(d) => d.nested,
-            VtableClosure(c) => c.nested,
-            VtableGenerator(c) => c.nested,
-            VtableObject(d) => d.nested,
-            VtableFnPointer(d) => d.nested,
-            VtableTraitAlias(d) => d.nested,
-        }
-    }
-
-    pub fn map<M, F>(self, f: F) -> Vtable<'tcx, M>
-    where
-        F: FnMut(N) -> M,
-    {
-        match self {
-            VtableImpl(i) => VtableImpl(VtableImplData {
-                impl_def_id: i.impl_def_id,
-                substs: i.substs,
-                nested: i.nested.into_iter().map(f).collect(),
-            }),
-            VtableParam(n) => VtableParam(n.into_iter().map(f).collect()),
-            VtableBuiltin(i) => {
-                VtableBuiltin(VtableBuiltinData { nested: i.nested.into_iter().map(f).collect() })
-            }
-            VtableObject(o) => VtableObject(VtableObjectData {
-                upcast_trait_ref: o.upcast_trait_ref,
-                vtable_base: o.vtable_base,
-                nested: o.nested.into_iter().map(f).collect(),
-            }),
-            VtableAutoImpl(d) => VtableAutoImpl(VtableAutoImplData {
-                trait_def_id: d.trait_def_id,
-                nested: d.nested.into_iter().map(f).collect(),
-            }),
-            VtableClosure(c) => VtableClosure(VtableClosureData {
-                closure_def_id: c.closure_def_id,
-                substs: c.substs,
-                nested: c.nested.into_iter().map(f).collect(),
-            }),
-            VtableGenerator(c) => VtableGenerator(VtableGeneratorData {
-                generator_def_id: c.generator_def_id,
-                substs: c.substs,
-                nested: c.nested.into_iter().map(f).collect(),
-            }),
-            VtableFnPointer(p) => VtableFnPointer(VtableFnPointerData {
-                fn_ty: p.fn_ty,
-                nested: p.nested.into_iter().map(f).collect(),
-            }),
-            VtableTraitAlias(d) => VtableTraitAlias(VtableTraitAliasData {
-                alias_def_id: d.alias_def_id,
-                substs: d.substs,
-                nested: d.nested.into_iter().map(f).collect(),
-            }),
-        }
-    }
-}
-
-/// Identifies a particular impl in the source, along with a set of
-/// substitutions from the impl's type/lifetime parameters. The
-/// `nested` vector corresponds to the nested obligations attached to
-/// the impl's type parameters.
-///
-/// The type parameter `N` indicates the type used for "nested
-/// obligations" that are required by the impl. During type-check, this
-/// is `Obligation`, as one might expect. During codegen, however, this
-/// is `()`, because codegen only requires a shallow resolution of an
-/// impl, and nested obligations are satisfied later.
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
-pub struct VtableImplData<'tcx, N> {
-    pub impl_def_id: DefId,
-    pub substs: SubstsRef<'tcx>,
-    pub nested: Vec<N>,
-}
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
-pub struct VtableGeneratorData<'tcx, N> {
-    pub generator_def_id: DefId,
-    pub substs: SubstsRef<'tcx>,
-    /// Nested obligations. This can be non-empty if the generator
-    /// signature contains associated types.
-    pub nested: Vec<N>,
-}
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
-pub struct VtableClosureData<'tcx, N> {
-    pub closure_def_id: DefId,
-    pub substs: SubstsRef<'tcx>,
-    /// Nested obligations. This can be non-empty if the closure
-    /// signature contains associated types.
-    pub nested: Vec<N>,
-}
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
-pub struct VtableAutoImplData<N> {
-    pub trait_def_id: DefId,
-    pub nested: Vec<N>,
-}
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
-pub struct VtableBuiltinData<N> {
-    pub nested: Vec<N>,
-}
-
-/// A vtable for some object-safe trait `Foo` automatically derived
-/// for the object type `Foo`.
-#[derive(PartialEq, Eq, Clone, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
-pub struct VtableObjectData<'tcx, N> {
-    /// `Foo` upcast to the obligation trait. This will be some supertrait of `Foo`.
-    pub upcast_trait_ref: ty::PolyTraitRef<'tcx>,
-
-    /// The vtable is formed by concatenating together the method lists of
-    /// the base object trait and all supertraits; this is the start of
-    /// `upcast_trait_ref`'s methods in that vtable.
-    pub vtable_base: usize,
-
-    pub nested: Vec<N>,
-}
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
-pub struct VtableFnPointerData<'tcx, N> {
-    pub fn_ty: Ty<'tcx>,
-    pub nested: Vec<N>,
-}
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
-pub struct VtableTraitAliasData<'tcx, N> {
-    pub alias_def_id: DefId,
-    pub substs: SubstsRef<'tcx>,
-    pub nested: Vec<N>,
-}
-
-pub trait ExClauseFold<'tcx>
-where
-    Self: chalk_engine::context::Context + Clone,
-{
-    fn fold_ex_clause_with<F: TypeFolder<'tcx>>(
-        ex_clause: &chalk_engine::ExClause<Self>,
-        folder: &mut F,
-    ) -> chalk_engine::ExClause<Self>;
-
-    fn visit_ex_clause_with<V: TypeVisitor<'tcx>>(
-        ex_clause: &chalk_engine::ExClause<Self>,
-        visitor: &mut V,
-    ) -> bool;
-}
-
-pub trait ChalkContextLift<'tcx>
-where
-    Self: chalk_engine::context::Context + Clone,
-{
-    type LiftedExClause: Debug + 'tcx;
-    type LiftedDelayedLiteral: Debug + 'tcx;
-    type LiftedLiteral: Debug + 'tcx;
-
-    fn lift_ex_clause_to_tcx(
-        ex_clause: &chalk_engine::ExClause<Self>,
-        tcx: TyCtxt<'tcx>,
-    ) -> Option<Self::LiftedExClause>;
-
-    fn lift_delayed_literal_to_tcx(
-        ex_clause: &chalk_engine::DelayedLiteral<Self>,
-        tcx: TyCtxt<'tcx>,
-    ) -> Option<Self::LiftedDelayedLiteral>;
-
-    fn lift_literal_to_tcx(
-        ex_clause: &chalk_engine::Literal<Self>,
-        tcx: TyCtxt<'tcx>,
-    ) -> Option<Self::LiftedLiteral>;
-}
-
-#[derive(Clone, Debug, PartialEq, Eq, Hash, HashStable)]
-pub enum ObjectSafetyViolation {
-    /// `Self: Sized` declared on the trait.
-    SizedSelf(SmallVec<[Span; 1]>),
-
-    /// Supertrait reference references `Self` an in illegal location
-    /// (e.g., `trait Foo : Bar<Self>`).
-    SupertraitSelf(SmallVec<[Span; 1]>),
-
-    /// Method has something illegal.
-    Method(ast::Name, MethodViolationCode, Span),
-
-    /// Associated const.
-    AssocConst(ast::Name, Span),
-}
-
-impl ObjectSafetyViolation {
-    pub fn error_msg(&self) -> Cow<'static, str> {
-        match *self {
-            ObjectSafetyViolation::SizedSelf(_) => "it requires `Self: Sized`".into(),
-            ObjectSafetyViolation::SupertraitSelf(ref spans) => {
-                if spans.iter().any(|sp| *sp != DUMMY_SP) {
-                    "it uses `Self` as a type parameter in this".into()
-                } else {
-                    "it cannot use `Self` as a type parameter in a supertrait or `where`-clause"
-                        .into()
-                }
-            }
-            ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod(_), _) => {
-                format!("associated function `{}` has no `self` parameter", name).into()
-            }
-            ObjectSafetyViolation::Method(
-                name,
-                MethodViolationCode::ReferencesSelfInput(_),
-                DUMMY_SP,
-            ) => format!("method `{}` references the `Self` type in its parameters", name).into(),
-            ObjectSafetyViolation::Method(name, MethodViolationCode::ReferencesSelfInput(_), _) => {
-                format!("method `{}` references the `Self` type in this parameter", name).into()
-            }
-            ObjectSafetyViolation::Method(name, MethodViolationCode::ReferencesSelfOutput, _) => {
-                format!("method `{}` references the `Self` type in its return type", name).into()
-            }
-            ObjectSafetyViolation::Method(
-                name,
-                MethodViolationCode::WhereClauseReferencesSelf,
-                _,
-            ) => {
-                format!("method `{}` references the `Self` type in its `where` clause", name).into()
-            }
-            ObjectSafetyViolation::Method(name, MethodViolationCode::Generic, _) => {
-                format!("method `{}` has generic type parameters", name).into()
-            }
-            ObjectSafetyViolation::Method(name, MethodViolationCode::UndispatchableReceiver, _) => {
-                format!("method `{}`'s `self` parameter cannot be dispatched on", name).into()
-            }
-            ObjectSafetyViolation::AssocConst(name, DUMMY_SP) => {
-                format!("it contains associated `const` `{}`", name).into()
-            }
-            ObjectSafetyViolation::AssocConst(..) => "it contains this associated `const`".into(),
-        }
-    }
-
-    pub fn solution(&self) -> Option<(String, Option<(String, Span)>)> {
-        Some(match *self {
-            ObjectSafetyViolation::SizedSelf(_) | ObjectSafetyViolation::SupertraitSelf(_) => {
-                return None;
-            }
-            ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod(sugg), _) => (
-                format!(
-                    "consider turning `{}` into a method by giving it a `&self` argument or \
-                     constraining it so it does not apply to trait objects",
-                    name
-                ),
-                sugg.map(|(sugg, sp)| (sugg.to_string(), sp)),
-            ),
-            ObjectSafetyViolation::Method(
-                name,
-                MethodViolationCode::UndispatchableReceiver,
-                span,
-            ) => (
-                format!("consider changing method `{}`'s `self` parameter to be `&self`", name)
-                    .into(),
-                Some(("&Self".to_string(), span)),
-            ),
-            ObjectSafetyViolation::AssocConst(name, _)
-            | ObjectSafetyViolation::Method(name, ..) => {
-                (format!("consider moving `{}` to another trait", name), None)
-            }
-        })
-    }
-
-    pub fn spans(&self) -> SmallVec<[Span; 1]> {
-        // When `span` comes from a separate crate, it'll be `DUMMY_SP`. Treat it as `None` so
-        // diagnostics use a `note` instead of a `span_label`.
-        match self {
-            ObjectSafetyViolation::SupertraitSelf(spans)
-            | ObjectSafetyViolation::SizedSelf(spans) => spans.clone(),
-            ObjectSafetyViolation::AssocConst(_, span)
-            | ObjectSafetyViolation::Method(_, _, span)
-                if *span != DUMMY_SP =>
-            {
-                smallvec![*span]
-            }
-            _ => smallvec![],
-        }
-    }
-}
-
-/// Reasons a method might not be object-safe.
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)]
-pub enum MethodViolationCode {
-    /// e.g., `fn foo()`
-    StaticMethod(Option<(&'static str, Span)>),
-
-    /// e.g., `fn foo(&self, x: Self)`
-    ReferencesSelfInput(usize),
-
-    /// e.g., `fn foo(&self) -> Self`
-    ReferencesSelfOutput,
-
-    /// e.g., `fn foo(&self) where Self: Clone`
-    WhereClauseReferencesSelf,
-
-    /// e.g., `fn foo<A>()`
-    Generic,
-
-    /// the method's receiver (`self` argument) can't be dispatched on
-    UndispatchableReceiver,
-}
diff --git a/src/librustc/traits/query.rs b/src/librustc/traits/query.rs
deleted file mode 100644
index c9055182620..00000000000
--- a/src/librustc/traits/query.rs
+++ /dev/null
@@ -1,332 +0,0 @@
-//! Experimental types for the trait query interface. The methods
-//! defined in this module are all based on **canonicalization**,
-//! which makes a canonical query by replacing unbound inference
-//! variables and regions, so that results can be reused more broadly.
-//! The providers for the queries defined here can be found in
-//! `librustc_traits`.
-
-use crate::ich::StableHashingContext;
-use crate::infer::canonical::{Canonical, QueryResponse};
-use crate::ty::error::TypeError;
-use crate::ty::subst::GenericArg;
-use crate::ty::{self, Ty, TyCtxt};
-
-use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
-use rustc_data_structures::sync::Lrc;
-use rustc_errors::struct_span_err;
-use rustc_span::source_map::Span;
-use std::iter::FromIterator;
-use std::mem;
-
-pub mod type_op {
-    use crate::ty::fold::TypeFoldable;
-    use crate::ty::subst::UserSubsts;
-    use crate::ty::{Predicate, Ty};
-    use rustc_hir::def_id::DefId;
-    use std::fmt;
-
-    #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, Lift)]
-    pub struct AscribeUserType<'tcx> {
-        pub mir_ty: Ty<'tcx>,
-        pub def_id: DefId,
-        pub user_substs: UserSubsts<'tcx>,
-    }
-
-    impl<'tcx> AscribeUserType<'tcx> {
-        pub fn new(mir_ty: Ty<'tcx>, def_id: DefId, user_substs: UserSubsts<'tcx>) -> Self {
-            Self { mir_ty, def_id, user_substs }
-        }
-    }
-
-    #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, Lift)]
-    pub struct Eq<'tcx> {
-        pub a: Ty<'tcx>,
-        pub b: Ty<'tcx>,
-    }
-
-    impl<'tcx> Eq<'tcx> {
-        pub fn new(a: Ty<'tcx>, b: Ty<'tcx>) -> Self {
-            Self { a, b }
-        }
-    }
-
-    #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, Lift)]
-    pub struct Subtype<'tcx> {
-        pub sub: Ty<'tcx>,
-        pub sup: Ty<'tcx>,
-    }
-
-    impl<'tcx> Subtype<'tcx> {
-        pub fn new(sub: Ty<'tcx>, sup: Ty<'tcx>) -> Self {
-            Self { sub, sup }
-        }
-    }
-
-    #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, Lift)]
-    pub struct ProvePredicate<'tcx> {
-        pub predicate: Predicate<'tcx>,
-    }
-
-    impl<'tcx> ProvePredicate<'tcx> {
-        pub fn new(predicate: Predicate<'tcx>) -> Self {
-            ProvePredicate { predicate }
-        }
-    }
-
-    #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, Lift)]
-    pub struct Normalize<T> {
-        pub value: T,
-    }
-
-    impl<'tcx, T> Normalize<T>
-    where
-        T: fmt::Debug + TypeFoldable<'tcx>,
-    {
-        pub fn new(value: T) -> Self {
-            Self { value }
-        }
-    }
-}
-
-pub type CanonicalProjectionGoal<'tcx> =
-    Canonical<'tcx, ty::ParamEnvAnd<'tcx, ty::ProjectionTy<'tcx>>>;
-
-pub type CanonicalTyGoal<'tcx> = Canonical<'tcx, ty::ParamEnvAnd<'tcx, Ty<'tcx>>>;
-
-pub type CanonicalPredicateGoal<'tcx> = Canonical<'tcx, ty::ParamEnvAnd<'tcx, ty::Predicate<'tcx>>>;
-
-pub type CanonicalTypeOpAscribeUserTypeGoal<'tcx> =
-    Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::AscribeUserType<'tcx>>>;
-
-pub type CanonicalTypeOpEqGoal<'tcx> = Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::Eq<'tcx>>>;
-
-pub type CanonicalTypeOpSubtypeGoal<'tcx> =
-    Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::Subtype<'tcx>>>;
-
-pub type CanonicalTypeOpProvePredicateGoal<'tcx> =
-    Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::ProvePredicate<'tcx>>>;
-
-pub type CanonicalTypeOpNormalizeGoal<'tcx, T> =
-    Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::Normalize<T>>>;
-
-#[derive(Clone, Debug, HashStable)]
-pub struct NoSolution;
-
-pub type Fallible<T> = Result<T, NoSolution>;
-
-impl<'tcx> From<TypeError<'tcx>> for NoSolution {
-    fn from(_: TypeError<'tcx>) -> NoSolution {
-        NoSolution
-    }
-}
-
-#[derive(Clone, Debug, Default, HashStable, TypeFoldable, Lift)]
-pub struct DropckOutlivesResult<'tcx> {
-    pub kinds: Vec<GenericArg<'tcx>>,
-    pub overflows: Vec<Ty<'tcx>>,
-}
-
-impl<'tcx> DropckOutlivesResult<'tcx> {
-    pub fn report_overflows(&self, tcx: TyCtxt<'tcx>, span: Span, ty: Ty<'tcx>) {
-        if let Some(overflow_ty) = self.overflows.iter().next() {
-            let mut err = struct_span_err!(
-                tcx.sess,
-                span,
-                E0320,
-                "overflow while adding drop-check rules for {}",
-                ty,
-            );
-            err.note(&format!("overflowed on {}", overflow_ty));
-            err.emit();
-        }
-    }
-
-    pub fn into_kinds_reporting_overflows(
-        self,
-        tcx: TyCtxt<'tcx>,
-        span: Span,
-        ty: Ty<'tcx>,
-    ) -> Vec<GenericArg<'tcx>> {
-        self.report_overflows(tcx, span, ty);
-        let DropckOutlivesResult { kinds, overflows: _ } = self;
-        kinds
-    }
-}
-
-/// A set of constraints that need to be satisfied in order for
-/// a type to be valid for destruction.
-#[derive(Clone, Debug, HashStable)]
-pub struct DtorckConstraint<'tcx> {
-    /// Types that are required to be alive in order for this
-    /// type to be valid for destruction.
-    pub outlives: Vec<ty::subst::GenericArg<'tcx>>,
-
-    /// Types that could not be resolved: projections and params.
-    pub dtorck_types: Vec<Ty<'tcx>>,
-
-    /// If, during the computation of the dtorck constraint, we
-    /// overflow, that gets recorded here. The caller is expected to
-    /// report an error.
-    pub overflows: Vec<Ty<'tcx>>,
-}
-
-impl<'tcx> DtorckConstraint<'tcx> {
-    pub fn empty() -> DtorckConstraint<'tcx> {
-        DtorckConstraint { outlives: vec![], dtorck_types: vec![], overflows: vec![] }
-    }
-}
-
-impl<'tcx> FromIterator<DtorckConstraint<'tcx>> for DtorckConstraint<'tcx> {
-    fn from_iter<I: IntoIterator<Item = DtorckConstraint<'tcx>>>(iter: I) -> Self {
-        let mut result = Self::empty();
-
-        for DtorckConstraint { outlives, dtorck_types, overflows } in iter {
-            result.outlives.extend(outlives);
-            result.dtorck_types.extend(dtorck_types);
-            result.overflows.extend(overflows);
-        }
-
-        result
-    }
-}
-
-/// This returns true if the type `ty` is "trivial" for
-/// dropck-outlives -- that is, if it doesn't require any types to
-/// outlive. This is similar but not *quite* the same as the
-/// `needs_drop` test in the compiler already -- that is, for every
-/// type T for which this function return true, needs-drop would
-/// return `false`. But the reverse does not hold: in particular,
-/// `needs_drop` returns false for `PhantomData`, but it is not
-/// trivial for dropck-outlives.
-///
-/// Note also that `needs_drop` requires a "global" type (i.e., one
-/// with erased regions), but this function does not.
-pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
-    match ty.kind {
-        // None of these types have a destructor and hence they do not
-        // require anything in particular to outlive the dtor's
-        // execution.
-        ty::Infer(ty::FreshIntTy(_))
-        | ty::Infer(ty::FreshFloatTy(_))
-        | ty::Bool
-        | ty::Int(_)
-        | ty::Uint(_)
-        | ty::Float(_)
-        | ty::Never
-        | ty::FnDef(..)
-        | ty::FnPtr(_)
-        | ty::Char
-        | ty::GeneratorWitness(..)
-        | ty::RawPtr(_)
-        | ty::Ref(..)
-        | ty::Str
-        | ty::Foreign(..)
-        | ty::Error => true,
-
-        // [T; N] and [T] have same properties as T.
-        ty::Array(ty, _) | ty::Slice(ty) => trivial_dropck_outlives(tcx, ty),
-
-        // (T1..Tn) and closures have same properties as T1..Tn --
-        // check if *any* of those are trivial.
-        ty::Tuple(ref tys) => tys.iter().all(|t| trivial_dropck_outlives(tcx, t.expect_ty())),
-        ty::Closure(def_id, ref substs) => {
-            substs.as_closure().upvar_tys(def_id, tcx).all(|t| trivial_dropck_outlives(tcx, t))
-        }
-
-        ty::Adt(def, _) => {
-            if Some(def.did) == tcx.lang_items().manually_drop() {
-                // `ManuallyDrop` never has a dtor.
-                true
-            } else {
-                // Other types might. Moreover, PhantomData doesn't
-                // have a dtor, but it is considered to own its
-                // content, so it is non-trivial. Unions can have `impl Drop`,
-                // and hence are non-trivial as well.
-                false
-            }
-        }
-
-        // The following *might* require a destructor: needs deeper inspection.
-        ty::Dynamic(..)
-        | ty::Projection(..)
-        | ty::Param(_)
-        | ty::Opaque(..)
-        | ty::Placeholder(..)
-        | ty::Infer(_)
-        | ty::Bound(..)
-        | ty::Generator(..) => false,
-
-        ty::UnnormalizedProjection(..) => bug!("only used with chalk-engine"),
-    }
-}
-
-#[derive(Debug, HashStable)]
-pub struct CandidateStep<'tcx> {
-    pub self_ty: Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>,
-    pub autoderefs: usize,
-    /// `true` if the type results from a dereference of a raw pointer.
-    /// when assembling candidates, we include these steps, but not when
-    /// picking methods. This so that if we have `foo: *const Foo` and `Foo` has methods
-    /// `fn by_raw_ptr(self: *const Self)` and `fn by_ref(&self)`, then
-    /// `foo.by_raw_ptr()` will work and `foo.by_ref()` won't.
-    pub from_unsafe_deref: bool,
-    pub unsize: bool,
-}
-
-#[derive(Clone, Debug, HashStable)]
-pub struct MethodAutoderefStepsResult<'tcx> {
-    /// The valid autoderef steps that could be find.
-    pub steps: Lrc<Vec<CandidateStep<'tcx>>>,
-    /// If Some(T), a type autoderef reported an error on.
-    pub opt_bad_ty: Option<Lrc<MethodAutoderefBadTy<'tcx>>>,
-    /// If `true`, `steps` has been truncated due to reaching the
-    /// recursion limit.
-    pub reached_recursion_limit: bool,
-}
-
-#[derive(Debug, HashStable)]
-pub struct MethodAutoderefBadTy<'tcx> {
-    pub reached_raw_pointer: bool,
-    pub ty: Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>,
-}
-
-/// Result from the `normalize_projection_ty` query.
-#[derive(Clone, Debug, HashStable, TypeFoldable, Lift)]
-pub struct NormalizationResult<'tcx> {
-    /// Result of normalization.
-    pub normalized_ty: Ty<'tcx>,
-}
-
-/// Outlives bounds are relationships between generic parameters,
-/// whether they both be regions (`'a: 'b`) or whether types are
-/// involved (`T: 'a`). These relationships can be extracted from the
-/// full set of predicates we understand or also from types (in which
-/// case they are called implied bounds). They are fed to the
-/// `OutlivesEnv` which in turn is supplied to the region checker and
-/// other parts of the inference system.
-#[derive(Clone, Debug, TypeFoldable, Lift)]
-pub enum OutlivesBound<'tcx> {
-    RegionSubRegion(ty::Region<'tcx>, ty::Region<'tcx>),
-    RegionSubParam(ty::Region<'tcx>, ty::ParamTy),
-    RegionSubProjection(ty::Region<'tcx>, ty::ProjectionTy<'tcx>),
-}
-
-impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for OutlivesBound<'tcx> {
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        mem::discriminant(self).hash_stable(hcx, hasher);
-        match *self {
-            OutlivesBound::RegionSubRegion(ref a, ref b) => {
-                a.hash_stable(hcx, hasher);
-                b.hash_stable(hcx, hasher);
-            }
-            OutlivesBound::RegionSubParam(ref a, ref b) => {
-                a.hash_stable(hcx, hasher);
-                b.hash_stable(hcx, hasher);
-            }
-            OutlivesBound::RegionSubProjection(ref a, ref b) => {
-                a.hash_stable(hcx, hasher);
-                b.hash_stable(hcx, hasher);
-            }
-        }
-    }
-}
diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs
deleted file mode 100644
index ac3d0049c0c..00000000000
--- a/src/librustc/traits/select.rs
+++ /dev/null
@@ -1,290 +0,0 @@
-//! Candidate selection. See the [rustc guide] for more information on how this works.
-//!
-//! [rustc guide]: https://rust-lang.github.io/rustc-guide/traits/resolution.html#selection
-
-use self::EvaluationResult::*;
-
-use super::{SelectionError, SelectionResult};
-
-use crate::dep_graph::DepNodeIndex;
-use crate::ty::{self, TyCtxt};
-
-use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::sync::Lock;
-use rustc_hir::def_id::DefId;
-
-#[derive(Clone, Default)]
-pub struct SelectionCache<'tcx> {
-    pub hashmap: Lock<
-        FxHashMap<
-            ty::ParamEnvAnd<'tcx, ty::TraitRef<'tcx>>,
-            WithDepNode<SelectionResult<'tcx, SelectionCandidate<'tcx>>>,
-        >,
-    >,
-}
-
-impl<'tcx> SelectionCache<'tcx> {
-    /// Actually frees the underlying memory in contrast to what stdlib containers do on `clear`
-    pub fn clear(&self) {
-        *self.hashmap.borrow_mut() = Default::default();
-    }
-}
-
-/// The selection process begins by considering all impls, where
-/// clauses, and so forth that might resolve an obligation. Sometimes
-/// we'll be able to say definitively that (e.g.) an impl does not
-/// apply to the obligation: perhaps it is defined for `usize` but the
-/// obligation is for `int`. In that case, we drop the impl out of the
-/// list. But the other cases are considered *candidates*.
-///
-/// For selection to succeed, there must be exactly one matching
-/// candidate. If the obligation is fully known, this is guaranteed
-/// by coherence. However, if the obligation contains type parameters
-/// or variables, there may be multiple such impls.
-///
-/// It is not a real problem if multiple matching impls exist because
-/// of type variables - it just means the obligation isn't sufficiently
-/// elaborated. In that case we report an ambiguity, and the caller can
-/// try again after more type information has been gathered or report a
-/// "type annotations needed" error.
-///
-/// However, with type parameters, this can be a real problem - type
-/// parameters don't unify with regular types, but they *can* unify
-/// with variables from blanket impls, and (unless we know its bounds
-/// will always be satisfied) picking the blanket impl will be wrong
-/// for at least *some* substitutions. To make this concrete, if we have
-///
-///    trait AsDebug { type Out : fmt::Debug; fn debug(self) -> Self::Out; }
-///    impl<T: fmt::Debug> AsDebug for T {
-///        type Out = T;
-///        fn debug(self) -> fmt::Debug { self }
-///    }
-///    fn foo<T: AsDebug>(t: T) { println!("{:?}", <T as AsDebug>::debug(t)); }
-///
-/// we can't just use the impl to resolve the `<T as AsDebug>` obligation
-/// -- a type from another crate (that doesn't implement `fmt::Debug`) could
-/// implement `AsDebug`.
-///
-/// Because where-clauses match the type exactly, multiple clauses can
-/// only match if there are unresolved variables, and we can mostly just
-/// report this ambiguity in that case. This is still a problem - we can't
-/// *do anything* with ambiguities that involve only regions. This is issue
-/// #21974.
-///
-/// If a single where-clause matches and there are no inference
-/// variables left, then it definitely matches and we can just select
-/// it.
-///
-/// In fact, we even select the where-clause when the obligation contains
-/// inference variables. The can lead to inference making "leaps of logic",
-/// for example in this situation:
-///
-///    pub trait Foo<T> { fn foo(&self) -> T; }
-///    impl<T> Foo<()> for T { fn foo(&self) { } }
-///    impl Foo<bool> for bool { fn foo(&self) -> bool { *self } }
-///
-///    pub fn foo<T>(t: T) where T: Foo<bool> {
-///       println!("{:?}", <T as Foo<_>>::foo(&t));
-///    }
-///    fn main() { foo(false); }
-///
-/// Here the obligation `<T as Foo<$0>>` can be matched by both the blanket
-/// impl and the where-clause. We select the where-clause and unify `$0=bool`,
-/// so the program prints "false". However, if the where-clause is omitted,
-/// the blanket impl is selected, we unify `$0=()`, and the program prints
-/// "()".
-///
-/// Exactly the same issues apply to projection and object candidates, except
-/// that we can have both a projection candidate and a where-clause candidate
-/// for the same obligation. In that case either would do (except that
-/// different "leaps of logic" would occur if inference variables are
-/// present), and we just pick the where-clause. This is, for example,
-/// required for associated types to work in default impls, as the bounds
-/// are visible both as projection bounds and as where-clauses from the
-/// parameter environment.
-#[derive(PartialEq, Eq, Debug, Clone, TypeFoldable)]
-pub enum SelectionCandidate<'tcx> {
-    BuiltinCandidate {
-        /// `false` if there are no *further* obligations.
-        has_nested: bool,
-    },
-    ParamCandidate(ty::PolyTraitRef<'tcx>),
-    ImplCandidate(DefId),
-    AutoImplCandidate(DefId),
-
-    /// This is a trait matching with a projected type as `Self`, and
-    /// we found an applicable bound in the trait definition.
-    ProjectionCandidate,
-
-    /// Implementation of a `Fn`-family trait by one of the anonymous types
-    /// generated for a `||` expression.
-    ClosureCandidate,
-
-    /// Implementation of a `Generator` trait by one of the anonymous types
-    /// generated for a generator.
-    GeneratorCandidate,
-
-    /// Implementation of a `Fn`-family trait by one of the anonymous
-    /// types generated for a fn pointer type (e.g., `fn(int) -> int`)
-    FnPointerCandidate,
-
-    TraitAliasCandidate(DefId),
-
-    ObjectCandidate,
-
-    BuiltinObjectCandidate,
-
-    BuiltinUnsizeCandidate,
-}
-
-/// The result of trait evaluation. The order is important
-/// here as the evaluation of a list is the maximum of the
-/// evaluations.
-///
-/// The evaluation results are ordered:
-///     - `EvaluatedToOk` implies `EvaluatedToOkModuloRegions`
-///       implies `EvaluatedToAmbig` implies `EvaluatedToUnknown`
-///     - `EvaluatedToErr` implies `EvaluatedToRecur`
-///     - the "union" of evaluation results is equal to their maximum -
-///     all the "potential success" candidates can potentially succeed,
-///     so they are noops when unioned with a definite error, and within
-///     the categories it's easy to see that the unions are correct.
-#[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq, HashStable)]
-pub enum EvaluationResult {
-    /// Evaluation successful.
-    EvaluatedToOk,
-    /// Evaluation successful, but there were unevaluated region obligations.
-    EvaluatedToOkModuloRegions,
-    /// Evaluation is known to be ambiguous -- it *might* hold for some
-    /// assignment of inference variables, but it might not.
-    ///
-    /// While this has the same meaning as `EvaluatedToUnknown` -- we can't
-    /// know whether this obligation holds or not -- it is the result we
-    /// would get with an empty stack, and therefore is cacheable.
-    EvaluatedToAmbig,
-    /// Evaluation failed because of recursion involving inference
-    /// variables. We are somewhat imprecise there, so we don't actually
-    /// know the real result.
-    ///
-    /// This can't be trivially cached for the same reason as `EvaluatedToRecur`.
-    EvaluatedToUnknown,
-    /// Evaluation failed because we encountered an obligation we are already
-    /// trying to prove on this branch.
-    ///
-    /// We know this branch can't be a part of a minimal proof-tree for
-    /// the "root" of our cycle, because then we could cut out the recursion
-    /// and maintain a valid proof tree. However, this does not mean
-    /// that all the obligations on this branch do not hold -- it's possible
-    /// that we entered this branch "speculatively", and that there
-    /// might be some other way to prove this obligation that does not
-    /// go through this cycle -- so we can't cache this as a failure.
-    ///
-    /// For example, suppose we have this:
-    ///
-    /// ```rust,ignore (pseudo-Rust)
-    /// pub trait Trait { fn xyz(); }
-    /// // This impl is "useless", but we can still have
-    /// // an `impl Trait for SomeUnsizedType` somewhere.
-    /// impl<T: Trait + Sized> Trait for T { fn xyz() {} }
-    ///
-    /// pub fn foo<T: Trait + ?Sized>() {
-    ///     <T as Trait>::xyz();
-    /// }
-    /// ```
-    ///
-    /// When checking `foo`, we have to prove `T: Trait`. This basically
-    /// translates into this:
-    ///
-    /// ```plain,ignore
-    /// (T: Trait + Sized →_\impl T: Trait), T: Trait ⊢ T: Trait
-    /// ```
-    ///
-    /// When we try to prove it, we first go the first option, which
-    /// recurses. This shows us that the impl is "useless" -- it won't
-    /// tell us that `T: Trait` unless it already implemented `Trait`
-    /// by some other means. However, that does not prevent `T: Trait`
-    /// does not hold, because of the bound (which can indeed be satisfied
-    /// by `SomeUnsizedType` from another crate).
-    //
-    // FIXME: when an `EvaluatedToRecur` goes past its parent root, we
-    // ought to convert it to an `EvaluatedToErr`, because we know
-    // there definitely isn't a proof tree for that obligation. Not
-    // doing so is still sound -- there isn't any proof tree, so the
-    // branch still can't be a part of a minimal one -- but does not re-enable caching.
-    EvaluatedToRecur,
-    /// Evaluation failed.
-    EvaluatedToErr,
-}
-
-impl EvaluationResult {
-    /// Returns `true` if this evaluation result is known to apply, even
-    /// considering outlives constraints.
-    pub fn must_apply_considering_regions(self) -> bool {
-        self == EvaluatedToOk
-    }
-
-    /// Returns `true` if this evaluation result is known to apply, ignoring
-    /// outlives constraints.
-    pub fn must_apply_modulo_regions(self) -> bool {
-        self <= EvaluatedToOkModuloRegions
-    }
-
-    pub fn may_apply(self) -> bool {
-        match self {
-            EvaluatedToOk | EvaluatedToOkModuloRegions | EvaluatedToAmbig | EvaluatedToUnknown => {
-                true
-            }
-
-            EvaluatedToErr | EvaluatedToRecur => false,
-        }
-    }
-
-    pub fn is_stack_dependent(self) -> bool {
-        match self {
-            EvaluatedToUnknown | EvaluatedToRecur => true,
-
-            EvaluatedToOk | EvaluatedToOkModuloRegions | EvaluatedToAmbig | EvaluatedToErr => false,
-        }
-    }
-}
-
-/// Indicates that trait evaluation caused overflow.
-#[derive(Copy, Clone, Debug, PartialEq, Eq, HashStable)]
-pub struct OverflowError;
-
-impl<'tcx> From<OverflowError> for SelectionError<'tcx> {
-    fn from(OverflowError: OverflowError) -> SelectionError<'tcx> {
-        SelectionError::Overflow
-    }
-}
-
-#[derive(Clone, Default)]
-pub struct EvaluationCache<'tcx> {
-    pub hashmap: Lock<
-        FxHashMap<ty::ParamEnvAnd<'tcx, ty::PolyTraitRef<'tcx>>, WithDepNode<EvaluationResult>>,
-    >,
-}
-
-impl<'tcx> EvaluationCache<'tcx> {
-    /// Actually frees the underlying memory in contrast to what stdlib containers do on `clear`
-    pub fn clear(&self) {
-        *self.hashmap.borrow_mut() = Default::default();
-    }
-}
-
-#[derive(Clone, Eq, PartialEq)]
-pub struct WithDepNode<T> {
-    dep_node: DepNodeIndex,
-    cached_value: T,
-}
-
-impl<T: Clone> WithDepNode<T> {
-    pub fn new(dep_node: DepNodeIndex, cached_value: T) -> Self {
-        WithDepNode { dep_node, cached_value }
-    }
-
-    pub fn get(&self, tcx: TyCtxt<'_>) -> T {
-        tcx.dep_graph.read_index(self.dep_node);
-        self.cached_value.clone()
-    }
-}
diff --git a/src/librustc/traits/specialization_graph.rs b/src/librustc/traits/specialization_graph.rs
deleted file mode 100644
index ee813bf606e..00000000000
--- a/src/librustc/traits/specialization_graph.rs
+++ /dev/null
@@ -1,202 +0,0 @@
-use crate::ich::{self, StableHashingContext};
-use crate::ty::fast_reject::SimplifiedType;
-use crate::ty::{self, TyCtxt};
-use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
-use rustc_hir::def_id::{DefId, DefIdMap};
-use syntax::ast::Ident;
-
-/// A per-trait graph of impls in specialization order. At the moment, this
-/// graph forms a tree rooted with the trait itself, with all other nodes
-/// representing impls, and parent-child relationships representing
-/// specializations.
-///
-/// The graph provides two key services:
-///
-/// - Construction. This implicitly checks for overlapping impls (i.e., impls
-///   that overlap but where neither specializes the other -- an artifact of the
-///   simple "chain" rule.
-///
-/// - Parent extraction. In particular, the graph can give you the *immediate*
-///   parents of a given specializing impl, which is needed for extracting
-///   default items amongst other things. In the simple "chain" rule, every impl
-///   has at most one parent.
-#[derive(RustcEncodable, RustcDecodable, HashStable)]
-pub struct Graph {
-    // All impls have a parent; the "root" impls have as their parent the `def_id`
-    // of the trait.
-    pub parent: DefIdMap<DefId>,
-
-    // The "root" impls are found by looking up the trait's def_id.
-    pub children: DefIdMap<Children>,
-}
-
-impl Graph {
-    pub fn new() -> Graph {
-        Graph { parent: Default::default(), children: Default::default() }
-    }
-
-    /// The parent of a given impl, which is the `DefId` of the trait when the
-    /// impl is a "specialization root".
-    pub fn parent(&self, child: DefId) -> DefId {
-        *self.parent.get(&child).unwrap_or_else(|| panic!("Failed to get parent for {:?}", child))
-    }
-}
-
-/// Children of a given impl, grouped into blanket/non-blanket varieties as is
-/// done in `TraitDef`.
-#[derive(Default, RustcEncodable, RustcDecodable)]
-pub struct Children {
-    // Impls of a trait (or specializations of a given impl). To allow for
-    // quicker lookup, the impls are indexed by a simplified version of their
-    // `Self` type: impls with a simplifiable `Self` are stored in
-    // `nonblanket_impls` keyed by it, while all other impls are stored in
-    // `blanket_impls`.
-    //
-    // A similar division is used within `TraitDef`, but the lists there collect
-    // together *all* the impls for a trait, and are populated prior to building
-    // the specialization graph.
-    /// Impls of the trait.
-    pub nonblanket_impls: FxHashMap<SimplifiedType, Vec<DefId>>,
-
-    /// Blanket impls associated with the trait.
-    pub blanket_impls: Vec<DefId>,
-}
-
-/// A node in the specialization graph is either an impl or a trait
-/// definition; either can serve as a source of item definitions.
-/// There is always exactly one trait definition node: the root.
-#[derive(Debug, Copy, Clone)]
-pub enum Node {
-    Impl(DefId),
-    Trait(DefId),
-}
-
-impl<'tcx> Node {
-    pub fn is_from_trait(&self) -> bool {
-        match *self {
-            Node::Trait(..) => true,
-            _ => false,
-        }
-    }
-
-    /// Iterate over the items defined directly by the given (impl or trait) node.
-    pub fn items(&self, tcx: TyCtxt<'tcx>) -> impl 'tcx + Iterator<Item = &'tcx ty::AssocItem> {
-        tcx.associated_items(self.def_id()).in_definition_order()
-    }
-
-    /// Finds an associated item defined in this node.
-    ///
-    /// If this returns `None`, the item can potentially still be found in
-    /// parents of this node.
-    pub fn item(
-        &self,
-        tcx: TyCtxt<'tcx>,
-        trait_item_name: Ident,
-        trait_item_kind: ty::AssocKind,
-        trait_def_id: DefId,
-    ) -> Option<ty::AssocItem> {
-        use crate::ty::AssocKind::*;
-
-        tcx.associated_items(self.def_id())
-            .filter_by_name_unhygienic(trait_item_name.name)
-            .find(move |impl_item| {
-                match (trait_item_kind, impl_item.kind) {
-                | (Const, Const)
-                | (Method, Method)
-                | (Type, Type)
-                | (Type, OpaqueTy)  // assoc. types can be made opaque in impls
-                => tcx.hygienic_eq(impl_item.ident, trait_item_name, trait_def_id),
-
-                | (Const, _)
-                | (Method, _)
-                | (Type, _)
-                | (OpaqueTy, _)
-                => false,
-            }
-            })
-            .copied()
-    }
-
-    pub fn def_id(&self) -> DefId {
-        match *self {
-            Node::Impl(did) => did,
-            Node::Trait(did) => did,
-        }
-    }
-}
-
-#[derive(Copy, Clone)]
-pub struct Ancestors<'tcx> {
-    trait_def_id: DefId,
-    specialization_graph: &'tcx Graph,
-    current_source: Option<Node>,
-}
-
-impl Iterator for Ancestors<'_> {
-    type Item = Node;
-    fn next(&mut self) -> Option<Node> {
-        let cur = self.current_source.take();
-        if let Some(Node::Impl(cur_impl)) = cur {
-            let parent = self.specialization_graph.parent(cur_impl);
-
-            self.current_source = if parent == self.trait_def_id {
-                Some(Node::Trait(parent))
-            } else {
-                Some(Node::Impl(parent))
-            };
-        }
-        cur
-    }
-}
-
-pub struct NodeItem<T> {
-    pub node: Node,
-    pub item: T,
-}
-
-impl<T> NodeItem<T> {
-    pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> NodeItem<U> {
-        NodeItem { node: self.node, item: f(self.item) }
-    }
-}
-
-impl<'tcx> Ancestors<'tcx> {
-    /// Finds the bottom-most (ie. most specialized) definition of an associated
-    /// item.
-    pub fn leaf_def(
-        mut self,
-        tcx: TyCtxt<'tcx>,
-        trait_item_name: Ident,
-        trait_item_kind: ty::AssocKind,
-    ) -> Option<NodeItem<ty::AssocItem>> {
-        let trait_def_id = self.trait_def_id;
-        self.find_map(|node| {
-            node.item(tcx, trait_item_name, trait_item_kind, trait_def_id)
-                .map(|item| NodeItem { node, item })
-        })
-    }
-}
-
-/// Walk up the specialization ancestors of a given impl, starting with that
-/// impl itself.
-pub fn ancestors(
-    tcx: TyCtxt<'tcx>,
-    trait_def_id: DefId,
-    start_from_impl: DefId,
-) -> Ancestors<'tcx> {
-    let specialization_graph = tcx.specialization_graph_of(trait_def_id);
-    Ancestors {
-        trait_def_id,
-        specialization_graph,
-        current_source: Some(Node::Impl(start_from_impl)),
-    }
-}
-
-impl<'a> HashStable<StableHashingContext<'a>> for Children {
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        let Children { ref nonblanket_impls, ref blanket_impls } = *self;
-
-        ich::hash_stable_trait_impls(hcx, hasher, blanket_impls, nonblanket_impls);
-    }
-}
diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs
deleted file mode 100644
index 48ed29f2bb3..00000000000
--- a/src/librustc/traits/structural_impls.rs
+++ /dev/null
@@ -1,712 +0,0 @@
-use crate::traits;
-use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
-use crate::ty::{self, Lift, Ty, TyCtxt};
-use rustc_span::symbol::Symbol;
-use smallvec::SmallVec;
-
-use std::collections::{BTreeMap, BTreeSet};
-use std::fmt;
-use std::rc::Rc;
-
-// Structural impls for the structs in `traits`.
-
-impl<'tcx, N: fmt::Debug> fmt::Debug for traits::Vtable<'tcx, N> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match *self {
-            super::VtableImpl(ref v) => write!(f, "{:?}", v),
-
-            super::VtableAutoImpl(ref t) => write!(f, "{:?}", t),
-
-            super::VtableClosure(ref d) => write!(f, "{:?}", d),
-
-            super::VtableGenerator(ref d) => write!(f, "{:?}", d),
-
-            super::VtableFnPointer(ref d) => write!(f, "VtableFnPointer({:?})", d),
-
-            super::VtableObject(ref d) => write!(f, "{:?}", d),
-
-            super::VtableParam(ref n) => write!(f, "VtableParam({:?})", n),
-
-            super::VtableBuiltin(ref d) => write!(f, "{:?}", d),
-
-            super::VtableTraitAlias(ref d) => write!(f, "{:?}", d),
-        }
-    }
-}
-
-impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableImplData<'tcx, N> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(
-            f,
-            "VtableImplData(impl_def_id={:?}, substs={:?}, nested={:?})",
-            self.impl_def_id, self.substs, self.nested
-        )
-    }
-}
-
-impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableGeneratorData<'tcx, N> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(
-            f,
-            "VtableGeneratorData(generator_def_id={:?}, substs={:?}, nested={:?})",
-            self.generator_def_id, self.substs, self.nested
-        )
-    }
-}
-
-impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableClosureData<'tcx, N> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(
-            f,
-            "VtableClosureData(closure_def_id={:?}, substs={:?}, nested={:?})",
-            self.closure_def_id, self.substs, self.nested
-        )
-    }
-}
-
-impl<N: fmt::Debug> fmt::Debug for traits::VtableBuiltinData<N> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "VtableBuiltinData(nested={:?})", self.nested)
-    }
-}
-
-impl<N: fmt::Debug> fmt::Debug for traits::VtableAutoImplData<N> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(
-            f,
-            "VtableAutoImplData(trait_def_id={:?}, nested={:?})",
-            self.trait_def_id, self.nested
-        )
-    }
-}
-
-impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableObjectData<'tcx, N> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(
-            f,
-            "VtableObjectData(upcast={:?}, vtable_base={}, nested={:?})",
-            self.upcast_trait_ref, self.vtable_base, self.nested
-        )
-    }
-}
-
-impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableFnPointerData<'tcx, N> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "VtableFnPointerData(fn_ty={:?}, nested={:?})", self.fn_ty, self.nested)
-    }
-}
-
-impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableTraitAliasData<'tcx, N> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(
-            f,
-            "VtableTraitAlias(alias_def_id={:?}, substs={:?}, nested={:?})",
-            self.alias_def_id, self.substs, self.nested
-        )
-    }
-}
-
-impl<'tcx> fmt::Display for traits::WhereClause<'tcx> {
-    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-        use crate::traits::WhereClause::*;
-
-        // Bypass `ty::print` because it does not print out anonymous regions.
-        // FIXME(eddyb) implement a custom `PrettyPrinter`, or move this to `ty::print`.
-        fn write_region_name<'tcx>(
-            r: ty::Region<'tcx>,
-            fmt: &mut fmt::Formatter<'_>,
-        ) -> fmt::Result {
-            match r {
-                ty::ReLateBound(index, br) => match br {
-                    ty::BoundRegion::BrNamed(_, name) => write!(fmt, "{}", name),
-                    ty::BoundRegion::BrAnon(var) => {
-                        if *index == ty::INNERMOST {
-                            write!(fmt, "'^{}", var)
-                        } else {
-                            write!(fmt, "'^{}_{}", index.index(), var)
-                        }
-                    }
-                    _ => write!(fmt, "'_"),
-                },
-
-                _ => write!(fmt, "{}", r),
-            }
-        }
-
-        match self {
-            Implemented(trait_ref) => write!(fmt, "Implemented({})", trait_ref),
-            ProjectionEq(projection) => write!(fmt, "ProjectionEq({})", projection),
-            RegionOutlives(predicate) => {
-                write!(fmt, "RegionOutlives({}: ", predicate.0)?;
-                write_region_name(predicate.1, fmt)?;
-                write!(fmt, ")")
-            }
-            TypeOutlives(predicate) => {
-                write!(fmt, "TypeOutlives({}: ", predicate.0)?;
-                write_region_name(predicate.1, fmt)?;
-                write!(fmt, ")")
-            }
-        }
-    }
-}
-
-impl<'tcx> fmt::Display for traits::WellFormed<'tcx> {
-    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-        use crate::traits::WellFormed::*;
-
-        match self {
-            Trait(trait_ref) => write!(fmt, "WellFormed({})", trait_ref),
-            Ty(ty) => write!(fmt, "WellFormed({})", ty),
-        }
-    }
-}
-
-impl<'tcx> fmt::Display for traits::FromEnv<'tcx> {
-    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-        use crate::traits::FromEnv::*;
-
-        match self {
-            Trait(trait_ref) => write!(fmt, "FromEnv({})", trait_ref),
-            Ty(ty) => write!(fmt, "FromEnv({})", ty),
-        }
-    }
-}
-
-impl<'tcx> fmt::Display for traits::DomainGoal<'tcx> {
-    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-        use crate::traits::DomainGoal::*;
-
-        match self {
-            Holds(wc) => write!(fmt, "{}", wc),
-            WellFormed(wf) => write!(fmt, "{}", wf),
-            FromEnv(from_env) => write!(fmt, "{}", from_env),
-            Normalize(projection) => {
-                write!(fmt, "Normalize({} -> {})", projection.projection_ty, projection.ty)
-            }
-        }
-    }
-}
-
-impl fmt::Display for traits::QuantifierKind {
-    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-        use crate::traits::QuantifierKind::*;
-
-        match self {
-            Universal => write!(fmt, "forall"),
-            Existential => write!(fmt, "exists"),
-        }
-    }
-}
-
-/// Collect names for regions / types bound by a quantified goal / clause.
-/// This collector does not try to do anything clever like in `ty::print`, it's just used
-/// for debug output in tests anyway.
-struct BoundNamesCollector {
-    // Just sort by name because `BoundRegion::BrNamed` does not have a `BoundVar` index anyway.
-    regions: BTreeSet<Symbol>,
-
-    // Sort by `BoundVar` index, so usually this should be equivalent to the order given
-    // by the list of type parameters.
-    types: BTreeMap<u32, Symbol>,
-
-    binder_index: ty::DebruijnIndex,
-}
-
-impl BoundNamesCollector {
-    fn new() -> Self {
-        BoundNamesCollector {
-            regions: BTreeSet::new(),
-            types: BTreeMap::new(),
-            binder_index: ty::INNERMOST,
-        }
-    }
-
-    fn is_empty(&self) -> bool {
-        self.regions.is_empty() && self.types.is_empty()
-    }
-
-    fn write_names(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-        let mut start = true;
-        for r in &self.regions {
-            if !start {
-                write!(fmt, ", ")?;
-            }
-            start = false;
-            write!(fmt, "{}", r)?;
-        }
-        for (_, t) in &self.types {
-            if !start {
-                write!(fmt, ", ")?;
-            }
-            start = false;
-            write!(fmt, "{}", t)?;
-        }
-        Ok(())
-    }
-}
-
-impl<'tcx> TypeVisitor<'tcx> for BoundNamesCollector {
-    fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, t: &ty::Binder<T>) -> bool {
-        self.binder_index.shift_in(1);
-        let result = t.super_visit_with(self);
-        self.binder_index.shift_out(1);
-        result
-    }
-
-    fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
-        match t.kind {
-            ty::Bound(debruijn, bound_ty) if debruijn == self.binder_index => {
-                self.types.insert(
-                    bound_ty.var.as_u32(),
-                    match bound_ty.kind {
-                        ty::BoundTyKind::Param(name) => name,
-                        ty::BoundTyKind::Anon => {
-                            Symbol::intern(&format!("^{}", bound_ty.var.as_u32()))
-                        }
-                    },
-                );
-            }
-
-            _ => (),
-        };
-
-        t.super_visit_with(self)
-    }
-
-    fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
-        match r {
-            ty::ReLateBound(index, br) if *index == self.binder_index => match br {
-                ty::BoundRegion::BrNamed(_, name) => {
-                    self.regions.insert(*name);
-                }
-
-                ty::BoundRegion::BrAnon(var) => {
-                    self.regions.insert(Symbol::intern(&format!("'^{}", var)));
-                }
-
-                _ => (),
-            },
-
-            _ => (),
-        };
-
-        r.super_visit_with(self)
-    }
-}
-
-impl<'tcx> fmt::Display for traits::Goal<'tcx> {
-    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-        use crate::traits::GoalKind::*;
-
-        match self {
-            Implies(hypotheses, goal) => {
-                write!(fmt, "if (")?;
-                for (index, hyp) in hypotheses.iter().enumerate() {
-                    if index > 0 {
-                        write!(fmt, ", ")?;
-                    }
-                    write!(fmt, "{}", hyp)?;
-                }
-                write!(fmt, ") {{ {} }}", goal)
-            }
-            And(goal1, goal2) => write!(fmt, "({} && {})", goal1, goal2),
-            Not(goal) => write!(fmt, "not {{ {} }}", goal),
-            DomainGoal(goal) => write!(fmt, "{}", goal),
-            Quantified(qkind, goal) => {
-                let mut collector = BoundNamesCollector::new();
-                goal.skip_binder().visit_with(&mut collector);
-
-                if !collector.is_empty() {
-                    write!(fmt, "{}<", qkind)?;
-                    collector.write_names(fmt)?;
-                    write!(fmt, "> {{ ")?;
-                }
-
-                write!(fmt, "{}", goal.skip_binder())?;
-
-                if !collector.is_empty() {
-                    write!(fmt, " }}")?;
-                }
-
-                Ok(())
-            }
-            Subtype(a, b) => write!(fmt, "{} <: {}", a, b),
-            CannotProve => write!(fmt, "CannotProve"),
-        }
-    }
-}
-
-impl<'tcx> fmt::Display for traits::ProgramClause<'tcx> {
-    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-        let traits::ProgramClause { goal, hypotheses, .. } = self;
-        write!(fmt, "{}", goal)?;
-        if !hypotheses.is_empty() {
-            write!(fmt, " :- ")?;
-            for (index, condition) in hypotheses.iter().enumerate() {
-                if index > 0 {
-                    write!(fmt, ", ")?;
-                }
-                write!(fmt, "{}", condition)?;
-            }
-        }
-        write!(fmt, ".")
-    }
-}
-
-impl<'tcx> fmt::Display for traits::Clause<'tcx> {
-    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-        use crate::traits::Clause::*;
-
-        match self {
-            Implies(clause) => write!(fmt, "{}", clause),
-            ForAll(clause) => {
-                let mut collector = BoundNamesCollector::new();
-                clause.skip_binder().visit_with(&mut collector);
-
-                if !collector.is_empty() {
-                    write!(fmt, "forall<")?;
-                    collector.write_names(fmt)?;
-                    write!(fmt, "> {{ ")?;
-                }
-
-                write!(fmt, "{}", clause.skip_binder())?;
-
-                if !collector.is_empty() {
-                    write!(fmt, " }}")?;
-                }
-
-                Ok(())
-            }
-        }
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////
-// Lift implementations
-
-impl<'a, 'tcx> Lift<'tcx> for traits::SelectionError<'a> {
-    type Lifted = traits::SelectionError<'tcx>;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        match *self {
-            super::Unimplemented => Some(super::Unimplemented),
-            super::OutputTypeParameterMismatch(a, b, ref err) => {
-                tcx.lift(&(a, b)).and_then(|(a, b)| {
-                    tcx.lift(err).map(|err| super::OutputTypeParameterMismatch(a, b, err))
-                })
-            }
-            super::TraitNotObjectSafe(def_id) => Some(super::TraitNotObjectSafe(def_id)),
-            super::ConstEvalFailure(err) => Some(super::ConstEvalFailure(err)),
-            super::Overflow => Some(super::Overflow),
-        }
-    }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> {
-    type Lifted = traits::ObligationCauseCode<'tcx>;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        match *self {
-            super::ReturnNoExpression => Some(super::ReturnNoExpression),
-            super::MiscObligation => Some(super::MiscObligation),
-            super::SliceOrArrayElem => Some(super::SliceOrArrayElem),
-            super::TupleElem => Some(super::TupleElem),
-            super::ProjectionWf(proj) => tcx.lift(&proj).map(super::ProjectionWf),
-            super::ItemObligation(def_id) => Some(super::ItemObligation(def_id)),
-            super::BindingObligation(def_id, span) => Some(super::BindingObligation(def_id, span)),
-            super::ReferenceOutlivesReferent(ty) => {
-                tcx.lift(&ty).map(super::ReferenceOutlivesReferent)
-            }
-            super::ObjectTypeBound(ty, r) => tcx
-                .lift(&ty)
-                .and_then(|ty| tcx.lift(&r).and_then(|r| Some(super::ObjectTypeBound(ty, r)))),
-            super::ObjectCastObligation(ty) => tcx.lift(&ty).map(super::ObjectCastObligation),
-            super::Coercion { source, target } => {
-                Some(super::Coercion { source: tcx.lift(&source)?, target: tcx.lift(&target)? })
-            }
-            super::AssignmentLhsSized => Some(super::AssignmentLhsSized),
-            super::TupleInitializerSized => Some(super::TupleInitializerSized),
-            super::StructInitializerSized => Some(super::StructInitializerSized),
-            super::VariableType(id) => Some(super::VariableType(id)),
-            super::ReturnValue(id) => Some(super::ReturnValue(id)),
-            super::ReturnType => Some(super::ReturnType),
-            super::SizedArgumentType => Some(super::SizedArgumentType),
-            super::SizedReturnType => Some(super::SizedReturnType),
-            super::SizedYieldType => Some(super::SizedYieldType),
-            super::RepeatVec(suggest_flag) => Some(super::RepeatVec(suggest_flag)),
-            super::FieldSized { adt_kind, last } => Some(super::FieldSized { adt_kind, last }),
-            super::ConstSized => Some(super::ConstSized),
-            super::ConstPatternStructural => Some(super::ConstPatternStructural),
-            super::SharedStatic => Some(super::SharedStatic),
-            super::BuiltinDerivedObligation(ref cause) => {
-                tcx.lift(cause).map(super::BuiltinDerivedObligation)
-            }
-            super::ImplDerivedObligation(ref cause) => {
-                tcx.lift(cause).map(super::ImplDerivedObligation)
-            }
-            super::CompareImplMethodObligation {
-                item_name,
-                impl_item_def_id,
-                trait_item_def_id,
-            } => Some(super::CompareImplMethodObligation {
-                item_name,
-                impl_item_def_id,
-                trait_item_def_id,
-            }),
-            super::CompareImplTypeObligation { item_name, impl_item_def_id, trait_item_def_id } => {
-                Some(super::CompareImplTypeObligation {
-                    item_name,
-                    impl_item_def_id,
-                    trait_item_def_id,
-                })
-            }
-            super::ExprAssignable => Some(super::ExprAssignable),
-            super::MatchExpressionArm(box super::MatchExpressionArmCause {
-                arm_span,
-                source,
-                ref prior_arms,
-                last_ty,
-                scrut_hir_id,
-            }) => tcx.lift(&last_ty).map(|last_ty| {
-                super::MatchExpressionArm(box super::MatchExpressionArmCause {
-                    arm_span,
-                    source,
-                    prior_arms: prior_arms.clone(),
-                    last_ty,
-                    scrut_hir_id,
-                })
-            }),
-            super::Pattern { span, root_ty, origin_expr } => {
-                tcx.lift(&root_ty).map(|root_ty| super::Pattern { span, root_ty, origin_expr })
-            }
-            super::IfExpression(box super::IfExpressionCause { then, outer, semicolon }) => {
-                Some(super::IfExpression(box super::IfExpressionCause { then, outer, semicolon }))
-            }
-            super::IfExpressionWithNoElse => Some(super::IfExpressionWithNoElse),
-            super::MainFunctionType => Some(super::MainFunctionType),
-            super::StartFunctionType => Some(super::StartFunctionType),
-            super::IntrinsicType => Some(super::IntrinsicType),
-            super::MethodReceiver => Some(super::MethodReceiver),
-            super::BlockTailExpression(id) => Some(super::BlockTailExpression(id)),
-            super::TrivialBound => Some(super::TrivialBound),
-            super::AssocTypeBound(ref data) => Some(super::AssocTypeBound(data.clone())),
-        }
-    }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for traits::DerivedObligationCause<'a> {
-    type Lifted = traits::DerivedObligationCause<'tcx>;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        tcx.lift(&self.parent_trait_ref).and_then(|trait_ref| {
-            tcx.lift(&*self.parent_code).map(|code| traits::DerivedObligationCause {
-                parent_trait_ref: trait_ref,
-                parent_code: Rc::new(code),
-            })
-        })
-    }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCause<'a> {
-    type Lifted = traits::ObligationCause<'tcx>;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        tcx.lift(&self.code).map(|code| traits::ObligationCause {
-            span: self.span,
-            body_id: self.body_id,
-            code,
-        })
-    }
-}
-
-// For codegen only.
-impl<'a, 'tcx> Lift<'tcx> for traits::Vtable<'a, ()> {
-    type Lifted = traits::Vtable<'tcx, ()>;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        match self.clone() {
-            traits::VtableImpl(traits::VtableImplData { impl_def_id, substs, nested }) => {
-                tcx.lift(&substs).map(|substs| {
-                    traits::VtableImpl(traits::VtableImplData { impl_def_id, substs, nested })
-                })
-            }
-            traits::VtableAutoImpl(t) => Some(traits::VtableAutoImpl(t)),
-            traits::VtableGenerator(traits::VtableGeneratorData {
-                generator_def_id,
-                substs,
-                nested,
-            }) => tcx.lift(&substs).map(|substs| {
-                traits::VtableGenerator(traits::VtableGeneratorData {
-                    generator_def_id: generator_def_id,
-                    substs: substs,
-                    nested: nested,
-                })
-            }),
-            traits::VtableClosure(traits::VtableClosureData { closure_def_id, substs, nested }) => {
-                tcx.lift(&substs).map(|substs| {
-                    traits::VtableClosure(traits::VtableClosureData {
-                        closure_def_id,
-                        substs,
-                        nested,
-                    })
-                })
-            }
-            traits::VtableFnPointer(traits::VtableFnPointerData { fn_ty, nested }) => {
-                tcx.lift(&fn_ty).map(|fn_ty| {
-                    traits::VtableFnPointer(traits::VtableFnPointerData { fn_ty, nested })
-                })
-            }
-            traits::VtableParam(n) => Some(traits::VtableParam(n)),
-            traits::VtableBuiltin(n) => Some(traits::VtableBuiltin(n)),
-            traits::VtableObject(traits::VtableObjectData {
-                upcast_trait_ref,
-                vtable_base,
-                nested,
-            }) => tcx.lift(&upcast_trait_ref).map(|trait_ref| {
-                traits::VtableObject(traits::VtableObjectData {
-                    upcast_trait_ref: trait_ref,
-                    vtable_base,
-                    nested,
-                })
-            }),
-            traits::VtableTraitAlias(traits::VtableTraitAliasData {
-                alias_def_id,
-                substs,
-                nested,
-            }) => tcx.lift(&substs).map(|substs| {
-                traits::VtableTraitAlias(traits::VtableTraitAliasData {
-                    alias_def_id,
-                    substs,
-                    nested,
-                })
-            }),
-        }
-    }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for traits::Environment<'a> {
-    type Lifted = traits::Environment<'tcx>;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        tcx.lift(&self.clauses).map(|clauses| traits::Environment { clauses })
-    }
-}
-
-impl<'a, 'tcx, G: Lift<'tcx>> Lift<'tcx> for traits::InEnvironment<'a, G> {
-    type Lifted = traits::InEnvironment<'tcx, G::Lifted>;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        tcx.lift(&self.environment).and_then(|environment| {
-            tcx.lift(&self.goal).map(|goal| traits::InEnvironment { environment, goal })
-        })
-    }
-}
-
-impl<'tcx, C> Lift<'tcx> for chalk_engine::ExClause<C>
-where
-    C: chalk_engine::context::Context + Clone,
-    C: traits::ChalkContextLift<'tcx>,
-{
-    type Lifted = C::LiftedExClause;
-
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        <C as traits::ChalkContextLift>::lift_ex_clause_to_tcx(self, tcx)
-    }
-}
-
-impl<'tcx, C> Lift<'tcx> for chalk_engine::DelayedLiteral<C>
-where
-    C: chalk_engine::context::Context + Clone,
-    C: traits::ChalkContextLift<'tcx>,
-{
-    type Lifted = C::LiftedDelayedLiteral;
-
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        <C as traits::ChalkContextLift>::lift_delayed_literal_to_tcx(self, tcx)
-    }
-}
-
-impl<'tcx, C> Lift<'tcx> for chalk_engine::Literal<C>
-where
-    C: chalk_engine::context::Context + Clone,
-    C: traits::ChalkContextLift<'tcx>,
-{
-    type Lifted = C::LiftedLiteral;
-
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        <C as traits::ChalkContextLift>::lift_literal_to_tcx(self, tcx)
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////
-// TypeFoldable implementations.
-
-CloneTypeFoldableAndLiftImpls! {
-    traits::QuantifierKind,
-}
-
-impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<traits::Goal<'tcx>> {
-    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
-        let v = self.iter().map(|t| t.fold_with(folder)).collect::<SmallVec<[_; 8]>>();
-        folder.tcx().intern_goals(&v)
-    }
-
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
-        self.iter().any(|t| t.visit_with(visitor))
-    }
-}
-
-impl<'tcx> TypeFoldable<'tcx> for traits::Goal<'tcx> {
-    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
-        let v = (**self).fold_with(folder);
-        folder.tcx().mk_goal(v)
-    }
-
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
-        (**self).visit_with(visitor)
-    }
-}
-
-CloneTypeFoldableAndLiftImpls! {
-    traits::ProgramClauseCategory,
-}
-
-impl<'tcx> TypeFoldable<'tcx> for traits::Clauses<'tcx> {
-    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
-        let v = self.iter().map(|t| t.fold_with(folder)).collect::<SmallVec<[_; 8]>>();
-        folder.tcx().intern_clauses(&v)
-    }
-
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
-        self.iter().any(|t| t.visit_with(visitor))
-    }
-}
-
-impl<'tcx, C> TypeFoldable<'tcx> for chalk_engine::ExClause<C>
-where
-    C: traits::ExClauseFold<'tcx>,
-    C::Substitution: Clone,
-    C::RegionConstraint: Clone,
-{
-    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
-        <C as traits::ExClauseFold>::fold_ex_clause_with(self, folder)
-    }
-
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
-        <C as traits::ExClauseFold>::visit_ex_clause_with(self, visitor)
-    }
-}
-
-EnumTypeFoldableImpl! {
-    impl<'tcx, C> TypeFoldable<'tcx> for chalk_engine::DelayedLiteral<C> {
-        (chalk_engine::DelayedLiteral::CannotProve)(a),
-        (chalk_engine::DelayedLiteral::Negative)(a),
-        (chalk_engine::DelayedLiteral::Positive)(a, b),
-    } where
-        C: chalk_engine::context::Context<CanonicalConstrainedSubst: TypeFoldable<'tcx>> + Clone,
-}
-
-EnumTypeFoldableImpl! {
-    impl<'tcx, C> TypeFoldable<'tcx> for chalk_engine::Literal<C> {
-        (chalk_engine::Literal::Negative)(a),
-        (chalk_engine::Literal::Positive)(a),
-    } where
-        C: chalk_engine::context::Context<GoalInEnvironment: Clone + TypeFoldable<'tcx>> + Clone,
-}
-
-CloneTypeFoldableAndLiftImpls! {
-    chalk_engine::TableIndex,
-}
diff --git a/src/librustc/ty/_match.rs b/src/librustc/ty/_match.rs
deleted file mode 100644
index 35f8eb20475..00000000000
--- a/src/librustc/ty/_match.rs
+++ /dev/null
@@ -1,120 +0,0 @@
-use crate::ty::error::TypeError;
-use crate::ty::relate::{self, Relate, RelateResult, TypeRelation};
-use crate::ty::{self, InferConst, Ty, TyCtxt};
-
-/// A type "A" *matches* "B" if the fresh types in B could be
-/// substituted with values so as to make it equal to A. Matching is
-/// intended to be used only on freshened types, and it basically
-/// indicates if the non-freshened versions of A and B could have been
-/// unified.
-///
-/// It is only an approximation. If it yields false, unification would
-/// definitely fail, but a true result doesn't mean unification would
-/// succeed. This is because we don't track the "side-constraints" on
-/// type variables, nor do we track if the same freshened type appears
-/// more than once. To some extent these approximations could be
-/// fixed, given effort.
-///
-/// Like subtyping, matching is really a binary relation, so the only
-/// important thing about the result is Ok/Err. Also, matching never
-/// affects any type variables or unification state.
-pub struct Match<'tcx> {
-    tcx: TyCtxt<'tcx>,
-    param_env: ty::ParamEnv<'tcx>,
-}
-
-impl Match<'tcx> {
-    pub fn new(tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Match<'tcx> {
-        Match { tcx, param_env }
-    }
-}
-
-impl TypeRelation<'tcx> for Match<'tcx> {
-    fn tag(&self) -> &'static str {
-        "Match"
-    }
-    fn tcx(&self) -> TyCtxt<'tcx> {
-        self.tcx
-    }
-    fn param_env(&self) -> ty::ParamEnv<'tcx> {
-        self.param_env
-    }
-    fn a_is_expected(&self) -> bool {
-        true
-    } // irrelevant
-
-    fn relate_with_variance<T: Relate<'tcx>>(
-        &mut self,
-        _: ty::Variance,
-        a: &T,
-        b: &T,
-    ) -> RelateResult<'tcx, T> {
-        self.relate(a, b)
-    }
-
-    fn regions(
-        &mut self,
-        a: ty::Region<'tcx>,
-        b: ty::Region<'tcx>,
-    ) -> RelateResult<'tcx, ty::Region<'tcx>> {
-        debug!("{}.regions({:?}, {:?})", self.tag(), a, b);
-        Ok(a)
-    }
-
-    fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
-        debug!("{}.tys({:?}, {:?})", self.tag(), a, b);
-        if a == b {
-            return Ok(a);
-        }
-
-        match (&a.kind, &b.kind) {
-            (_, &ty::Infer(ty::FreshTy(_)))
-            | (_, &ty::Infer(ty::FreshIntTy(_)))
-            | (_, &ty::Infer(ty::FreshFloatTy(_))) => Ok(a),
-
-            (&ty::Infer(_), _) | (_, &ty::Infer(_)) => {
-                Err(TypeError::Sorts(relate::expected_found(self, &a, &b)))
-            }
-
-            (&ty::Error, _) | (_, &ty::Error) => Ok(self.tcx().types.err),
-
-            _ => relate::super_relate_tys(self, a, b),
-        }
-    }
-
-    fn consts(
-        &mut self,
-        a: &'tcx ty::Const<'tcx>,
-        b: &'tcx ty::Const<'tcx>,
-    ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
-        debug!("{}.consts({:?}, {:?})", self.tag(), a, b);
-        if a == b {
-            return Ok(a);
-        }
-
-        match (a.val, b.val) {
-            (_, ty::ConstKind::Infer(InferConst::Fresh(_))) => {
-                return Ok(a);
-            }
-
-            (ty::ConstKind::Infer(_), _) | (_, ty::ConstKind::Infer(_)) => {
-                return Err(TypeError::ConstMismatch(relate::expected_found(self, &a, &b)));
-            }
-
-            _ => {}
-        }
-
-        relate::super_relate_consts(self, a, b)
-    }
-
-    fn binders<T>(
-        &mut self,
-        a: &ty::Binder<T>,
-        b: &ty::Binder<T>,
-    ) -> RelateResult<'tcx, ty::Binder<T>>
-    where
-        T: Relate<'tcx>,
-    {
-        Ok(ty::Binder::bind(self.relate(a.skip_binder(), b.skip_binder())?))
-    }
-}
diff --git a/src/librustc/ty/adjustment.rs b/src/librustc/ty/adjustment.rs
deleted file mode 100644
index 851bffc2065..00000000000
--- a/src/librustc/ty/adjustment.rs
+++ /dev/null
@@ -1,194 +0,0 @@
-use crate::ty::subst::SubstsRef;
-use crate::ty::{self, Ty, TyCtxt};
-use rustc_hir as hir;
-use rustc_hir::def_id::DefId;
-use rustc_macros::HashStable;
-
-#[derive(Clone, Copy, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
-pub enum PointerCast {
-    /// Go from a fn-item type to a fn-pointer type.
-    ReifyFnPointer,
-
-    /// Go from a safe fn pointer to an unsafe fn pointer.
-    UnsafeFnPointer,
-
-    /// Go from a non-capturing closure to an fn pointer or an unsafe fn pointer.
-    /// It cannot convert a closure that requires unsafe.
-    ClosureFnPointer(hir::Unsafety),
-
-    /// Go from a mut raw pointer to a const raw pointer.
-    MutToConstPointer,
-
-    /// Go from `*const [T; N]` to `*const T`
-    ArrayToPointer,
-
-    /// Unsize a pointer/reference value, e.g., `&[T; n]` to
-    /// `&[T]`. Note that the source could be a thin or fat pointer.
-    /// This will do things like convert thin pointers to fat
-    /// pointers, or convert structs containing thin pointers to
-    /// structs containing fat pointers, or convert between fat
-    /// pointers. We don't store the details of how the transform is
-    /// done (in fact, we don't know that, because it might depend on
-    /// the precise type parameters). We just store the target
-    /// type. Codegen backends and miri figure out what has to be done
-    /// based on the precise source/target type at hand.
-    Unsize,
-}
-
-/// Represents coercing a value to a different type of value.
-///
-/// We transform values by following a number of `Adjust` steps in order.
-/// See the documentation on variants of `Adjust` for more details.
-///
-/// Here are some common scenarios:
-///
-/// 1. The simplest cases are where a pointer is not adjusted fat vs thin.
-///    Here the pointer will be dereferenced N times (where a dereference can
-///    happen to raw or borrowed pointers or any smart pointer which implements
-///    Deref, including Box<_>). The types of dereferences is given by
-///    `autoderefs`. It can then be auto-referenced zero or one times, indicated
-///    by `autoref`, to either a raw or borrowed pointer. In these cases unsize is
-///    `false`.
-///
-/// 2. A thin-to-fat coercion involves unsizing the underlying data. We start
-///    with a thin pointer, deref a number of times, unsize the underlying data,
-///    then autoref. The 'unsize' phase may change a fixed length array to a
-///    dynamically sized one, a concrete object to a trait object, or statically
-///    sized struct to a dynamically sized one. E.g., &[i32; 4] -> &[i32] is
-///    represented by:
-///
-///    ```
-///    Deref(None) -> [i32; 4],
-///    Borrow(AutoBorrow::Ref) -> &[i32; 4],
-///    Unsize -> &[i32],
-///    ```
-///
-///    Note that for a struct, the 'deep' unsizing of the struct is not recorded.
-///    E.g., `struct Foo<T> { x: T }` we can coerce &Foo<[i32; 4]> to &Foo<[i32]>
-///    The autoderef and -ref are the same as in the above example, but the type
-///    stored in `unsize` is `Foo<[i32]>`, we don't store any further detail about
-///    the underlying conversions from `[i32; 4]` to `[i32]`.
-///
-/// 3. Coercing a `Box<T>` to `Box<dyn Trait>` is an interesting special case. In
-///    that case, we have the pointer we need coming in, so there are no
-///    autoderefs, and no autoref. Instead we just do the `Unsize` transformation.
-///    At some point, of course, `Box` should move out of the compiler, in which
-///    case this is analogous to transforming a struct. E.g., Box<[i32; 4]> ->
-///    Box<[i32]> is an `Adjust::Unsize` with the target `Box<[i32]>`.
-#[derive(Clone, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
-pub struct Adjustment<'tcx> {
-    pub kind: Adjust<'tcx>,
-    pub target: Ty<'tcx>,
-}
-
-impl Adjustment<'tcx> {
-    pub fn is_region_borrow(&self) -> bool {
-        match self.kind {
-            Adjust::Borrow(AutoBorrow::Ref(..)) => true,
-            _ => false,
-        }
-    }
-}
-
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
-pub enum Adjust<'tcx> {
-    /// Go from ! to any type.
-    NeverToAny,
-
-    /// Dereference once, producing a place.
-    Deref(Option<OverloadedDeref<'tcx>>),
-
-    /// Take the address and produce either a `&` or `*` pointer.
-    Borrow(AutoBorrow<'tcx>),
-
-    Pointer(PointerCast),
-}
-
-/// An overloaded autoderef step, representing a `Deref(Mut)::deref(_mut)`
-/// call, with the signature `&'a T -> &'a U` or `&'a mut T -> &'a mut U`.
-/// The target type is `U` in both cases, with the region and mutability
-/// being those shared by both the receiver and the returned reference.
-#[derive(Copy, Clone, PartialEq, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
-pub struct OverloadedDeref<'tcx> {
-    pub region: ty::Region<'tcx>,
-    pub mutbl: hir::Mutability,
-}
-
-impl<'tcx> OverloadedDeref<'tcx> {
-    pub fn method_call(&self, tcx: TyCtxt<'tcx>, source: Ty<'tcx>) -> (DefId, SubstsRef<'tcx>) {
-        let trait_def_id = match self.mutbl {
-            hir::Mutability::Not => tcx.lang_items().deref_trait(),
-            hir::Mutability::Mut => tcx.lang_items().deref_mut_trait(),
-        };
-        let method_def_id = tcx
-            .associated_items(trait_def_id.unwrap())
-            .in_definition_order()
-            .find(|m| m.kind == ty::AssocKind::Method)
-            .unwrap()
-            .def_id;
-        (method_def_id, tcx.mk_substs_trait(source, &[]))
-    }
-}
-
-/// At least for initial deployment, we want to limit two-phase borrows to
-/// only a few specific cases. Right now, those are mostly "things that desugar"
-/// into method calls:
-/// - using `x.some_method()` syntax, where some_method takes `&mut self`,
-/// - using `Foo::some_method(&mut x, ...)` syntax,
-/// - binary assignment operators (`+=`, `-=`, `*=`, etc.).
-/// Anything else should be rejected until generalized two-phase borrow support
-/// is implemented. Right now, dataflow can't handle the general case where there
-/// is more than one use of a mutable borrow, and we don't want to accept too much
-/// new code via two-phase borrows, so we try to limit where we create two-phase
-/// capable mutable borrows.
-/// See #49434 for tracking.
-#[derive(Copy, Clone, PartialEq, Debug, RustcEncodable, RustcDecodable, HashStable)]
-pub enum AllowTwoPhase {
-    Yes,
-    No,
-}
-
-#[derive(Copy, Clone, PartialEq, Debug, RustcEncodable, RustcDecodable, HashStable)]
-pub enum AutoBorrowMutability {
-    Mut { allow_two_phase_borrow: AllowTwoPhase },
-    Not,
-}
-
-impl From<AutoBorrowMutability> for hir::Mutability {
-    fn from(m: AutoBorrowMutability) -> Self {
-        match m {
-            AutoBorrowMutability::Mut { .. } => hir::Mutability::Mut,
-            AutoBorrowMutability::Not => hir::Mutability::Not,
-        }
-    }
-}
-
-#[derive(Copy, Clone, PartialEq, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
-pub enum AutoBorrow<'tcx> {
-    /// Converts from T to &T.
-    Ref(ty::Region<'tcx>, AutoBorrowMutability),
-
-    /// Converts from T to *T.
-    RawPtr(hir::Mutability),
-}
-
-/// Information for `CoerceUnsized` impls, storing information we
-/// have computed about the coercion.
-///
-/// This struct can be obtained via the `coerce_impl_info` query.
-/// Demanding this struct also has the side-effect of reporting errors
-/// for inappropriate impls.
-#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, HashStable)]
-pub struct CoerceUnsizedInfo {
-    /// If this is a "custom coerce" impl, then what kind of custom
-    /// coercion is it? This applies to impls of `CoerceUnsized` for
-    /// structs, primarily, where we store a bit of info about which
-    /// fields need to be coerced.
-    pub custom_kind: Option<CustomCoerceUnsized>,
-}
-
-#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, HashStable)]
-pub enum CustomCoerceUnsized {
-    /// Records the index of the field being coerced.
-    Struct(usize),
-}
diff --git a/src/librustc/ty/binding.rs b/src/librustc/ty/binding.rs
deleted file mode 100644
index 5ee88115090..00000000000
--- a/src/librustc/ty/binding.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-use rustc_hir::BindingAnnotation;
-use rustc_hir::BindingAnnotation::*;
-use rustc_hir::Mutability;
-
-#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy, HashStable)]
-pub enum BindingMode {
-    BindByReference(Mutability),
-    BindByValue(Mutability),
-}
-
-CloneTypeFoldableAndLiftImpls! { BindingMode, }
-
-impl BindingMode {
-    pub fn convert(ba: BindingAnnotation) -> BindingMode {
-        match ba {
-            Unannotated => BindingMode::BindByValue(Mutability::Not),
-            Mutable => BindingMode::BindByValue(Mutability::Mut),
-            Ref => BindingMode::BindByReference(Mutability::Not),
-            RefMut => BindingMode::BindByReference(Mutability::Mut),
-        }
-    }
-}
diff --git a/src/librustc/ty/cast.rs b/src/librustc/ty/cast.rs
deleted file mode 100644
index 5ba3f80b822..00000000000
--- a/src/librustc/ty/cast.rs
+++ /dev/null
@@ -1,67 +0,0 @@
-// Helpers for handling cast expressions, used in both
-// typeck and codegen.
-
-use crate::ty::{self, Ty};
-
-use rustc_macros::HashStable;
-use syntax::ast;
-
-/// Types that are represented as ints.
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
-pub enum IntTy {
-    U(ast::UintTy),
-    I,
-    CEnum,
-    Bool,
-    Char,
-}
-
-// Valid types for the result of a non-coercion cast
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
-pub enum CastTy<'tcx> {
-    /// Various types that are represented as ints and handled mostly
-    /// in the same way, merged for easier matching.
-    Int(IntTy),
-    /// Floating-Point types
-    Float,
-    /// Function Pointers
-    FnPtr,
-    /// Raw pointers
-    Ptr(ty::TypeAndMut<'tcx>),
-}
-
-/// Cast Kind. See RFC 401 (or librustc_typeck/check/cast.rs)
-#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
-pub enum CastKind {
-    CoercionCast,
-    PtrPtrCast,
-    PtrAddrCast,
-    AddrPtrCast,
-    NumericCast,
-    EnumCast,
-    PrimIntCast,
-    U8CharCast,
-    ArrayPtrCast,
-    FnPtrPtrCast,
-    FnPtrAddrCast,
-}
-
-impl<'tcx> CastTy<'tcx> {
-    /// Returns `Some` for integral/pointer casts.
-    /// casts like unsizing casts will return `None`
-    pub fn from_ty(t: Ty<'tcx>) -> Option<CastTy<'tcx>> {
-        match t.kind {
-            ty::Bool => Some(CastTy::Int(IntTy::Bool)),
-            ty::Char => Some(CastTy::Int(IntTy::Char)),
-            ty::Int(_) => Some(CastTy::Int(IntTy::I)),
-            ty::Infer(ty::InferTy::IntVar(_)) => Some(CastTy::Int(IntTy::I)),
-            ty::Infer(ty::InferTy::FloatVar(_)) => Some(CastTy::Float),
-            ty::Uint(u) => Some(CastTy::Int(IntTy::U(u))),
-            ty::Float(_) => Some(CastTy::Float),
-            ty::Adt(d, _) if d.is_enum() && d.is_payloadfree() => Some(CastTy::Int(IntTy::CEnum)),
-            ty::RawPtr(mt) => Some(CastTy::Ptr(mt)),
-            ty::FnPtr(..) => Some(CastTy::FnPtr),
-            _ => None,
-        }
-    }
-}
diff --git a/src/librustc/ty/codec.rs b/src/librustc/ty/codec.rs
deleted file mode 100644
index c305999a64b..00000000000
--- a/src/librustc/ty/codec.rs
+++ /dev/null
@@ -1,494 +0,0 @@
-// This module contains some shared code for encoding and decoding various
-// things from the `ty` module, and in particular implements support for
-// "shorthands" which allow to have pointers back into the already encoded
-// stream instead of re-encoding the same thing twice.
-//
-// The functionality in here is shared between persisting to crate metadata and
-// persisting to incr. comp. caches.
-
-use crate::arena::ArenaAllocatable;
-use crate::infer::canonical::{CanonicalVarInfo, CanonicalVarInfos};
-use crate::mir::{self, interpret::Allocation};
-use crate::ty::subst::SubstsRef;
-use crate::ty::{self, List, Ty, TyCtxt};
-use rustc_data_structures::fx::FxHashMap;
-use rustc_hir::def_id::{CrateNum, DefId};
-use rustc_serialize::{opaque, Decodable, Decoder, Encodable, Encoder};
-use rustc_span::Span;
-use std::hash::Hash;
-use std::intrinsics;
-
-/// The shorthand encoding uses an enum's variant index `usize`
-/// and is offset by this value so it never matches a real variant.
-/// This offset is also chosen so that the first byte is never < 0x80.
-pub const SHORTHAND_OFFSET: usize = 0x80;
-
-pub trait EncodableWithShorthand: Clone + Eq + Hash {
-    type Variant: Encodable;
-    fn variant(&self) -> &Self::Variant;
-}
-
-#[allow(rustc::usage_of_ty_tykind)]
-impl<'tcx> EncodableWithShorthand for Ty<'tcx> {
-    type Variant = ty::TyKind<'tcx>;
-    fn variant(&self) -> &Self::Variant {
-        &self.kind
-    }
-}
-
-impl<'tcx> EncodableWithShorthand for ty::Predicate<'tcx> {
-    type Variant = ty::Predicate<'tcx>;
-    fn variant(&self) -> &Self::Variant {
-        self
-    }
-}
-
-pub trait TyEncoder: Encoder {
-    fn position(&self) -> usize;
-}
-
-impl TyEncoder for opaque::Encoder {
-    #[inline]
-    fn position(&self) -> usize {
-        self.position()
-    }
-}
-
-/// Encode the given value or a previously cached shorthand.
-pub fn encode_with_shorthand<E, T, M>(encoder: &mut E, value: &T, cache: M) -> Result<(), E::Error>
-where
-    E: TyEncoder,
-    M: for<'b> Fn(&'b mut E) -> &'b mut FxHashMap<T, usize>,
-    T: EncodableWithShorthand,
-{
-    let existing_shorthand = cache(encoder).get(value).cloned();
-    if let Some(shorthand) = existing_shorthand {
-        return encoder.emit_usize(shorthand);
-    }
-
-    let variant = value.variant();
-
-    let start = encoder.position();
-    variant.encode(encoder)?;
-    let len = encoder.position() - start;
-
-    // The shorthand encoding uses the same usize as the
-    // discriminant, with an offset so they can't conflict.
-    let discriminant = intrinsics::discriminant_value(variant);
-    assert!(discriminant < SHORTHAND_OFFSET as u64);
-    let shorthand = start + SHORTHAND_OFFSET;
-
-    // Get the number of bits that leb128 could fit
-    // in the same space as the fully encoded type.
-    let leb128_bits = len * 7;
-
-    // Check that the shorthand is a not longer than the
-    // full encoding itself, i.e., it's an obvious win.
-    if leb128_bits >= 64 || (shorthand as u64) < (1 << leb128_bits) {
-        cache(encoder).insert(value.clone(), shorthand);
-    }
-
-    Ok(())
-}
-
-pub fn encode_spanned_predicates<'tcx, E, C>(
-    encoder: &mut E,
-    predicates: &'tcx [(ty::Predicate<'tcx>, Span)],
-    cache: C,
-) -> Result<(), E::Error>
-where
-    E: TyEncoder,
-    C: for<'b> Fn(&'b mut E) -> &'b mut FxHashMap<ty::Predicate<'tcx>, usize>,
-{
-    predicates.len().encode(encoder)?;
-    for (predicate, span) in predicates {
-        encode_with_shorthand(encoder, predicate, &cache)?;
-        span.encode(encoder)?;
-    }
-    Ok(())
-}
-
-pub trait TyDecoder<'tcx>: Decoder {
-    fn tcx(&self) -> TyCtxt<'tcx>;
-
-    fn peek_byte(&self) -> u8;
-
-    fn position(&self) -> usize;
-
-    fn cached_ty_for_shorthand<F>(
-        &mut self,
-        shorthand: usize,
-        or_insert_with: F,
-    ) -> Result<Ty<'tcx>, Self::Error>
-    where
-        F: FnOnce(&mut Self) -> Result<Ty<'tcx>, Self::Error>;
-
-    fn with_position<F, R>(&mut self, pos: usize, f: F) -> R
-    where
-        F: FnOnce(&mut Self) -> R;
-
-    fn map_encoded_cnum_to_current(&self, cnum: CrateNum) -> CrateNum;
-
-    fn positioned_at_shorthand(&self) -> bool {
-        (self.peek_byte() & (SHORTHAND_OFFSET as u8)) != 0
-    }
-}
-
-#[inline]
-pub fn decode_arena_allocable<D, T: ArenaAllocatable + Decodable>(
-    decoder: &mut D,
-) -> Result<&'tcx T, D::Error>
-where
-    D: TyDecoder<'tcx>,
-{
-    Ok(decoder.tcx().arena.alloc(Decodable::decode(decoder)?))
-}
-
-#[inline]
-pub fn decode_arena_allocable_slice<D, T: ArenaAllocatable + Decodable>(
-    decoder: &mut D,
-) -> Result<&'tcx [T], D::Error>
-where
-    D: TyDecoder<'tcx>,
-{
-    Ok(decoder.tcx().arena.alloc_from_iter(<Vec<T> as Decodable>::decode(decoder)?))
-}
-
-#[inline]
-pub fn decode_cnum<D>(decoder: &mut D) -> Result<CrateNum, D::Error>
-where
-    D: TyDecoder<'tcx>,
-{
-    let cnum = CrateNum::from_u32(u32::decode(decoder)?);
-    Ok(decoder.map_encoded_cnum_to_current(cnum))
-}
-
-#[allow(rustc::usage_of_ty_tykind)]
-#[inline]
-pub fn decode_ty<D>(decoder: &mut D) -> Result<Ty<'tcx>, D::Error>
-where
-    D: TyDecoder<'tcx>,
-{
-    // Handle shorthands first, if we have an usize > 0x80.
-    if decoder.positioned_at_shorthand() {
-        let pos = decoder.read_usize()?;
-        assert!(pos >= SHORTHAND_OFFSET);
-        let shorthand = pos - SHORTHAND_OFFSET;
-
-        decoder.cached_ty_for_shorthand(shorthand, |decoder| {
-            decoder.with_position(shorthand, Ty::decode)
-        })
-    } else {
-        let tcx = decoder.tcx();
-        Ok(tcx.mk_ty(ty::TyKind::decode(decoder)?))
-    }
-}
-
-#[inline]
-pub fn decode_spanned_predicates<D>(
-    decoder: &mut D,
-) -> Result<&'tcx [(ty::Predicate<'tcx>, Span)], D::Error>
-where
-    D: TyDecoder<'tcx>,
-{
-    let tcx = decoder.tcx();
-    Ok(tcx.arena.alloc_from_iter(
-        (0..decoder.read_usize()?)
-            .map(|_| {
-                // Handle shorthands first, if we have an usize > 0x80.
-                let predicate = if decoder.positioned_at_shorthand() {
-                    let pos = decoder.read_usize()?;
-                    assert!(pos >= SHORTHAND_OFFSET);
-                    let shorthand = pos - SHORTHAND_OFFSET;
-
-                    decoder.with_position(shorthand, ty::Predicate::decode)
-                } else {
-                    ty::Predicate::decode(decoder)
-                }?;
-                Ok((predicate, Decodable::decode(decoder)?))
-            })
-            .collect::<Result<Vec<_>, _>>()?,
-    ))
-}
-
-#[inline]
-pub fn decode_substs<D>(decoder: &mut D) -> Result<SubstsRef<'tcx>, D::Error>
-where
-    D: TyDecoder<'tcx>,
-{
-    let len = decoder.read_usize()?;
-    let tcx = decoder.tcx();
-    Ok(tcx.mk_substs((0..len).map(|_| Decodable::decode(decoder)))?)
-}
-
-#[inline]
-pub fn decode_place<D>(decoder: &mut D) -> Result<mir::Place<'tcx>, D::Error>
-where
-    D: TyDecoder<'tcx>,
-{
-    let local: mir::Local = Decodable::decode(decoder)?;
-    let len = decoder.read_usize()?;
-    let projection: &'tcx List<mir::PlaceElem<'tcx>> =
-        decoder.tcx().mk_place_elems((0..len).map(|_| Decodable::decode(decoder)))?;
-    Ok(mir::Place { local, projection })
-}
-
-#[inline]
-pub fn decode_region<D>(decoder: &mut D) -> Result<ty::Region<'tcx>, D::Error>
-where
-    D: TyDecoder<'tcx>,
-{
-    Ok(decoder.tcx().mk_region(Decodable::decode(decoder)?))
-}
-
-#[inline]
-pub fn decode_ty_slice<D>(decoder: &mut D) -> Result<&'tcx ty::List<Ty<'tcx>>, D::Error>
-where
-    D: TyDecoder<'tcx>,
-{
-    let len = decoder.read_usize()?;
-    Ok(decoder.tcx().mk_type_list((0..len).map(|_| Decodable::decode(decoder)))?)
-}
-
-#[inline]
-pub fn decode_adt_def<D>(decoder: &mut D) -> Result<&'tcx ty::AdtDef, D::Error>
-where
-    D: TyDecoder<'tcx>,
-{
-    let def_id = DefId::decode(decoder)?;
-    Ok(decoder.tcx().adt_def(def_id))
-}
-
-#[inline]
-pub fn decode_existential_predicate_slice<D>(
-    decoder: &mut D,
-) -> Result<&'tcx ty::List<ty::ExistentialPredicate<'tcx>>, D::Error>
-where
-    D: TyDecoder<'tcx>,
-{
-    let len = decoder.read_usize()?;
-    Ok(decoder.tcx().mk_existential_predicates((0..len).map(|_| Decodable::decode(decoder)))?)
-}
-
-#[inline]
-pub fn decode_canonical_var_infos<D>(decoder: &mut D) -> Result<CanonicalVarInfos<'tcx>, D::Error>
-where
-    D: TyDecoder<'tcx>,
-{
-    let len = decoder.read_usize()?;
-    let interned: Result<Vec<CanonicalVarInfo>, _> =
-        (0..len).map(|_| Decodable::decode(decoder)).collect();
-    Ok(decoder.tcx().intern_canonical_var_infos(interned?.as_slice()))
-}
-
-#[inline]
-pub fn decode_const<D>(decoder: &mut D) -> Result<&'tcx ty::Const<'tcx>, D::Error>
-where
-    D: TyDecoder<'tcx>,
-{
-    Ok(decoder.tcx().mk_const(Decodable::decode(decoder)?))
-}
-
-#[inline]
-pub fn decode_allocation<D>(decoder: &mut D) -> Result<&'tcx Allocation, D::Error>
-where
-    D: TyDecoder<'tcx>,
-{
-    Ok(decoder.tcx().intern_const_alloc(Decodable::decode(decoder)?))
-}
-
-#[macro_export]
-macro_rules! __impl_decoder_methods {
-    ($($name:ident -> $ty:ty;)*) => {
-        $(
-            #[inline]
-            fn $name(&mut self) -> Result<$ty, Self::Error> {
-                self.opaque.$name()
-            }
-        )*
-    }
-}
-
-#[macro_export]
-macro_rules! impl_arena_allocatable_decoder {
-    ([]$args:tt) => {};
-    ([decode $(, $attrs:ident)*]
-     [[$DecoderName:ident [$($typaram:tt),*]], [$name:ident: $ty:ty], $tcx:lifetime]) => {
-        impl<$($typaram),*> SpecializedDecoder<&$tcx $ty> for $DecoderName<$($typaram),*> {
-            #[inline]
-            fn specialized_decode(&mut self) -> Result<&$tcx $ty, Self::Error> {
-                decode_arena_allocable(self)
-            }
-        }
-
-        impl<$($typaram),*> SpecializedDecoder<&$tcx [$ty]> for $DecoderName<$($typaram),*> {
-            #[inline]
-            fn specialized_decode(&mut self) -> Result<&$tcx [$ty], Self::Error> {
-                decode_arena_allocable_slice(self)
-            }
-        }
-    };
-    ([$ignore:ident $(, $attrs:ident)*]$args:tt) => {
-        impl_arena_allocatable_decoder!([$($attrs),*]$args);
-    };
-}
-
-#[macro_export]
-macro_rules! impl_arena_allocatable_decoders {
-    ($args:tt, [$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) => {
-        $(
-            impl_arena_allocatable_decoder!($a [$args, [$name: $ty], $tcx]);
-        )*
-    }
-}
-
-#[macro_export]
-macro_rules! implement_ty_decoder {
-    ($DecoderName:ident <$($typaram:tt),*>) => {
-        mod __ty_decoder_impl {
-            use std::borrow::Cow;
-
-            use rustc_serialize::{Decoder, SpecializedDecoder};
-
-            use $crate::infer::canonical::CanonicalVarInfos;
-            use $crate::ty;
-            use $crate::ty::codec::*;
-            use $crate::ty::subst::SubstsRef;
-            use rustc_hir::def_id::{CrateNum};
-
-            use rustc_span::Span;
-
-            use super::$DecoderName;
-
-            impl<$($typaram ),*> Decoder for $DecoderName<$($typaram),*> {
-                type Error = String;
-
-                __impl_decoder_methods! {
-                    read_nil -> ();
-
-                    read_u128 -> u128;
-                    read_u64 -> u64;
-                    read_u32 -> u32;
-                    read_u16 -> u16;
-                    read_u8 -> u8;
-                    read_usize -> usize;
-
-                    read_i128 -> i128;
-                    read_i64 -> i64;
-                    read_i32 -> i32;
-                    read_i16 -> i16;
-                    read_i8 -> i8;
-                    read_isize -> isize;
-
-                    read_bool -> bool;
-                    read_f64 -> f64;
-                    read_f32 -> f32;
-                    read_char -> char;
-                    read_str -> Cow<'_, str>;
-                }
-
-                fn error(&mut self, err: &str) -> Self::Error {
-                    self.opaque.error(err)
-                }
-            }
-
-            // FIXME(#36588): These impls are horribly unsound as they allow
-            // the caller to pick any lifetime for `'tcx`, including `'static`,
-            // by using the unspecialized proxies to them.
-
-            arena_types!(impl_arena_allocatable_decoders, [$DecoderName [$($typaram),*]], 'tcx);
-
-            impl<$($typaram),*> SpecializedDecoder<CrateNum>
-            for $DecoderName<$($typaram),*> {
-                fn specialized_decode(&mut self) -> Result<CrateNum, Self::Error> {
-                    decode_cnum(self)
-                }
-            }
-
-            impl<$($typaram),*> SpecializedDecoder<ty::Ty<'tcx>>
-            for $DecoderName<$($typaram),*> {
-                fn specialized_decode(&mut self) -> Result<ty::Ty<'tcx>, Self::Error> {
-                    decode_ty(self)
-                }
-            }
-
-            impl<$($typaram),*> SpecializedDecoder<&'tcx [(ty::Predicate<'tcx>, Span)]>
-            for $DecoderName<$($typaram),*> {
-                fn specialized_decode(&mut self)
-                                      -> Result<&'tcx [(ty::Predicate<'tcx>, Span)], Self::Error> {
-                    decode_spanned_predicates(self)
-                }
-            }
-
-            impl<$($typaram),*> SpecializedDecoder<SubstsRef<'tcx>>
-            for $DecoderName<$($typaram),*> {
-                fn specialized_decode(&mut self) -> Result<SubstsRef<'tcx>, Self::Error> {
-                    decode_substs(self)
-                }
-            }
-
-            impl<$($typaram),*> SpecializedDecoder<$crate::mir::Place<'tcx>>
-            for $DecoderName<$($typaram),*> {
-                fn specialized_decode(
-                    &mut self
-                ) -> Result<$crate::mir::Place<'tcx>, Self::Error> {
-                    decode_place(self)
-                }
-            }
-
-            impl<$($typaram),*> SpecializedDecoder<ty::Region<'tcx>>
-            for $DecoderName<$($typaram),*> {
-                fn specialized_decode(&mut self) -> Result<ty::Region<'tcx>, Self::Error> {
-                    decode_region(self)
-                }
-            }
-
-            impl<$($typaram),*> SpecializedDecoder<&'tcx ty::List<ty::Ty<'tcx>>>
-            for $DecoderName<$($typaram),*> {
-                fn specialized_decode(&mut self)
-                                      -> Result<&'tcx ty::List<ty::Ty<'tcx>>, Self::Error> {
-                    decode_ty_slice(self)
-                }
-            }
-
-            impl<$($typaram),*> SpecializedDecoder<&'tcx ty::AdtDef>
-            for $DecoderName<$($typaram),*> {
-                fn specialized_decode(&mut self) -> Result<&'tcx ty::AdtDef, Self::Error> {
-                    decode_adt_def(self)
-                }
-            }
-
-            impl<$($typaram),*> SpecializedDecoder<&'tcx ty::List<ty::ExistentialPredicate<'tcx>>>
-                for $DecoderName<$($typaram),*> {
-                fn specialized_decode(&mut self)
-                    -> Result<&'tcx ty::List<ty::ExistentialPredicate<'tcx>>, Self::Error> {
-                    decode_existential_predicate_slice(self)
-                }
-            }
-
-            impl<$($typaram),*> SpecializedDecoder<CanonicalVarInfos<'tcx>>
-                for $DecoderName<$($typaram),*> {
-                fn specialized_decode(&mut self)
-                    -> Result<CanonicalVarInfos<'tcx>, Self::Error> {
-                    decode_canonical_var_infos(self)
-                }
-            }
-
-            impl<$($typaram),*> SpecializedDecoder<&'tcx $crate::ty::Const<'tcx>>
-            for $DecoderName<$($typaram),*> {
-                fn specialized_decode(&mut self) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
-                    decode_const(self)
-                }
-            }
-
-            impl<$($typaram),*> SpecializedDecoder<&'tcx $crate::mir::interpret::Allocation>
-            for $DecoderName<$($typaram),*> {
-                fn specialized_decode(
-                    &mut self
-                ) -> Result<&'tcx $crate::mir::interpret::Allocation, Self::Error> {
-                    decode_allocation(self)
-                }
-            }
-        }
-    }
-}
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
deleted file mode 100644
index 823cbf0966d..00000000000
--- a/src/librustc/ty/context.rs
+++ /dev/null
@@ -1,2796 +0,0 @@
-//! Type context book-keeping.
-
-use crate::arena::Arena;
-use crate::dep_graph::DepGraph;
-use crate::dep_graph::{self, DepConstructor};
-use crate::hir::exports::Export;
-use crate::hir::map as hir_map;
-use crate::hir::map::{DefPathData, DefPathHash};
-use crate::ich::{NodeIdHashingMode, StableHashingContext};
-use crate::infer::canonical::{Canonical, CanonicalVarInfo, CanonicalVarInfos};
-use crate::lint::{struct_lint_level, LintSource};
-use crate::middle;
-use crate::middle::cstore::CrateStoreDyn;
-use crate::middle::cstore::EncodedMetadata;
-use crate::middle::lang_items;
-use crate::middle::lang_items::PanicLocationLangItem;
-use crate::middle::resolve_lifetime::{self, ObjectLifetimeDefault};
-use crate::middle::stability;
-use crate::mir::interpret::{Allocation, ConstValue, Scalar};
-use crate::mir::{
-    interpret, BodyAndCache, Field, Local, Place, PlaceElem, ProjectionKind, Promoted,
-};
-use crate::traits;
-use crate::traits::{Clause, Clauses, Goal, GoalKind, Goals};
-use crate::ty::free_region_map::FreeRegionMap;
-use crate::ty::layout::{LayoutDetails, TargetDataLayout, VariantIdx};
-use crate::ty::query;
-use crate::ty::steal::Steal;
-use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef};
-use crate::ty::subst::{GenericArgKind, UserSubsts};
-use crate::ty::CanonicalPolyFnSig;
-use crate::ty::GenericParamDefKind;
-use crate::ty::RegionKind;
-use crate::ty::ReprOptions;
-use crate::ty::TyKind::*;
-use crate::ty::{self, DefIdTree, Ty, TypeAndMut};
-use crate::ty::{AdtDef, AdtKind, Const, Region};
-use crate::ty::{BindingMode, BoundVar};
-use crate::ty::{ConstVid, FloatVar, FloatVid, IntVar, IntVid, TyVar, TyVid};
-use crate::ty::{ExistentialPredicate, InferTy, ParamTy, PolyFnSig, Predicate, ProjectionTy};
-use crate::ty::{InferConst, ParamConst};
-use crate::ty::{List, TyKind, TyS};
-use crate::util::common::ErrorReported;
-use rustc::lint::LintDiagnosticBuilder;
-use rustc_attr as attr;
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
-use rustc_data_structures::profiling::SelfProfilerRef;
-use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
-use rustc_data_structures::stable_hasher::{
-    hash_stable_hashmap, HashStable, StableHasher, StableVec,
-};
-use rustc_data_structures::sync::{self, Lock, Lrc, WorkerLocal};
-use rustc_hir as hir;
-use rustc_hir::def::{DefKind, Res};
-use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, DefIndex, LOCAL_CRATE};
-use rustc_hir::{HirId, Node, TraitCandidate};
-use rustc_hir::{ItemKind, ItemLocalId, ItemLocalMap, ItemLocalSet};
-use rustc_index::vec::{Idx, IndexVec};
-use rustc_macros::HashStable;
-use rustc_session::config::CrateType;
-use rustc_session::config::{BorrowckMode, OutputFilenames};
-use rustc_session::lint::{Level, Lint};
-use rustc_session::Session;
-use rustc_span::source_map::MultiSpan;
-use rustc_span::symbol::{kw, sym, Symbol};
-use rustc_span::Span;
-use rustc_target::spec::abi;
-use syntax::ast;
-use syntax::expand::allocator::AllocatorKind;
-use syntax::node_id::NodeMap;
-
-use smallvec::SmallVec;
-use std::any::Any;
-use std::borrow::Borrow;
-use std::cmp::Ordering;
-use std::collections::hash_map::{self, Entry};
-use std::fmt;
-use std::hash::{Hash, Hasher};
-use std::iter;
-use std::mem;
-use std::ops::{Bound, Deref};
-use std::sync::Arc;
-
-type InternedSet<'tcx, T> = ShardedHashMap<Interned<'tcx, T>, ()>;
-
-pub struct CtxtInterners<'tcx> {
-    /// The arena that types, regions, etc. are allocated from.
-    arena: &'tcx WorkerLocal<Arena<'tcx>>,
-
-    /// Specifically use a speedy hash algorithm for these hash sets, since
-    /// they're accessed quite often.
-    type_: InternedSet<'tcx, TyS<'tcx>>,
-    type_list: InternedSet<'tcx, List<Ty<'tcx>>>,
-    substs: InternedSet<'tcx, InternalSubsts<'tcx>>,
-    canonical_var_infos: InternedSet<'tcx, List<CanonicalVarInfo>>,
-    region: InternedSet<'tcx, RegionKind>,
-    existential_predicates: InternedSet<'tcx, List<ExistentialPredicate<'tcx>>>,
-    predicates: InternedSet<'tcx, List<Predicate<'tcx>>>,
-    clauses: InternedSet<'tcx, List<Clause<'tcx>>>,
-    goal: InternedSet<'tcx, GoalKind<'tcx>>,
-    goal_list: InternedSet<'tcx, List<Goal<'tcx>>>,
-    projs: InternedSet<'tcx, List<ProjectionKind>>,
-    place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
-    const_: InternedSet<'tcx, Const<'tcx>>,
-}
-
-impl<'tcx> CtxtInterners<'tcx> {
-    fn new(arena: &'tcx WorkerLocal<Arena<'tcx>>) -> CtxtInterners<'tcx> {
-        CtxtInterners {
-            arena,
-            type_: Default::default(),
-            type_list: Default::default(),
-            substs: Default::default(),
-            region: Default::default(),
-            existential_predicates: Default::default(),
-            canonical_var_infos: Default::default(),
-            predicates: Default::default(),
-            clauses: Default::default(),
-            goal: Default::default(),
-            goal_list: Default::default(),
-            projs: Default::default(),
-            place_elems: Default::default(),
-            const_: Default::default(),
-        }
-    }
-
-    /// Interns a type.
-    #[allow(rustc::usage_of_ty_tykind)]
-    #[inline(never)]
-    fn intern_ty(&self, kind: TyKind<'tcx>) -> Ty<'tcx> {
-        self.type_
-            .intern(kind, |kind| {
-                let flags = super::flags::FlagComputation::for_kind(&kind);
-
-                let ty_struct = TyS {
-                    kind,
-                    flags: flags.flags,
-                    outer_exclusive_binder: flags.outer_exclusive_binder,
-                };
-
-                Interned(self.arena.alloc(ty_struct))
-            })
-            .0
-    }
-}
-
-pub struct CommonTypes<'tcx> {
-    pub unit: Ty<'tcx>,
-    pub bool: Ty<'tcx>,
-    pub char: Ty<'tcx>,
-    pub isize: Ty<'tcx>,
-    pub i8: Ty<'tcx>,
-    pub i16: Ty<'tcx>,
-    pub i32: Ty<'tcx>,
-    pub i64: Ty<'tcx>,
-    pub i128: Ty<'tcx>,
-    pub usize: Ty<'tcx>,
-    pub u8: Ty<'tcx>,
-    pub u16: Ty<'tcx>,
-    pub u32: Ty<'tcx>,
-    pub u64: Ty<'tcx>,
-    pub u128: Ty<'tcx>,
-    pub f32: Ty<'tcx>,
-    pub f64: Ty<'tcx>,
-    pub never: Ty<'tcx>,
-    pub self_param: Ty<'tcx>,
-    pub err: Ty<'tcx>,
-
-    /// Dummy type used for the `Self` of a `TraitRef` created for converting
-    /// a trait object, and which gets removed in `ExistentialTraitRef`.
-    /// This type must not appear anywhere in other converted types.
-    pub trait_object_dummy_self: Ty<'tcx>,
-}
-
-pub struct CommonLifetimes<'tcx> {
-    /// `ReEmpty` in the root universe.
-    pub re_root_empty: Region<'tcx>,
-
-    /// `ReStatic`
-    pub re_static: Region<'tcx>,
-
-    /// Erased region, used after type-checking
-    pub re_erased: Region<'tcx>,
-}
-
-pub struct CommonConsts<'tcx> {
-    pub err: &'tcx Const<'tcx>,
-}
-
-pub struct LocalTableInContext<'a, V> {
-    local_id_root: Option<DefId>,
-    data: &'a ItemLocalMap<V>,
-}
-
-/// Validate that the given HirId (respectively its `local_id` part) can be
-/// safely used as a key in the tables of a TypeckTable. For that to be
-/// the case, the HirId must have the same `owner` as all the other IDs in
-/// this table (signified by `local_id_root`). Otherwise the HirId
-/// would be in a different frame of reference and using its `local_id`
-/// would result in lookup errors, or worse, in silently wrong data being
-/// stored/returned.
-fn validate_hir_id_for_typeck_tables(
-    local_id_root: Option<DefId>,
-    hir_id: hir::HirId,
-    mut_access: bool,
-) {
-    if let Some(local_id_root) = local_id_root {
-        if hir_id.owner != local_id_root.index {
-            ty::tls::with(|tcx| {
-                bug!(
-                    "node {} with HirId::owner {:?} cannot be placed in \
-                     TypeckTables with local_id_root {:?}",
-                    tcx.hir().node_to_string(hir_id),
-                    DefId::local(hir_id.owner),
-                    local_id_root
-                )
-            });
-        }
-    } else {
-        // We use "Null Object" TypeckTables in some of the analysis passes.
-        // These are just expected to be empty and their `local_id_root` is
-        // `None`. Therefore we cannot verify whether a given `HirId` would
-        // be a valid key for the given table. Instead we make sure that
-        // nobody tries to write to such a Null Object table.
-        if mut_access {
-            bug!("access to invalid TypeckTables")
-        }
-    }
-}
-
-impl<'a, V> LocalTableInContext<'a, V> {
-    pub fn contains_key(&self, id: hir::HirId) -> bool {
-        validate_hir_id_for_typeck_tables(self.local_id_root, id, false);
-        self.data.contains_key(&id.local_id)
-    }
-
-    pub fn get(&self, id: hir::HirId) -> Option<&V> {
-        validate_hir_id_for_typeck_tables(self.local_id_root, id, false);
-        self.data.get(&id.local_id)
-    }
-
-    pub fn iter(&self) -> hash_map::Iter<'_, hir::ItemLocalId, V> {
-        self.data.iter()
-    }
-}
-
-impl<'a, V> ::std::ops::Index<hir::HirId> for LocalTableInContext<'a, V> {
-    type Output = V;
-
-    fn index(&self, key: hir::HirId) -> &V {
-        self.get(key).expect("LocalTableInContext: key not found")
-    }
-}
-
-pub struct LocalTableInContextMut<'a, V> {
-    local_id_root: Option<DefId>,
-    data: &'a mut ItemLocalMap<V>,
-}
-
-impl<'a, V> LocalTableInContextMut<'a, V> {
-    pub fn get_mut(&mut self, id: hir::HirId) -> Option<&mut V> {
-        validate_hir_id_for_typeck_tables(self.local_id_root, id, true);
-        self.data.get_mut(&id.local_id)
-    }
-
-    pub fn entry(&mut self, id: hir::HirId) -> Entry<'_, hir::ItemLocalId, V> {
-        validate_hir_id_for_typeck_tables(self.local_id_root, id, true);
-        self.data.entry(id.local_id)
-    }
-
-    pub fn insert(&mut self, id: hir::HirId, val: V) -> Option<V> {
-        validate_hir_id_for_typeck_tables(self.local_id_root, id, true);
-        self.data.insert(id.local_id, val)
-    }
-
-    pub fn remove(&mut self, id: hir::HirId) -> Option<V> {
-        validate_hir_id_for_typeck_tables(self.local_id_root, id, true);
-        self.data.remove(&id.local_id)
-    }
-}
-
-/// All information necessary to validate and reveal an `impl Trait`.
-#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
-pub struct ResolvedOpaqueTy<'tcx> {
-    /// The revealed type as seen by this function.
-    pub concrete_type: Ty<'tcx>,
-    /// Generic parameters on the opaque type as passed by this function.
-    /// For `type Foo<A, B> = impl Bar<A, B>; fn foo<T, U>() -> Foo<T, U> { .. }`
-    /// this is `[T, U]`, not `[A, B]`.
-    pub substs: SubstsRef<'tcx>,
-}
-
-/// Whenever a value may be live across a generator yield, the type of that value winds up in the
-/// `GeneratorInteriorTypeCause` struct. This struct adds additional information about such
-/// captured types that can be useful for diagnostics. In particular, it stores the span that
-/// caused a given type to be recorded, along with the scope that enclosed the value (which can
-/// be used to find the await that the value is live across).
-///
-/// For example:
-///
-/// ```ignore (pseudo-Rust)
-/// async move {
-///     let x: T = ...;
-///     foo.await
-///     ...
-/// }
-/// ```
-///
-/// Here, we would store the type `T`, the span of the value `x`, and the "scope-span" for
-/// the scope that contains `x`.
-#[derive(RustcEncodable, RustcDecodable, Clone, Debug, Eq, Hash, PartialEq, HashStable)]
-pub struct GeneratorInteriorTypeCause<'tcx> {
-    /// Type of the captured binding.
-    pub ty: Ty<'tcx>,
-    /// Span of the binding that was captured.
-    pub span: Span,
-    /// Span of the scope of the captured binding.
-    pub scope_span: Option<Span>,
-    /// Expr which the type evaluated from.
-    pub expr: Option<hir::HirId>,
-}
-
-#[derive(RustcEncodable, RustcDecodable, Debug)]
-pub struct TypeckTables<'tcx> {
-    /// The HirId::owner all ItemLocalIds in this table are relative to.
-    pub local_id_root: Option<DefId>,
-
-    /// Resolved definitions for `<T>::X` associated paths and
-    /// method calls, including those of overloaded operators.
-    type_dependent_defs: ItemLocalMap<Result<(DefKind, DefId), ErrorReported>>,
-
-    /// Resolved field indices for field accesses in expressions (`S { field }`, `obj.field`)
-    /// or patterns (`S { field }`). The index is often useful by itself, but to learn more
-    /// about the field you also need definition of the variant to which the field
-    /// belongs, but it may not exist if it's a tuple field (`tuple.0`).
-    field_indices: ItemLocalMap<usize>,
-
-    /// Stores the types for various nodes in the AST. Note that this table
-    /// is not guaranteed to be populated until after typeck. See
-    /// typeck::check::fn_ctxt for details.
-    node_types: ItemLocalMap<Ty<'tcx>>,
-
-    /// Stores the type parameters which were substituted to obtain the type
-    /// of this node. This only applies to nodes that refer to entities
-    /// parameterized by type parameters, such as generic fns, types, or
-    /// other items.
-    node_substs: ItemLocalMap<SubstsRef<'tcx>>,
-
-    /// This will either store the canonicalized types provided by the user
-    /// or the substitutions that the user explicitly gave (if any) attached
-    /// to `id`. These will not include any inferred values. The canonical form
-    /// is used to capture things like `_` or other unspecified values.
-    ///
-    /// For example, if the user wrote `foo.collect::<Vec<_>>()`, then the
-    /// canonical substitutions would include only `for<X> { Vec<X> }`.
-    ///
-    /// See also `AscribeUserType` statement in MIR.
-    user_provided_types: ItemLocalMap<CanonicalUserType<'tcx>>,
-
-    /// Stores the canonicalized types provided by the user. See also
-    /// `AscribeUserType` statement in MIR.
-    pub user_provided_sigs: DefIdMap<CanonicalPolyFnSig<'tcx>>,
-
-    adjustments: ItemLocalMap<Vec<ty::adjustment::Adjustment<'tcx>>>,
-
-    /// Stores the actual binding mode for all instances of hir::BindingAnnotation.
-    pat_binding_modes: ItemLocalMap<BindingMode>,
-
-    /// Stores the types which were implicitly dereferenced in pattern binding modes
-    /// for later usage in HAIR lowering. For example,
-    ///
-    /// ```
-    /// match &&Some(5i32) {
-    ///     Some(n) => {},
-    ///     _ => {},
-    /// }
-    /// ```
-    /// leads to a `vec![&&Option<i32>, &Option<i32>]`. Empty vectors are not stored.
-    ///
-    /// See:
-    /// https://github.com/rust-lang/rfcs/blob/master/text/2005-match-ergonomics.md#definitions
-    pat_adjustments: ItemLocalMap<Vec<Ty<'tcx>>>,
-
-    /// Borrows
-    pub upvar_capture_map: ty::UpvarCaptureMap<'tcx>,
-
-    /// Records the reasons that we picked the kind of each closure;
-    /// not all closures are present in the map.
-    closure_kind_origins: ItemLocalMap<(Span, ast::Name)>,
-
-    /// For each fn, records the "liberated" types of its arguments
-    /// and return type. Liberated means that all bound regions
-    /// (including late-bound regions) are replaced with free
-    /// equivalents. This table is not used in codegen (since regions
-    /// are erased there) and hence is not serialized to metadata.
-    liberated_fn_sigs: ItemLocalMap<ty::FnSig<'tcx>>,
-
-    /// For each FRU expression, record the normalized types of the fields
-    /// of the struct - this is needed because it is non-trivial to
-    /// normalize while preserving regions. This table is used only in
-    /// MIR construction and hence is not serialized to metadata.
-    fru_field_types: ItemLocalMap<Vec<Ty<'tcx>>>,
-
-    /// For every coercion cast we add the HIR node ID of the cast
-    /// expression to this set.
-    coercion_casts: ItemLocalSet,
-
-    /// Set of trait imports actually used in the method resolution.
-    /// This is used for warning unused imports. During type
-    /// checking, this `Lrc` should not be cloned: it must have a ref-count
-    /// of 1 so that we can insert things into the set mutably.
-    pub used_trait_imports: Lrc<DefIdSet>,
-
-    /// If any errors occurred while type-checking this body,
-    /// this field will be set to `true`.
-    pub tainted_by_errors: bool,
-
-    /// Stores the free-region relationships that were deduced from
-    /// its where-clauses and parameter types. These are then
-    /// read-again by borrowck.
-    pub free_region_map: FreeRegionMap<'tcx>,
-
-    /// All the opaque types that are restricted to concrete types
-    /// by this function.
-    pub concrete_opaque_types: FxHashMap<DefId, ResolvedOpaqueTy<'tcx>>,
-
-    /// Given the closure ID this map provides the list of UpvarIDs used by it.
-    /// The upvarID contains the HIR node ID and it also contains the full path
-    /// leading to the member of the struct or tuple that is used instead of the
-    /// entire variable.
-    pub upvar_list: ty::UpvarListMap,
-
-    /// Stores the type, expression, span and optional scope span of all types
-    /// that are live across the yield of this generator (if a generator).
-    pub generator_interior_types: Vec<GeneratorInteriorTypeCause<'tcx>>,
-}
-
-impl<'tcx> TypeckTables<'tcx> {
-    pub fn empty(local_id_root: Option<DefId>) -> TypeckTables<'tcx> {
-        TypeckTables {
-            local_id_root,
-            type_dependent_defs: Default::default(),
-            field_indices: Default::default(),
-            user_provided_types: Default::default(),
-            user_provided_sigs: Default::default(),
-            node_types: Default::default(),
-            node_substs: Default::default(),
-            adjustments: Default::default(),
-            pat_binding_modes: Default::default(),
-            pat_adjustments: Default::default(),
-            upvar_capture_map: Default::default(),
-            closure_kind_origins: Default::default(),
-            liberated_fn_sigs: Default::default(),
-            fru_field_types: Default::default(),
-            coercion_casts: Default::default(),
-            used_trait_imports: Lrc::new(Default::default()),
-            tainted_by_errors: false,
-            free_region_map: Default::default(),
-            concrete_opaque_types: Default::default(),
-            upvar_list: Default::default(),
-            generator_interior_types: Default::default(),
-        }
-    }
-
-    /// Returns the final resolution of a `QPath` in an `Expr` or `Pat` node.
-    pub fn qpath_res(&self, qpath: &hir::QPath<'_>, id: hir::HirId) -> Res {
-        match *qpath {
-            hir::QPath::Resolved(_, ref path) => path.res,
-            hir::QPath::TypeRelative(..) => self
-                .type_dependent_def(id)
-                .map_or(Res::Err, |(kind, def_id)| Res::Def(kind, def_id)),
-        }
-    }
-
-    pub fn type_dependent_defs(
-        &self,
-    ) -> LocalTableInContext<'_, Result<(DefKind, DefId), ErrorReported>> {
-        LocalTableInContext { local_id_root: self.local_id_root, data: &self.type_dependent_defs }
-    }
-
-    pub fn type_dependent_def(&self, id: HirId) -> Option<(DefKind, DefId)> {
-        validate_hir_id_for_typeck_tables(self.local_id_root, id, false);
-        self.type_dependent_defs.get(&id.local_id).cloned().and_then(|r| r.ok())
-    }
-
-    pub fn type_dependent_def_id(&self, id: HirId) -> Option<DefId> {
-        self.type_dependent_def(id).map(|(_, def_id)| def_id)
-    }
-
-    pub fn type_dependent_defs_mut(
-        &mut self,
-    ) -> LocalTableInContextMut<'_, Result<(DefKind, DefId), ErrorReported>> {
-        LocalTableInContextMut {
-            local_id_root: self.local_id_root,
-            data: &mut self.type_dependent_defs,
-        }
-    }
-
-    pub fn field_indices(&self) -> LocalTableInContext<'_, usize> {
-        LocalTableInContext { local_id_root: self.local_id_root, data: &self.field_indices }
-    }
-
-    pub fn field_indices_mut(&mut self) -> LocalTableInContextMut<'_, usize> {
-        LocalTableInContextMut { local_id_root: self.local_id_root, data: &mut self.field_indices }
-    }
-
-    pub fn user_provided_types(&self) -> LocalTableInContext<'_, CanonicalUserType<'tcx>> {
-        LocalTableInContext { local_id_root: self.local_id_root, data: &self.user_provided_types }
-    }
-
-    pub fn user_provided_types_mut(
-        &mut self,
-    ) -> LocalTableInContextMut<'_, CanonicalUserType<'tcx>> {
-        LocalTableInContextMut {
-            local_id_root: self.local_id_root,
-            data: &mut self.user_provided_types,
-        }
-    }
-
-    pub fn node_types(&self) -> LocalTableInContext<'_, Ty<'tcx>> {
-        LocalTableInContext { local_id_root: self.local_id_root, data: &self.node_types }
-    }
-
-    pub fn node_types_mut(&mut self) -> LocalTableInContextMut<'_, Ty<'tcx>> {
-        LocalTableInContextMut { local_id_root: self.local_id_root, data: &mut self.node_types }
-    }
-
-    pub fn node_type(&self, id: hir::HirId) -> Ty<'tcx> {
-        self.node_type_opt(id).unwrap_or_else(|| {
-            bug!("node_type: no type for node `{}`", tls::with(|tcx| tcx.hir().node_to_string(id)))
-        })
-    }
-
-    pub fn node_type_opt(&self, id: hir::HirId) -> Option<Ty<'tcx>> {
-        validate_hir_id_for_typeck_tables(self.local_id_root, id, false);
-        self.node_types.get(&id.local_id).cloned()
-    }
-
-    pub fn node_substs_mut(&mut self) -> LocalTableInContextMut<'_, SubstsRef<'tcx>> {
-        LocalTableInContextMut { local_id_root: self.local_id_root, data: &mut self.node_substs }
-    }
-
-    pub fn node_substs(&self, id: hir::HirId) -> SubstsRef<'tcx> {
-        validate_hir_id_for_typeck_tables(self.local_id_root, id, false);
-        self.node_substs.get(&id.local_id).cloned().unwrap_or_else(|| InternalSubsts::empty())
-    }
-
-    pub fn node_substs_opt(&self, id: hir::HirId) -> Option<SubstsRef<'tcx>> {
-        validate_hir_id_for_typeck_tables(self.local_id_root, id, false);
-        self.node_substs.get(&id.local_id).cloned()
-    }
-
-    // Returns the type of a pattern as a monotype. Like @expr_ty, this function
-    // doesn't provide type parameter substitutions.
-    pub fn pat_ty(&self, pat: &hir::Pat<'_>) -> Ty<'tcx> {
-        self.node_type(pat.hir_id)
-    }
-
-    pub fn pat_ty_opt(&self, pat: &hir::Pat<'_>) -> Option<Ty<'tcx>> {
-        self.node_type_opt(pat.hir_id)
-    }
-
-    // Returns the type of an expression as a monotype.
-    //
-    // NB (1): This is the PRE-ADJUSTMENT TYPE for the expression.  That is, in
-    // some cases, we insert `Adjustment` annotations such as auto-deref or
-    // auto-ref.  The type returned by this function does not consider such
-    // adjustments.  See `expr_ty_adjusted()` instead.
-    //
-    // NB (2): This type doesn't provide type parameter substitutions; e.g., if you
-    // ask for the type of "id" in "id(3)", it will return "fn(&isize) -> isize"
-    // instead of "fn(ty) -> T with T = isize".
-    pub fn expr_ty(&self, expr: &hir::Expr<'_>) -> Ty<'tcx> {
-        self.node_type(expr.hir_id)
-    }
-
-    pub fn expr_ty_opt(&self, expr: &hir::Expr<'_>) -> Option<Ty<'tcx>> {
-        self.node_type_opt(expr.hir_id)
-    }
-
-    pub fn adjustments(&self) -> LocalTableInContext<'_, Vec<ty::adjustment::Adjustment<'tcx>>> {
-        LocalTableInContext { local_id_root: self.local_id_root, data: &self.adjustments }
-    }
-
-    pub fn adjustments_mut(
-        &mut self,
-    ) -> LocalTableInContextMut<'_, Vec<ty::adjustment::Adjustment<'tcx>>> {
-        LocalTableInContextMut { local_id_root: self.local_id_root, data: &mut self.adjustments }
-    }
-
-    pub fn expr_adjustments(&self, expr: &hir::Expr<'_>) -> &[ty::adjustment::Adjustment<'tcx>] {
-        validate_hir_id_for_typeck_tables(self.local_id_root, expr.hir_id, false);
-        self.adjustments.get(&expr.hir_id.local_id).map_or(&[], |a| &a[..])
-    }
-
-    /// Returns the type of `expr`, considering any `Adjustment`
-    /// entry recorded for that expression.
-    pub fn expr_ty_adjusted(&self, expr: &hir::Expr<'_>) -> Ty<'tcx> {
-        self.expr_adjustments(expr).last().map_or_else(|| self.expr_ty(expr), |adj| adj.target)
-    }
-
-    pub fn expr_ty_adjusted_opt(&self, expr: &hir::Expr<'_>) -> Option<Ty<'tcx>> {
-        self.expr_adjustments(expr).last().map(|adj| adj.target).or_else(|| self.expr_ty_opt(expr))
-    }
-
-    pub fn is_method_call(&self, expr: &hir::Expr<'_>) -> bool {
-        // Only paths and method calls/overloaded operators have
-        // entries in type_dependent_defs, ignore the former here.
-        if let hir::ExprKind::Path(_) = expr.kind {
-            return false;
-        }
-
-        match self.type_dependent_defs().get(expr.hir_id) {
-            Some(Ok((DefKind::Method, _))) => true,
-            _ => false,
-        }
-    }
-
-    pub fn extract_binding_mode(&self, s: &Session, id: HirId, sp: Span) -> Option<BindingMode> {
-        self.pat_binding_modes().get(id).copied().or_else(|| {
-            s.delay_span_bug(sp, "missing binding mode");
-            None
-        })
-    }
-
-    pub fn pat_binding_modes(&self) -> LocalTableInContext<'_, BindingMode> {
-        LocalTableInContext { local_id_root: self.local_id_root, data: &self.pat_binding_modes }
-    }
-
-    pub fn pat_binding_modes_mut(&mut self) -> LocalTableInContextMut<'_, BindingMode> {
-        LocalTableInContextMut {
-            local_id_root: self.local_id_root,
-            data: &mut self.pat_binding_modes,
-        }
-    }
-
-    pub fn pat_adjustments(&self) -> LocalTableInContext<'_, Vec<Ty<'tcx>>> {
-        LocalTableInContext { local_id_root: self.local_id_root, data: &self.pat_adjustments }
-    }
-
-    pub fn pat_adjustments_mut(&mut self) -> LocalTableInContextMut<'_, Vec<Ty<'tcx>>> {
-        LocalTableInContextMut {
-            local_id_root: self.local_id_root,
-            data: &mut self.pat_adjustments,
-        }
-    }
-
-    pub fn upvar_capture(&self, upvar_id: ty::UpvarId) -> ty::UpvarCapture<'tcx> {
-        self.upvar_capture_map[&upvar_id]
-    }
-
-    pub fn closure_kind_origins(&self) -> LocalTableInContext<'_, (Span, ast::Name)> {
-        LocalTableInContext { local_id_root: self.local_id_root, data: &self.closure_kind_origins }
-    }
-
-    pub fn closure_kind_origins_mut(&mut self) -> LocalTableInContextMut<'_, (Span, ast::Name)> {
-        LocalTableInContextMut {
-            local_id_root: self.local_id_root,
-            data: &mut self.closure_kind_origins,
-        }
-    }
-
-    pub fn liberated_fn_sigs(&self) -> LocalTableInContext<'_, ty::FnSig<'tcx>> {
-        LocalTableInContext { local_id_root: self.local_id_root, data: &self.liberated_fn_sigs }
-    }
-
-    pub fn liberated_fn_sigs_mut(&mut self) -> LocalTableInContextMut<'_, ty::FnSig<'tcx>> {
-        LocalTableInContextMut {
-            local_id_root: self.local_id_root,
-            data: &mut self.liberated_fn_sigs,
-        }
-    }
-
-    pub fn fru_field_types(&self) -> LocalTableInContext<'_, Vec<Ty<'tcx>>> {
-        LocalTableInContext { local_id_root: self.local_id_root, data: &self.fru_field_types }
-    }
-
-    pub fn fru_field_types_mut(&mut self) -> LocalTableInContextMut<'_, Vec<Ty<'tcx>>> {
-        LocalTableInContextMut {
-            local_id_root: self.local_id_root,
-            data: &mut self.fru_field_types,
-        }
-    }
-
-    pub fn is_coercion_cast(&self, hir_id: hir::HirId) -> bool {
-        validate_hir_id_for_typeck_tables(self.local_id_root, hir_id, true);
-        self.coercion_casts.contains(&hir_id.local_id)
-    }
-
-    pub fn set_coercion_cast(&mut self, id: ItemLocalId) {
-        self.coercion_casts.insert(id);
-    }
-
-    pub fn coercion_casts(&self) -> &ItemLocalSet {
-        &self.coercion_casts
-    }
-}
-
-impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for TypeckTables<'tcx> {
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        let ty::TypeckTables {
-            local_id_root,
-            ref type_dependent_defs,
-            ref field_indices,
-            ref user_provided_types,
-            ref user_provided_sigs,
-            ref node_types,
-            ref node_substs,
-            ref adjustments,
-            ref pat_binding_modes,
-            ref pat_adjustments,
-            ref upvar_capture_map,
-            ref closure_kind_origins,
-            ref liberated_fn_sigs,
-            ref fru_field_types,
-
-            ref coercion_casts,
-
-            ref used_trait_imports,
-            tainted_by_errors,
-            ref free_region_map,
-            ref concrete_opaque_types,
-            ref upvar_list,
-            ref generator_interior_types,
-        } = *self;
-
-        hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
-            type_dependent_defs.hash_stable(hcx, hasher);
-            field_indices.hash_stable(hcx, hasher);
-            user_provided_types.hash_stable(hcx, hasher);
-            user_provided_sigs.hash_stable(hcx, hasher);
-            node_types.hash_stable(hcx, hasher);
-            node_substs.hash_stable(hcx, hasher);
-            adjustments.hash_stable(hcx, hasher);
-            pat_binding_modes.hash_stable(hcx, hasher);
-            pat_adjustments.hash_stable(hcx, hasher);
-            hash_stable_hashmap(hcx, hasher, upvar_capture_map, |up_var_id, hcx| {
-                let ty::UpvarId { var_path, closure_expr_id } = *up_var_id;
-
-                let local_id_root = local_id_root.expect("trying to hash invalid TypeckTables");
-
-                let var_owner_def_id =
-                    DefId { krate: local_id_root.krate, index: var_path.hir_id.owner };
-                let closure_def_id =
-                    DefId { krate: local_id_root.krate, index: closure_expr_id.to_def_id().index };
-                (
-                    hcx.def_path_hash(var_owner_def_id),
-                    var_path.hir_id.local_id,
-                    hcx.def_path_hash(closure_def_id),
-                )
-            });
-
-            closure_kind_origins.hash_stable(hcx, hasher);
-            liberated_fn_sigs.hash_stable(hcx, hasher);
-            fru_field_types.hash_stable(hcx, hasher);
-            coercion_casts.hash_stable(hcx, hasher);
-            used_trait_imports.hash_stable(hcx, hasher);
-            tainted_by_errors.hash_stable(hcx, hasher);
-            free_region_map.hash_stable(hcx, hasher);
-            concrete_opaque_types.hash_stable(hcx, hasher);
-            upvar_list.hash_stable(hcx, hasher);
-            generator_interior_types.hash_stable(hcx, hasher);
-        })
-    }
-}
-
-rustc_index::newtype_index! {
-    pub struct UserTypeAnnotationIndex {
-        derive [HashStable]
-        DEBUG_FORMAT = "UserType({})",
-        const START_INDEX = 0,
-    }
-}
-
-/// Mapping of type annotation indices to canonical user type annotations.
-pub type CanonicalUserTypeAnnotations<'tcx> =
-    IndexVec<UserTypeAnnotationIndex, CanonicalUserTypeAnnotation<'tcx>>;
-
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable, Lift)]
-pub struct CanonicalUserTypeAnnotation<'tcx> {
-    pub user_ty: CanonicalUserType<'tcx>,
-    pub span: Span,
-    pub inferred_ty: Ty<'tcx>,
-}
-
-/// Canonicalized user type annotation.
-pub type CanonicalUserType<'tcx> = Canonical<'tcx, UserType<'tcx>>;
-
-impl CanonicalUserType<'tcx> {
-    /// Returns `true` if this represents a substitution of the form `[?0, ?1, ?2]`,
-    /// i.e., each thing is mapped to a canonical variable with the same index.
-    pub fn is_identity(&self) -> bool {
-        match self.value {
-            UserType::Ty(_) => false,
-            UserType::TypeOf(_, user_substs) => {
-                if user_substs.user_self_ty.is_some() {
-                    return false;
-                }
-
-                user_substs.substs.iter().zip(BoundVar::new(0)..).all(|(kind, cvar)| {
-                    match kind.unpack() {
-                        GenericArgKind::Type(ty) => match ty.kind {
-                            ty::Bound(debruijn, b) => {
-                                // We only allow a `ty::INNERMOST` index in substitutions.
-                                assert_eq!(debruijn, ty::INNERMOST);
-                                cvar == b.var
-                            }
-                            _ => false,
-                        },
-
-                        GenericArgKind::Lifetime(r) => match r {
-                            ty::ReLateBound(debruijn, br) => {
-                                // We only allow a `ty::INNERMOST` index in substitutions.
-                                assert_eq!(*debruijn, ty::INNERMOST);
-                                cvar == br.assert_bound_var()
-                            }
-                            _ => false,
-                        },
-
-                        GenericArgKind::Const(ct) => match ct.val {
-                            ty::ConstKind::Bound(debruijn, b) => {
-                                // We only allow a `ty::INNERMOST` index in substitutions.
-                                assert_eq!(debruijn, ty::INNERMOST);
-                                cvar == b
-                            }
-                            _ => false,
-                        },
-                    }
-                })
-            }
-        }
-    }
-}
-
-/// A user-given type annotation attached to a constant. These arise
-/// from constants that are named via paths, like `Foo::<A>::new` and
-/// so forth.
-#[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
-#[derive(HashStable, TypeFoldable, Lift)]
-pub enum UserType<'tcx> {
-    Ty(Ty<'tcx>),
-
-    /// The canonical type is the result of `type_of(def_id)` with the
-    /// given substitutions applied.
-    TypeOf(DefId, UserSubsts<'tcx>),
-}
-
-impl<'tcx> CommonTypes<'tcx> {
-    fn new(interners: &CtxtInterners<'tcx>) -> CommonTypes<'tcx> {
-        let mk = |ty| interners.intern_ty(ty);
-
-        CommonTypes {
-            unit: mk(Tuple(List::empty())),
-            bool: mk(Bool),
-            char: mk(Char),
-            never: mk(Never),
-            err: mk(Error),
-            isize: mk(Int(ast::IntTy::Isize)),
-            i8: mk(Int(ast::IntTy::I8)),
-            i16: mk(Int(ast::IntTy::I16)),
-            i32: mk(Int(ast::IntTy::I32)),
-            i64: mk(Int(ast::IntTy::I64)),
-            i128: mk(Int(ast::IntTy::I128)),
-            usize: mk(Uint(ast::UintTy::Usize)),
-            u8: mk(Uint(ast::UintTy::U8)),
-            u16: mk(Uint(ast::UintTy::U16)),
-            u32: mk(Uint(ast::UintTy::U32)),
-            u64: mk(Uint(ast::UintTy::U64)),
-            u128: mk(Uint(ast::UintTy::U128)),
-            f32: mk(Float(ast::FloatTy::F32)),
-            f64: mk(Float(ast::FloatTy::F64)),
-            self_param: mk(ty::Param(ty::ParamTy { index: 0, name: kw::SelfUpper })),
-
-            trait_object_dummy_self: mk(Infer(ty::FreshTy(0))),
-        }
-    }
-}
-
-impl<'tcx> CommonLifetimes<'tcx> {
-    fn new(interners: &CtxtInterners<'tcx>) -> CommonLifetimes<'tcx> {
-        let mk = |r| interners.region.intern(r, |r| Interned(interners.arena.alloc(r))).0;
-
-        CommonLifetimes {
-            re_root_empty: mk(RegionKind::ReEmpty(ty::UniverseIndex::ROOT)),
-            re_static: mk(RegionKind::ReStatic),
-            re_erased: mk(RegionKind::ReErased),
-        }
-    }
-}
-
-impl<'tcx> CommonConsts<'tcx> {
-    fn new(interners: &CtxtInterners<'tcx>, types: &CommonTypes<'tcx>) -> CommonConsts<'tcx> {
-        let mk_const = |c| interners.const_.intern(c, |c| Interned(interners.arena.alloc(c))).0;
-
-        CommonConsts {
-            err: mk_const(ty::Const {
-                val: ty::ConstKind::Value(ConstValue::Scalar(Scalar::zst())),
-                ty: types.err,
-            }),
-        }
-    }
-}
-
-// This struct contains information regarding the `ReFree(FreeRegion)` corresponding to a lifetime
-// conflict.
-#[derive(Debug)]
-pub struct FreeRegionInfo {
-    // def id corresponding to FreeRegion
-    pub def_id: DefId,
-    // the bound region corresponding to FreeRegion
-    pub boundregion: ty::BoundRegion,
-    // checks if bound region is in Impl Item
-    pub is_impl_item: bool,
-}
-
-/// The central data structure of the compiler. It stores references
-/// to the various **arenas** and also houses the results of the
-/// various **compiler queries** that have been performed. See the
-/// [rustc guide] for more details.
-///
-/// [rustc guide]: https://rust-lang.github.io/rustc-guide/ty.html
-#[derive(Copy, Clone)]
-#[rustc_diagnostic_item = "TyCtxt"]
-pub struct TyCtxt<'tcx> {
-    gcx: &'tcx GlobalCtxt<'tcx>,
-}
-
-impl<'tcx> Deref for TyCtxt<'tcx> {
-    type Target = &'tcx GlobalCtxt<'tcx>;
-    #[inline(always)]
-    fn deref(&self) -> &Self::Target {
-        &self.gcx
-    }
-}
-
-pub struct GlobalCtxt<'tcx> {
-    pub arena: &'tcx WorkerLocal<Arena<'tcx>>,
-
-    interners: CtxtInterners<'tcx>,
-
-    cstore: Box<CrateStoreDyn>,
-
-    pub sess: &'tcx Session,
-
-    /// This only ever stores a `LintStore` but we don't want a dependency on that type here.
-    ///
-    /// FIXME(Centril): consider `dyn LintStoreMarker` once
-    /// we can upcast to `Any` for some additional type safety.
-    pub lint_store: Lrc<dyn Any + sync::Sync + sync::Send>,
-
-    pub dep_graph: DepGraph,
-
-    pub prof: SelfProfilerRef,
-
-    /// Common types, pre-interned for your convenience.
-    pub types: CommonTypes<'tcx>,
-
-    /// Common lifetimes, pre-interned for your convenience.
-    pub lifetimes: CommonLifetimes<'tcx>,
-
-    /// Common consts, pre-interned for your convenience.
-    pub consts: CommonConsts<'tcx>,
-
-    /// Resolutions of `extern crate` items produced by resolver.
-    extern_crate_map: NodeMap<CrateNum>,
-
-    /// Map indicating what traits are in scope for places where this
-    /// is relevant; generated by resolve.
-    trait_map: FxHashMap<DefIndex, FxHashMap<ItemLocalId, StableVec<TraitCandidate>>>,
-
-    /// Export map produced by name resolution.
-    export_map: FxHashMap<DefId, Vec<Export<hir::HirId>>>,
-
-    /// This should usually be accessed with the `tcx.hir()` method.
-    pub(crate) hir_map: hir_map::Map<'tcx>,
-
-    /// A map from `DefPathHash` -> `DefId`. Includes `DefId`s from the local crate
-    /// as well as all upstream crates. Only populated in incremental mode.
-    pub def_path_hash_to_def_id: Option<FxHashMap<DefPathHash, DefId>>,
-
-    pub queries: query::Queries<'tcx>,
-
-    maybe_unused_trait_imports: FxHashSet<DefId>,
-    maybe_unused_extern_crates: Vec<(DefId, Span)>,
-    /// A map of glob use to a set of names it actually imports. Currently only
-    /// used in save-analysis.
-    glob_map: FxHashMap<DefId, FxHashSet<ast::Name>>,
-    /// Extern prelude entries. The value is `true` if the entry was introduced
-    /// via `extern crate` item and not `--extern` option or compiler built-in.
-    pub extern_prelude: FxHashMap<ast::Name, bool>,
-
-    // Internal cache for metadata decoding. No need to track deps on this.
-    pub rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
-
-    /// Caches the results of trait selection. This cache is used
-    /// for things that do not have to do with the parameters in scope.
-    pub selection_cache: traits::SelectionCache<'tcx>,
-
-    /// Caches the results of trait evaluation. This cache is used
-    /// for things that do not have to do with the parameters in scope.
-    /// Merge this with `selection_cache`?
-    pub evaluation_cache: traits::EvaluationCache<'tcx>,
-
-    /// The definite name of the current crate after taking into account
-    /// attributes, commandline parameters, etc.
-    pub crate_name: Symbol,
-
-    /// Data layout specification for the current target.
-    pub data_layout: TargetDataLayout,
-
-    /// `#[stable]` and `#[unstable]` attributes
-    stability_interner: ShardedHashMap<&'tcx attr::Stability, ()>,
-
-    /// `#[rustc_const_stable]` and `#[rustc_const_unstable]` attributes
-    const_stability_interner: ShardedHashMap<&'tcx attr::ConstStability, ()>,
-
-    /// Stores the value of constants (and deduplicates the actual memory)
-    allocation_interner: ShardedHashMap<&'tcx Allocation, ()>,
-
-    pub alloc_map: Lock<interpret::AllocMap<'tcx>>,
-
-    layout_interner: ShardedHashMap<&'tcx LayoutDetails, ()>,
-
-    output_filenames: Arc<OutputFilenames>,
-}
-
-impl<'tcx> TyCtxt<'tcx> {
-    pub fn alloc_steal_mir(self, mir: BodyAndCache<'tcx>) -> &'tcx Steal<BodyAndCache<'tcx>> {
-        self.arena.alloc(Steal::new(mir))
-    }
-
-    pub fn alloc_steal_promoted(
-        self,
-        promoted: IndexVec<Promoted, BodyAndCache<'tcx>>,
-    ) -> &'tcx Steal<IndexVec<Promoted, BodyAndCache<'tcx>>> {
-        self.arena.alloc(Steal::new(promoted))
-    }
-
-    pub fn intern_promoted(
-        self,
-        promoted: IndexVec<Promoted, BodyAndCache<'tcx>>,
-    ) -> &'tcx IndexVec<Promoted, BodyAndCache<'tcx>> {
-        self.arena.alloc(promoted)
-    }
-
-    pub fn alloc_adt_def(
-        self,
-        did: DefId,
-        kind: AdtKind,
-        variants: IndexVec<VariantIdx, ty::VariantDef>,
-        repr: ReprOptions,
-    ) -> &'tcx ty::AdtDef {
-        let def = ty::AdtDef::new(self, did, kind, variants, repr);
-        self.arena.alloc(def)
-    }
-
-    pub fn intern_const_alloc(self, alloc: Allocation) -> &'tcx Allocation {
-        self.allocation_interner.intern(alloc, |alloc| self.arena.alloc(alloc))
-    }
-
-    /// Allocates a read-only byte or string literal for `mir::interpret`.
-    pub fn allocate_bytes(self, bytes: &[u8]) -> interpret::AllocId {
-        // Create an allocation that just contains these bytes.
-        let alloc = interpret::Allocation::from_byte_aligned_bytes(bytes);
-        let alloc = self.intern_const_alloc(alloc);
-        self.alloc_map.lock().create_memory_alloc(alloc)
-    }
-
-    pub fn intern_stability(self, stab: attr::Stability) -> &'tcx attr::Stability {
-        self.stability_interner.intern(stab, |stab| self.arena.alloc(stab))
-    }
-
-    pub fn intern_const_stability(self, stab: attr::ConstStability) -> &'tcx attr::ConstStability {
-        self.const_stability_interner.intern(stab, |stab| self.arena.alloc(stab))
-    }
-
-    pub fn intern_layout(self, layout: LayoutDetails) -> &'tcx LayoutDetails {
-        self.layout_interner.intern(layout, |layout| self.arena.alloc(layout))
-    }
-
-    /// Returns a range of the start/end indices specified with the
-    /// `rustc_layout_scalar_valid_range` attribute.
-    pub fn layout_scalar_valid_range(self, def_id: DefId) -> (Bound<u128>, Bound<u128>) {
-        let attrs = self.get_attrs(def_id);
-        let get = |name| {
-            let attr = match attrs.iter().find(|a| a.check_name(name)) {
-                Some(attr) => attr,
-                None => return Bound::Unbounded,
-            };
-            for meta in attr.meta_item_list().expect("rustc_layout_scalar_valid_range takes args") {
-                match meta.literal().expect("attribute takes lit").kind {
-                    ast::LitKind::Int(a, _) => return Bound::Included(a),
-                    _ => span_bug!(attr.span, "rustc_layout_scalar_valid_range expects int arg"),
-                }
-            }
-            span_bug!(attr.span, "no arguments to `rustc_layout_scalar_valid_range` attribute");
-        };
-        (
-            get(sym::rustc_layout_scalar_valid_range_start),
-            get(sym::rustc_layout_scalar_valid_range_end),
-        )
-    }
-
-    pub fn lift<T: ?Sized + Lift<'tcx>>(self, value: &T) -> Option<T::Lifted> {
-        value.lift_to_tcx(self)
-    }
-
-    /// Creates a type context and call the closure with a `TyCtxt` reference
-    /// to the context. The closure enforces that the type context and any interned
-    /// value (types, substs, etc.) can only be used while `ty::tls` has a valid
-    /// reference to the context, to allow formatting values that need it.
-    pub fn create_global_ctxt(
-        s: &'tcx Session,
-        lint_store: Lrc<dyn Any + sync::Send + sync::Sync>,
-        local_providers: ty::query::Providers<'tcx>,
-        extern_providers: ty::query::Providers<'tcx>,
-        arena: &'tcx WorkerLocal<Arena<'tcx>>,
-        resolutions: ty::ResolverOutputs,
-        hir: hir_map::Map<'tcx>,
-        on_disk_query_result_cache: query::OnDiskCache<'tcx>,
-        crate_name: &str,
-        output_filenames: &OutputFilenames,
-    ) -> GlobalCtxt<'tcx> {
-        let data_layout = TargetDataLayout::parse(&s.target.target).unwrap_or_else(|err| {
-            s.fatal(&err);
-        });
-        let interners = CtxtInterners::new(arena);
-        let common_types = CommonTypes::new(&interners);
-        let common_lifetimes = CommonLifetimes::new(&interners);
-        let common_consts = CommonConsts::new(&interners, &common_types);
-        let dep_graph = hir.dep_graph.clone();
-        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 def_path_tables = crates
-                .iter()
-                .map(|&cnum| (cnum, cstore.def_path_table(cnum)))
-                .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.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 {
-                def_path_table.add_def_path_hashes_to(cnum, &mut map);
-            }
-
-            Some(map)
-        } else {
-            None
-        };
-
-        let mut trait_map: FxHashMap<_, FxHashMap<_, _>> = FxHashMap::default();
-        for (k, v) in resolutions.trait_map {
-            let hir_id = hir.node_to_hir_id(k);
-            let map = trait_map.entry(hir_id.owner).or_default();
-            let v = v
-                .into_iter()
-                .map(|tc| tc.map_import_ids(|id| hir.definitions().node_to_hir_id(id)))
-                .collect();
-            map.insert(hir_id.local_id, StableVec::new(v));
-        }
-
-        GlobalCtxt {
-            sess: s,
-            lint_store,
-            cstore,
-            arena,
-            interners,
-            dep_graph,
-            prof: s.prof.clone(),
-            types: common_types,
-            lifetimes: common_lifetimes,
-            consts: common_consts,
-            extern_crate_map: resolutions.extern_crate_map,
-            trait_map,
-            export_map: resolutions
-                .export_map
-                .into_iter()
-                .map(|(k, v)| {
-                    let exports: Vec<_> =
-                        v.into_iter().map(|e| e.map_id(|id| hir.node_to_hir_id(id))).collect();
-                    (k, exports)
-                })
-                .collect(),
-            maybe_unused_trait_imports: resolutions
-                .maybe_unused_trait_imports
-                .into_iter()
-                .map(|id| hir.local_def_id_from_node_id(id))
-                .collect(),
-            maybe_unused_extern_crates: resolutions
-                .maybe_unused_extern_crates
-                .into_iter()
-                .map(|(id, sp)| (hir.local_def_id_from_node_id(id), sp))
-                .collect(),
-            glob_map: resolutions
-                .glob_map
-                .into_iter()
-                .map(|(id, names)| (hir.local_def_id_from_node_id(id), names))
-                .collect(),
-            extern_prelude: resolutions.extern_prelude,
-            hir_map: hir,
-            def_path_hash_to_def_id,
-            queries: query::Queries::new(providers, extern_providers, on_disk_query_result_cache),
-            rcache: Default::default(),
-            selection_cache: Default::default(),
-            evaluation_cache: Default::default(),
-            crate_name: Symbol::intern(crate_name),
-            data_layout,
-            layout_interner: Default::default(),
-            stability_interner: Default::default(),
-            const_stability_interner: Default::default(),
-            allocation_interner: Default::default(),
-            alloc_map: Lock::new(interpret::AllocMap::new()),
-            output_filenames: Arc::new(output_filenames.clone()),
-        }
-    }
-
-    pub fn consider_optimizing<T: Fn() -> String>(&self, msg: T) -> bool {
-        let cname = self.crate_name(LOCAL_CRATE).as_str();
-        self.sess.consider_optimizing(&cname, msg)
-    }
-
-    pub fn lib_features(self) -> &'tcx middle::lib_features::LibFeatures {
-        self.get_lib_features(LOCAL_CRATE)
-    }
-
-    /// Obtain all lang items of this crate and all dependencies (recursively)
-    pub fn lang_items(self) -> &'tcx middle::lang_items::LanguageItems {
-        self.get_lang_items(LOCAL_CRATE)
-    }
-
-    /// Obtain the given diagnostic item's `DefId`. Use `is_diagnostic_item` if you just want to
-    /// compare against another `DefId`, since `is_diagnostic_item` is cheaper.
-    pub fn get_diagnostic_item(self, name: Symbol) -> Option<DefId> {
-        self.all_diagnostic_items(LOCAL_CRATE).get(&name).copied()
-    }
-
-    /// Check whether the diagnostic item with the given `name` has the given `DefId`.
-    pub fn is_diagnostic_item(self, name: Symbol, did: DefId) -> bool {
-        self.diagnostic_items(did.krate).get(&name) == Some(&did)
-    }
-
-    pub fn stability(self) -> &'tcx stability::Index<'tcx> {
-        self.stability_index(LOCAL_CRATE)
-    }
-
-    pub fn crates(self) -> &'tcx [CrateNum] {
-        self.all_crate_nums(LOCAL_CRATE)
-    }
-
-    pub fn allocator_kind(self) -> Option<AllocatorKind> {
-        self.cstore.allocator_kind()
-    }
-
-    pub fn features(self) -> &'tcx rustc_feature::Features {
-        self.features_query(LOCAL_CRATE)
-    }
-
-    pub fn def_key(self, id: DefId) -> hir_map::DefKey {
-        if id.is_local() { self.hir().def_key(id) } else { self.cstore.def_key(id) }
-    }
-
-    /// Converts a `DefId` into its fully expanded `DefPath` (every
-    /// `DefId` is really just an interned `DefPath`).
-    ///
-    /// Note that if `id` is not local to this crate, the result will
-    ///  be a non-local `DefPath`.
-    pub fn def_path(self, id: DefId) -> hir_map::DefPath {
-        if id.is_local() { self.hir().def_path(id) } else { self.cstore.def_path(id) }
-    }
-
-    /// Returns whether or not the crate with CrateNum 'cnum'
-    /// is marked as a private dependency
-    pub fn is_private_dep(self, cnum: CrateNum) -> bool {
-        if cnum == LOCAL_CRATE { false } else { self.cstore.crate_is_private_dep_untracked(cnum) }
-    }
-
-    #[inline]
-    pub fn def_path_hash(self, def_id: DefId) -> hir_map::DefPathHash {
-        if def_id.is_local() {
-            self.hir().definitions().def_path_hash(def_id.index)
-        } else {
-            self.cstore.def_path_hash(def_id)
-        }
-    }
-
-    pub fn def_path_debug_str(self, def_id: DefId) -> String {
-        // We are explicitly not going through queries here in order to get
-        // crate name and disambiguator since this code is called from debug!()
-        // statements within the query system and we'd run into endless
-        // recursion otherwise.
-        let (crate_name, crate_disambiguator) = if def_id.is_local() {
-            (self.crate_name, self.sess.local_crate_disambiguator())
-        } else {
-            (
-                self.cstore.crate_name_untracked(def_id.krate),
-                self.cstore.crate_disambiguator_untracked(def_id.krate),
-            )
-        };
-
-        format!(
-            "{}[{}]{}",
-            crate_name,
-            // Don't print the whole crate disambiguator. That's just
-            // annoying in debug output.
-            &(crate_disambiguator.to_fingerprint().to_hex())[..4],
-            self.def_path(def_id).to_string_no_crate()
-        )
-    }
-
-    pub fn metadata_encoding_version(self) -> Vec<u8> {
-        self.cstore.metadata_encoding_version().to_vec()
-    }
-
-    pub fn encode_metadata(self) -> EncodedMetadata {
-        let _prof_timer = self.prof.generic_activity("generate_crate_metadata");
-        self.cstore.encode_metadata(self)
-    }
-
-    // Note that this is *untracked* and should only be used within the query
-    // system if the result is otherwise tracked through queries
-    pub fn cstore_as_any(self) -> &'tcx dyn Any {
-        self.cstore.as_any()
-    }
-
-    #[inline(always)]
-    pub fn create_stable_hashing_context(self) -> StableHashingContext<'tcx> {
-        let krate = self.gcx.hir_map.untracked_krate();
-
-        StableHashingContext::new(self.sess, krate, self.hir().definitions(), &*self.cstore)
-    }
-
-    // This method makes sure that we have a DepNode and a Fingerprint for
-    // every upstream crate. It needs to be called once right after the tcx is
-    // created.
-    // With full-fledged red/green, the method will probably become unnecessary
-    // as this will be done on-demand.
-    pub fn allocate_metadata_dep_nodes(self) {
-        // We cannot use the query versions of crates() and crate_hash(), since
-        // those would need the DepNodes that we are allocating here.
-        for cnum in self.cstore.crates_untracked() {
-            let dep_node = DepConstructor::CrateMetadata(self, cnum);
-            let crate_hash = self.cstore.crate_hash_untracked(cnum);
-            self.dep_graph.with_task(
-                dep_node,
-                self,
-                crate_hash,
-                |_, x| x, // No transformation needed
-                dep_graph::hash_result,
-            );
-        }
-    }
-
-    pub fn serialize_query_result_cache<E>(self, encoder: &mut E) -> Result<(), E::Error>
-    where
-        E: ty::codec::TyEncoder,
-    {
-        self.queries.on_disk_cache.serialize(self, encoder)
-    }
-
-    /// If `true`, we should use the MIR-based borrowck, but also
-    /// fall back on the AST borrowck if the MIR-based one errors.
-    pub fn migrate_borrowck(self) -> bool {
-        self.borrowck_mode().migrate()
-    }
-
-    /// What mode(s) of borrowck should we run? AST? MIR? both?
-    /// (Also considers the `#![feature(nll)]` setting.)
-    pub fn borrowck_mode(&self) -> BorrowckMode {
-        // Here are the main constraints we need to deal with:
-        //
-        // 1. An opts.borrowck_mode of `BorrowckMode::Migrate` is
-        //    synonymous with no `-Z borrowck=...` flag at all.
-        //
-        // 2. We want to allow developers on the Nightly channel
-        //    to opt back into the "hard error" mode for NLL,
-        //    (which they can do via specifying `#![feature(nll)]`
-        //    explicitly in their crate).
-        //
-        // So, this precedence list is how pnkfelix chose to work with
-        // the above constraints:
-        //
-        // * `#![feature(nll)]` *always* means use NLL with hard
-        //   errors. (To simplify the code here, it now even overrides
-        //   a user's attempt to specify `-Z borrowck=compare`, which
-        //   we arguably do not need anymore and should remove.)
-        //
-        // * Otherwise, if no `-Z borrowck=...` then use migrate mode
-        //
-        // * Otherwise, use the behavior requested via `-Z borrowck=...`
-
-        if self.features().nll {
-            return BorrowckMode::Mir;
-        }
-
-        self.sess.opts.borrowck_mode
-    }
-
-    #[inline]
-    pub fn local_crate_exports_generics(self) -> bool {
-        debug_assert!(self.sess.opts.share_generics());
-
-        self.sess.crate_types.borrow().iter().any(|crate_type| {
-            match crate_type {
-                CrateType::Executable
-                | CrateType::Staticlib
-                | CrateType::ProcMacro
-                | CrateType::Cdylib => false,
-
-                // FIXME rust-lang/rust#64319, rust-lang/rust#64872:
-                // We want to block export of generics from dylibs,
-                // but we must fix rust-lang/rust#65890 before we can
-                // do that robustly.
-                CrateType::Dylib => true,
-
-                CrateType::Rlib => true,
-            }
-        })
-    }
-
-    // Returns the `DefId` and the `BoundRegion` corresponding to the given region.
-    pub fn is_suitable_region(&self, region: Region<'tcx>) -> Option<FreeRegionInfo> {
-        let (suitable_region_binding_scope, bound_region) = match *region {
-            ty::ReFree(ref free_region) => (free_region.scope, free_region.bound_region),
-            ty::ReEarlyBound(ref ebr) => {
-                (self.parent(ebr.def_id).unwrap(), ty::BoundRegion::BrNamed(ebr.def_id, ebr.name))
-            }
-            _ => return None, // not a free region
-        };
-
-        let hir_id = self.hir().as_local_hir_id(suitable_region_binding_scope).unwrap();
-        let is_impl_item = match self.hir().find(hir_id) {
-            Some(Node::Item(..)) | Some(Node::TraitItem(..)) => false,
-            Some(Node::ImplItem(..)) => {
-                self.is_bound_region_in_impl_item(suitable_region_binding_scope)
-            }
-            _ => return None,
-        };
-
-        return Some(FreeRegionInfo {
-            def_id: suitable_region_binding_scope,
-            boundregion: bound_region,
-            is_impl_item,
-        });
-    }
-
-    pub fn return_type_impl_trait(&self, scope_def_id: DefId) -> Option<(Ty<'tcx>, Span)> {
-        // HACK: `type_of_def_id()` will fail on these (#55796), so return `None`.
-        let hir_id = self.hir().as_local_hir_id(scope_def_id).unwrap();
-        match self.hir().get(hir_id) {
-            Node::Item(item) => {
-                match item.kind {
-                    ItemKind::Fn(..) => { /* `type_of_def_id()` will work */ }
-                    _ => {
-                        return None;
-                    }
-                }
-            }
-            _ => { /* `type_of_def_id()` will work or panic */ }
-        }
-
-        let ret_ty = self.type_of(scope_def_id);
-        match ret_ty.kind {
-            ty::FnDef(_, _) => {
-                let sig = ret_ty.fn_sig(*self);
-                let output = self.erase_late_bound_regions(&sig.output());
-                if output.is_impl_trait() {
-                    let fn_decl = self.hir().fn_decl_by_hir_id(hir_id).unwrap();
-                    Some((output, fn_decl.output.span()))
-                } else {
-                    None
-                }
-            }
-            _ => None,
-        }
-    }
-
-    // Checks if the bound region is in Impl Item.
-    pub fn is_bound_region_in_impl_item(&self, suitable_region_binding_scope: DefId) -> bool {
-        let container_id = self.associated_item(suitable_region_binding_scope).container.id();
-        if self.impl_trait_ref(container_id).is_some() {
-            // For now, we do not try to target impls of traits. This is
-            // because this message is going to suggest that the user
-            // change the fn signature, but they may not be free to do so,
-            // since the signature must match the trait.
-            //
-            // FIXME(#42706) -- in some cases, we could do better here.
-            return true;
-        }
-        false
-    }
-
-    /// Determines whether identifiers in the assembly have strict naming rules.
-    /// Currently, only NVPTX* targets need it.
-    pub fn has_strict_asm_symbol_naming(&self) -> bool {
-        self.sess.target.target.arch.contains("nvptx")
-    }
-
-    /// Returns `&'static core::panic::Location<'static>`.
-    pub fn caller_location_ty(&self) -> Ty<'tcx> {
-        self.mk_imm_ref(
-            self.lifetimes.re_static,
-            self.type_of(self.require_lang_item(PanicLocationLangItem, None))
-                .subst(*self, self.mk_substs([self.lifetimes.re_static.into()].iter())),
-        )
-    }
-
-    /// Returns a displayable description and article for the given `def_id` (e.g. `("a", "struct")`).
-    pub fn article_and_description(&self, def_id: DefId) -> (&'static str, &'static str) {
-        match self.def_key(def_id).disambiguated_data.data {
-            DefPathData::TypeNs(..) | DefPathData::ValueNs(..) | DefPathData::MacroNs(..) => {
-                let kind = self.def_kind(def_id).unwrap();
-                (kind.article(), kind.descr(def_id))
-            }
-            DefPathData::ClosureExpr => match self.generator_kind(def_id) {
-                None => ("a", "closure"),
-                Some(rustc_hir::GeneratorKind::Async(..)) => ("an", "async closure"),
-                Some(rustc_hir::GeneratorKind::Gen) => ("a", "generator"),
-            },
-            DefPathData::LifetimeNs(..) => ("a", "lifetime"),
-            DefPathData::Impl => ("an", "implementation"),
-            _ => bug!("article_and_description called on def_id {:?}", def_id),
-        }
-    }
-}
-
-impl<'tcx> GlobalCtxt<'tcx> {
-    /// Calls the closure with a local `TyCtxt` using the given arena.
-    /// `interners` is a slot passed so we can create a CtxtInterners
-    /// with the same lifetime as `arena`.
-    pub fn enter_local<F, R>(&'tcx self, f: F) -> R
-    where
-        F: FnOnce(TyCtxt<'tcx>) -> R,
-    {
-        let tcx = TyCtxt { gcx: self };
-        ty::tls::with_related_context(tcx, |icx| {
-            let new_icx = ty::tls::ImplicitCtxt {
-                tcx,
-                query: icx.query,
-                diagnostics: icx.diagnostics,
-                layout_depth: icx.layout_depth,
-                task_deps: icx.task_deps,
-            };
-            ty::tls::enter_context(&new_icx, |_| f(tcx))
-        })
-    }
-}
-
-/// A trait implemented for all `X<'a>` types that can be safely and
-/// efficiently converted to `X<'tcx>` as long as they are part of the
-/// provided `TyCtxt<'tcx>`.
-/// This can be done, for example, for `Ty<'tcx>` or `SubstsRef<'tcx>`
-/// by looking them up in their respective interners.
-///
-/// However, this is still not the best implementation as it does
-/// need to compare the components, even for interned values.
-/// It would be more efficient if `TypedArena` provided a way to
-/// determine whether the address is in the allocated range.
-///
-/// `None` is returned if the value or one of the components is not part
-/// of the provided context.
-/// For `Ty`, `None` can be returned if either the type interner doesn't
-/// contain the `TyKind` key or if the address of the interned
-/// pointer differs. The latter case is possible if a primitive type,
-/// e.g., `()` or `u8`, was interned in a different context.
-pub trait Lift<'tcx>: fmt::Debug {
-    type Lifted: fmt::Debug + 'tcx;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted>;
-}
-
-macro_rules! nop_lift {
-    ($set:ident; $ty:ty => $lifted:ty) => {
-        impl<'a, 'tcx> Lift<'tcx> for $ty {
-            type Lifted = $lifted;
-            fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-                if tcx.interners.$set.contains_pointer_to(&Interned(*self)) {
-                    Some(unsafe { mem::transmute(*self) })
-                } else {
-                    None
-                }
-            }
-        }
-    };
-}
-
-macro_rules! nop_list_lift {
-    ($set:ident; $ty:ty => $lifted:ty) => {
-        impl<'a, 'tcx> Lift<'tcx> for &'a List<$ty> {
-            type Lifted = &'tcx List<$lifted>;
-            fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-                if self.is_empty() {
-                    return Some(List::empty());
-                }
-                if tcx.interners.$set.contains_pointer_to(&Interned(*self)) {
-                    Some(unsafe { mem::transmute(*self) })
-                } else {
-                    None
-                }
-            }
-        }
-    };
-}
-
-nop_lift! {type_; Ty<'a> => Ty<'tcx>}
-nop_lift! {region; Region<'a> => Region<'tcx>}
-nop_lift! {goal; Goal<'a> => Goal<'tcx>}
-nop_lift! {const_; &'a Const<'a> => &'tcx Const<'tcx>}
-
-nop_list_lift! {goal_list; Goal<'a> => Goal<'tcx>}
-nop_list_lift! {clauses; Clause<'a> => Clause<'tcx>}
-nop_list_lift! {type_list; Ty<'a> => Ty<'tcx>}
-nop_list_lift! {existential_predicates; ExistentialPredicate<'a> => ExistentialPredicate<'tcx>}
-nop_list_lift! {predicates; Predicate<'a> => Predicate<'tcx>}
-nop_list_lift! {canonical_var_infos; CanonicalVarInfo => CanonicalVarInfo}
-nop_list_lift! {projs; ProjectionKind => ProjectionKind}
-
-// This is the impl for `&'a InternalSubsts<'a>`.
-nop_list_lift! {substs; GenericArg<'a> => GenericArg<'tcx>}
-
-pub mod tls {
-    use super::{ptr_eq, GlobalCtxt, TyCtxt};
-
-    use crate::dep_graph::TaskDeps;
-    use crate::ty::query;
-    use rustc_data_structures::sync::{self, Lock};
-    use rustc_data_structures::thin_vec::ThinVec;
-    use rustc_data_structures::OnDrop;
-    use rustc_errors::Diagnostic;
-    use std::mem;
-
-    #[cfg(not(parallel_compiler))]
-    use std::cell::Cell;
-
-    #[cfg(parallel_compiler)]
-    use rustc_rayon_core as rayon_core;
-
-    /// This is the implicit state of rustc. It contains the current
-    /// `TyCtxt` and query. It is updated when creating a local interner or
-    /// executing a new query. Whenever there's a `TyCtxt` value available
-    /// you should also have access to an `ImplicitCtxt` through the functions
-    /// in this module.
-    #[derive(Clone)]
-    pub struct ImplicitCtxt<'a, 'tcx> {
-        /// The current `TyCtxt`. Initially created by `enter_global` and updated
-        /// by `enter_local` with a new local interner.
-        pub tcx: TyCtxt<'tcx>,
-
-        /// The current query job, if any. This is updated by `JobOwner::start` in
-        /// `ty::query::plumbing` when executing a query.
-        pub query: Option<query::QueryJobId>,
-
-        /// Where to store diagnostics for the current query job, if any.
-        /// This is updated by `JobOwner::start` in `ty::query::plumbing` when executing a query.
-        pub diagnostics: Option<&'a Lock<ThinVec<Diagnostic>>>,
-
-        /// Used to prevent layout from recursing too deeply.
-        pub layout_depth: usize,
-
-        /// The current dep graph task. This is used to add dependencies to queries
-        /// when executing them.
-        pub task_deps: Option<&'a Lock<TaskDeps>>,
-    }
-
-    /// Sets Rayon's thread-local variable, which is preserved for Rayon jobs
-    /// to `value` during the call to `f`. It is restored to its previous value after.
-    /// This is used to set the pointer to the new `ImplicitCtxt`.
-    #[cfg(parallel_compiler)]
-    #[inline]
-    fn set_tlv<F: FnOnce() -> R, R>(value: usize, f: F) -> R {
-        rayon_core::tlv::with(value, f)
-    }
-
-    /// Gets Rayon's thread-local variable, which is preserved for Rayon jobs.
-    /// This is used to get the pointer to the current `ImplicitCtxt`.
-    #[cfg(parallel_compiler)]
-    #[inline]
-    fn get_tlv() -> usize {
-        rayon_core::tlv::get()
-    }
-
-    #[cfg(not(parallel_compiler))]
-    thread_local! {
-        /// A thread local variable that stores a pointer to the current `ImplicitCtxt`.
-        static TLV: Cell<usize> = Cell::new(0);
-    }
-
-    /// Sets TLV to `value` during the call to `f`.
-    /// It is restored to its previous value after.
-    /// This is used to set the pointer to the new `ImplicitCtxt`.
-    #[cfg(not(parallel_compiler))]
-    #[inline]
-    fn set_tlv<F: FnOnce() -> R, R>(value: usize, f: F) -> R {
-        let old = get_tlv();
-        let _reset = OnDrop(move || TLV.with(|tlv| tlv.set(old)));
-        TLV.with(|tlv| tlv.set(value));
-        f()
-    }
-
-    /// Gets the pointer to the current `ImplicitCtxt`.
-    #[cfg(not(parallel_compiler))]
-    #[inline]
-    fn get_tlv() -> usize {
-        TLV.with(|tlv| tlv.get())
-    }
-
-    /// Sets `context` as the new current `ImplicitCtxt` for the duration of the function `f`.
-    #[inline]
-    pub fn enter_context<'a, 'tcx, F, R>(context: &ImplicitCtxt<'a, 'tcx>, f: F) -> R
-    where
-        F: FnOnce(&ImplicitCtxt<'a, 'tcx>) -> R,
-    {
-        set_tlv(context as *const _ as usize, || f(&context))
-    }
-
-    /// Enters `GlobalCtxt` by setting up libsyntax callbacks and
-    /// creating a initial `TyCtxt` and `ImplicitCtxt`.
-    /// This happens once per rustc session and `TyCtxt`s only exists
-    /// inside the `f` function.
-    pub fn enter_global<'tcx, F, R>(gcx: &'tcx GlobalCtxt<'tcx>, f: F) -> R
-    where
-        F: FnOnce(TyCtxt<'tcx>) -> R,
-    {
-        // Update `GCX_PTR` to indicate there's a `GlobalCtxt` available.
-        GCX_PTR.with(|lock| {
-            *lock.lock() = gcx as *const _ as usize;
-        });
-        // Set `GCX_PTR` back to 0 when we exit.
-        let _on_drop = OnDrop(move || {
-            GCX_PTR.with(|lock| *lock.lock() = 0);
-        });
-
-        let tcx = TyCtxt { gcx };
-        let icx =
-            ImplicitCtxt { tcx, query: None, diagnostics: None, layout_depth: 0, task_deps: None };
-        enter_context(&icx, |_| f(tcx))
-    }
-
-    scoped_thread_local! {
-        /// Stores a pointer to the `GlobalCtxt` if one is available.
-        /// This is used to access the `GlobalCtxt` in the deadlock handler given to Rayon.
-        pub static GCX_PTR: Lock<usize>
-    }
-
-    /// Creates a `TyCtxt` and `ImplicitCtxt` based on the `GCX_PTR` thread local.
-    /// This is used in the deadlock handler.
-    pub unsafe fn with_global<F, R>(f: F) -> R
-    where
-        F: for<'tcx> FnOnce(TyCtxt<'tcx>) -> R,
-    {
-        let gcx = GCX_PTR.with(|lock| *lock.lock());
-        assert!(gcx != 0);
-        let gcx = &*(gcx as *const GlobalCtxt<'_>);
-        let tcx = TyCtxt { gcx };
-        let icx =
-            ImplicitCtxt { query: None, diagnostics: None, tcx, layout_depth: 0, task_deps: None };
-        enter_context(&icx, |_| f(tcx))
-    }
-
-    /// Allows access to the current `ImplicitCtxt` in a closure if one is available.
-    #[inline]
-    pub fn with_context_opt<F, R>(f: F) -> R
-    where
-        F: for<'a, 'tcx> FnOnce(Option<&ImplicitCtxt<'a, 'tcx>>) -> R,
-    {
-        let context = get_tlv();
-        if context == 0 {
-            f(None)
-        } else {
-            // We could get a `ImplicitCtxt` pointer from another thread.
-            // Ensure that `ImplicitCtxt` is `Sync`.
-            sync::assert_sync::<ImplicitCtxt<'_, '_>>();
-
-            unsafe { f(Some(&*(context as *const ImplicitCtxt<'_, '_>))) }
-        }
-    }
-
-    /// Allows access to the current `ImplicitCtxt`.
-    /// Panics if there is no `ImplicitCtxt` available.
-    #[inline]
-    pub fn with_context<F, R>(f: F) -> R
-    where
-        F: for<'a, 'tcx> FnOnce(&ImplicitCtxt<'a, 'tcx>) -> R,
-    {
-        with_context_opt(|opt_context| f(opt_context.expect("no ImplicitCtxt stored in tls")))
-    }
-
-    /// Allows access to the current `ImplicitCtxt` whose tcx field has the same global
-    /// interner as the tcx argument passed in. This means the closure is given an `ImplicitCtxt`
-    /// with the same `'tcx` lifetime as the `TyCtxt` passed in.
-    /// This will panic if you pass it a `TyCtxt` which has a different global interner from
-    /// the current `ImplicitCtxt`'s `tcx` field.
-    #[inline]
-    pub fn with_related_context<'tcx, F, R>(tcx: TyCtxt<'tcx>, f: F) -> R
-    where
-        F: FnOnce(&ImplicitCtxt<'_, 'tcx>) -> R,
-    {
-        with_context(|context| unsafe {
-            assert!(ptr_eq(context.tcx.gcx, tcx.gcx));
-            let context: &ImplicitCtxt<'_, '_> = mem::transmute(context);
-            f(context)
-        })
-    }
-
-    /// Allows access to the `TyCtxt` in the current `ImplicitCtxt`.
-    /// Panics if there is no `ImplicitCtxt` available.
-    #[inline]
-    pub fn with<F, R>(f: F) -> R
-    where
-        F: for<'tcx> FnOnce(TyCtxt<'tcx>) -> R,
-    {
-        with_context(|context| f(context.tcx))
-    }
-
-    /// Allows access to the `TyCtxt` in the current `ImplicitCtxt`.
-    /// The closure is passed None if there is no `ImplicitCtxt` available.
-    #[inline]
-    pub fn with_opt<F, R>(f: F) -> R
-    where
-        F: for<'tcx> FnOnce(Option<TyCtxt<'tcx>>) -> R,
-    {
-        with_context_opt(|opt_context| f(opt_context.map(|context| context.tcx)))
-    }
-}
-
-macro_rules! sty_debug_print {
-    ($ctxt: expr, $($variant: ident),*) => {{
-        // Curious inner module to allow variant names to be used as
-        // variable names.
-        #[allow(non_snake_case)]
-        mod inner {
-            use crate::ty::{self, TyCtxt};
-            use crate::ty::context::Interned;
-
-            #[derive(Copy, Clone)]
-            struct DebugStat {
-                total: usize,
-                lt_infer: usize,
-                ty_infer: usize,
-                ct_infer: usize,
-                all_infer: usize,
-            }
-
-            pub fn go(tcx: TyCtxt<'_>) {
-                let mut total = DebugStat {
-                    total: 0,
-                    lt_infer: 0,
-                    ty_infer: 0,
-                    ct_infer: 0,
-                    all_infer: 0,
-                };
-                $(let mut $variant = total;)*
-
-                let shards = tcx.interners.type_.lock_shards();
-                let types = shards.iter().flat_map(|shard| shard.keys());
-                for &Interned(t) in types {
-                    let variant = match t.kind {
-                        ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
-                            ty::Float(..) | ty::Str | ty::Never => continue,
-                        ty::Error => /* unimportant */ continue,
-                        $(ty::$variant(..) => &mut $variant,)*
-                    };
-                    let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
-                    let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
-                    let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
-
-                    variant.total += 1;
-                    total.total += 1;
-                    if lt { total.lt_infer += 1; variant.lt_infer += 1 }
-                    if ty { total.ty_infer += 1; variant.ty_infer += 1 }
-                    if ct { total.ct_infer += 1; variant.ct_infer += 1 }
-                    if lt && ty && ct { total.all_infer += 1; variant.all_infer += 1 }
-                }
-                println!("Ty interner             total           ty lt ct all");
-                $(println!("    {:18}: {uses:6} {usespc:4.1}%, \
-                            {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
-                    stringify!($variant),
-                    uses = $variant.total,
-                    usespc = $variant.total as f64 * 100.0 / total.total as f64,
-                    ty = $variant.ty_infer as f64 * 100.0  / total.total as f64,
-                    lt = $variant.lt_infer as f64 * 100.0  / total.total as f64,
-                    ct = $variant.ct_infer as f64 * 100.0  / total.total as f64,
-                    all = $variant.all_infer as f64 * 100.0  / total.total as f64);
-                )*
-                println!("                  total {uses:6}        \
-                          {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
-                    uses = total.total,
-                    ty = total.ty_infer as f64 * 100.0  / total.total as f64,
-                    lt = total.lt_infer as f64 * 100.0  / total.total as f64,
-                    ct = total.ct_infer as f64 * 100.0  / total.total as f64,
-                    all = total.all_infer as f64 * 100.0  / total.total as f64)
-            }
-        }
-
-        inner::go($ctxt)
-    }}
-}
-
-impl<'tcx> TyCtxt<'tcx> {
-    pub fn print_debug_stats(self) {
-        sty_debug_print!(
-            self,
-            Adt,
-            Array,
-            Slice,
-            RawPtr,
-            Ref,
-            FnDef,
-            FnPtr,
-            Placeholder,
-            Generator,
-            GeneratorWitness,
-            Dynamic,
-            Closure,
-            Tuple,
-            Bound,
-            Param,
-            Infer,
-            UnnormalizedProjection,
-            Projection,
-            Opaque,
-            Foreign
-        );
-
-        println!("InternalSubsts interner: #{}", self.interners.substs.len());
-        println!("Region interner: #{}", self.interners.region.len());
-        println!("Stability interner: #{}", self.stability_interner.len());
-        println!("Const Stability interner: #{}", self.const_stability_interner.len());
-        println!("Allocation interner: #{}", self.allocation_interner.len());
-        println!("Layout interner: #{}", self.layout_interner.len());
-    }
-}
-
-/// An entry in an interner.
-struct Interned<'tcx, T: ?Sized>(&'tcx T);
-
-impl<'tcx, T: 'tcx + ?Sized> Clone for Interned<'tcx, T> {
-    fn clone(&self) -> Self {
-        Interned(self.0)
-    }
-}
-impl<'tcx, T: 'tcx + ?Sized> Copy for Interned<'tcx, T> {}
-
-impl<'tcx, T: 'tcx + ?Sized> IntoPointer for Interned<'tcx, T> {
-    fn into_pointer(&self) -> *const () {
-        self.0 as *const _ as *const ()
-    }
-}
-// N.B., an `Interned<Ty>` compares and hashes as a `TyKind`.
-impl<'tcx> PartialEq for Interned<'tcx, TyS<'tcx>> {
-    fn eq(&self, other: &Interned<'tcx, TyS<'tcx>>) -> bool {
-        self.0.kind == other.0.kind
-    }
-}
-
-impl<'tcx> Eq for Interned<'tcx, TyS<'tcx>> {}
-
-impl<'tcx> Hash for Interned<'tcx, TyS<'tcx>> {
-    fn hash<H: Hasher>(&self, s: &mut H) {
-        self.0.kind.hash(s)
-    }
-}
-
-#[allow(rustc::usage_of_ty_tykind)]
-impl<'tcx> Borrow<TyKind<'tcx>> for Interned<'tcx, TyS<'tcx>> {
-    fn borrow<'a>(&'a self) -> &'a TyKind<'tcx> {
-        &self.0.kind
-    }
-}
-
-// N.B., an `Interned<List<T>>` compares and hashes as its elements.
-impl<'tcx, T: PartialEq> PartialEq for Interned<'tcx, List<T>> {
-    fn eq(&self, other: &Interned<'tcx, List<T>>) -> bool {
-        self.0[..] == other.0[..]
-    }
-}
-
-impl<'tcx, T: Eq> Eq for Interned<'tcx, List<T>> {}
-
-impl<'tcx, T: Hash> Hash for Interned<'tcx, List<T>> {
-    fn hash<H: Hasher>(&self, s: &mut H) {
-        self.0[..].hash(s)
-    }
-}
-
-impl<'tcx> Borrow<[Ty<'tcx>]> for Interned<'tcx, List<Ty<'tcx>>> {
-    fn borrow<'a>(&'a self) -> &'a [Ty<'tcx>] {
-        &self.0[..]
-    }
-}
-
-impl<'tcx> Borrow<[CanonicalVarInfo]> for Interned<'tcx, List<CanonicalVarInfo>> {
-    fn borrow(&self) -> &[CanonicalVarInfo] {
-        &self.0[..]
-    }
-}
-
-impl<'tcx> Borrow<[GenericArg<'tcx>]> for Interned<'tcx, InternalSubsts<'tcx>> {
-    fn borrow<'a>(&'a self) -> &'a [GenericArg<'tcx>] {
-        &self.0[..]
-    }
-}
-
-impl<'tcx> Borrow<[ProjectionKind]> for Interned<'tcx, List<ProjectionKind>> {
-    fn borrow(&self) -> &[ProjectionKind] {
-        &self.0[..]
-    }
-}
-
-impl<'tcx> Borrow<[PlaceElem<'tcx>]> for Interned<'tcx, List<PlaceElem<'tcx>>> {
-    fn borrow(&self) -> &[PlaceElem<'tcx>] {
-        &self.0[..]
-    }
-}
-
-impl<'tcx> Borrow<RegionKind> for Interned<'tcx, RegionKind> {
-    fn borrow(&self) -> &RegionKind {
-        &self.0
-    }
-}
-
-impl<'tcx> Borrow<GoalKind<'tcx>> for Interned<'tcx, GoalKind<'tcx>> {
-    fn borrow<'a>(&'a self) -> &'a GoalKind<'tcx> {
-        &self.0
-    }
-}
-
-impl<'tcx> Borrow<[ExistentialPredicate<'tcx>]>
-    for Interned<'tcx, List<ExistentialPredicate<'tcx>>>
-{
-    fn borrow<'a>(&'a self) -> &'a [ExistentialPredicate<'tcx>] {
-        &self.0[..]
-    }
-}
-
-impl<'tcx> Borrow<[Predicate<'tcx>]> for Interned<'tcx, List<Predicate<'tcx>>> {
-    fn borrow<'a>(&'a self) -> &'a [Predicate<'tcx>] {
-        &self.0[..]
-    }
-}
-
-impl<'tcx> Borrow<Const<'tcx>> for Interned<'tcx, Const<'tcx>> {
-    fn borrow<'a>(&'a self) -> &'a Const<'tcx> {
-        &self.0
-    }
-}
-
-impl<'tcx> Borrow<[Clause<'tcx>]> for Interned<'tcx, List<Clause<'tcx>>> {
-    fn borrow<'a>(&'a self) -> &'a [Clause<'tcx>] {
-        &self.0[..]
-    }
-}
-
-impl<'tcx> Borrow<[Goal<'tcx>]> for Interned<'tcx, List<Goal<'tcx>>> {
-    fn borrow<'a>(&'a self) -> &'a [Goal<'tcx>] {
-        &self.0[..]
-    }
-}
-
-macro_rules! direct_interners {
-    ($($name:ident: $method:ident($ty:ty)),+) => {
-        $(impl<'tcx> PartialEq for Interned<'tcx, $ty> {
-            fn eq(&self, other: &Self) -> bool {
-                self.0 == other.0
-            }
-        }
-
-        impl<'tcx> Eq for Interned<'tcx, $ty> {}
-
-        impl<'tcx> Hash for Interned<'tcx, $ty> {
-            fn hash<H: Hasher>(&self, s: &mut H) {
-                self.0.hash(s)
-            }
-        }
-
-        impl<'tcx> TyCtxt<'tcx> {
-            pub fn $method(self, v: $ty) -> &'tcx $ty {
-                self.interners.$name.intern_ref(&v, || {
-                    Interned(self.interners.arena.alloc(v))
-                }).0
-            }
-        })+
-    }
-}
-
-pub fn keep_local<'tcx, T: ty::TypeFoldable<'tcx>>(x: &T) -> bool {
-    x.has_type_flags(ty::TypeFlags::KEEP_IN_LOCAL_TCX)
-}
-
-direct_interners!(
-    region: mk_region(RegionKind),
-    goal: mk_goal(GoalKind<'tcx>),
-    const_: mk_const(Const<'tcx>)
-);
-
-macro_rules! slice_interners {
-    ($($field:ident: $method:ident($ty:ty)),+) => (
-        $(impl<'tcx> TyCtxt<'tcx> {
-            pub fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
-                self.interners.$field.intern_ref(v, || {
-                    Interned(List::from_arena(&*self.arena, v))
-                }).0
-            }
-        })+
-    );
-}
-
-slice_interners!(
-    type_list: _intern_type_list(Ty<'tcx>),
-    substs: _intern_substs(GenericArg<'tcx>),
-    canonical_var_infos: _intern_canonical_var_infos(CanonicalVarInfo),
-    existential_predicates: _intern_existential_predicates(ExistentialPredicate<'tcx>),
-    predicates: _intern_predicates(Predicate<'tcx>),
-    clauses: _intern_clauses(Clause<'tcx>),
-    goal_list: _intern_goals(Goal<'tcx>),
-    projs: _intern_projs(ProjectionKind),
-    place_elems: _intern_place_elems(PlaceElem<'tcx>)
-);
-
-impl<'tcx> TyCtxt<'tcx> {
-    /// Given a `fn` type, returns an equivalent `unsafe fn` type;
-    /// that is, a `fn` type that is equivalent in every way for being
-    /// unsafe.
-    pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
-        assert_eq!(sig.unsafety(), hir::Unsafety::Normal);
-        self.mk_fn_ptr(sig.map_bound(|sig| ty::FnSig { unsafety: hir::Unsafety::Unsafe, ..sig }))
-    }
-
-    /// Given a closure signature `sig`, returns an equivalent `fn`
-    /// type with the same signature. Detuples and so forth -- so
-    /// e.g., if we have a sig with `Fn<(u32, i32)>` then you would get
-    /// a `fn(u32, i32)`.
-    /// `unsafety` determines the unsafety of the `fn` type. If you pass
-    /// `hir::Unsafety::Unsafe` in the previous example, then you would get
-    /// an `unsafe fn (u32, i32)`.
-    /// It cannot convert a closure that requires unsafe.
-    pub fn coerce_closure_fn_ty(self, sig: PolyFnSig<'tcx>, unsafety: hir::Unsafety) -> Ty<'tcx> {
-        let converted_sig = sig.map_bound(|s| {
-            let params_iter = match s.inputs()[0].kind {
-                ty::Tuple(params) => params.into_iter().map(|k| k.expect_ty()),
-                _ => bug!(),
-            };
-            self.mk_fn_sig(params_iter, s.output(), s.c_variadic, unsafety, abi::Abi::Rust)
-        });
-
-        self.mk_fn_ptr(converted_sig)
-    }
-
-    #[allow(rustc::usage_of_ty_tykind)]
-    #[inline]
-    pub fn mk_ty(&self, st: TyKind<'tcx>) -> Ty<'tcx> {
-        self.interners.intern_ty(st)
-    }
-
-    pub fn mk_mach_int(self, tm: ast::IntTy) -> Ty<'tcx> {
-        match tm {
-            ast::IntTy::Isize => self.types.isize,
-            ast::IntTy::I8 => self.types.i8,
-            ast::IntTy::I16 => self.types.i16,
-            ast::IntTy::I32 => self.types.i32,
-            ast::IntTy::I64 => self.types.i64,
-            ast::IntTy::I128 => self.types.i128,
-        }
-    }
-
-    pub fn mk_mach_uint(self, tm: ast::UintTy) -> Ty<'tcx> {
-        match tm {
-            ast::UintTy::Usize => self.types.usize,
-            ast::UintTy::U8 => self.types.u8,
-            ast::UintTy::U16 => self.types.u16,
-            ast::UintTy::U32 => self.types.u32,
-            ast::UintTy::U64 => self.types.u64,
-            ast::UintTy::U128 => self.types.u128,
-        }
-    }
-
-    pub fn mk_mach_float(self, tm: ast::FloatTy) -> Ty<'tcx> {
-        match tm {
-            ast::FloatTy::F32 => self.types.f32,
-            ast::FloatTy::F64 => self.types.f64,
-        }
-    }
-
-    #[inline]
-    pub fn mk_str(self) -> Ty<'tcx> {
-        self.mk_ty(Str)
-    }
-
-    #[inline]
-    pub fn mk_static_str(self) -> Ty<'tcx> {
-        self.mk_imm_ref(self.lifetimes.re_static, self.mk_str())
-    }
-
-    #[inline]
-    pub fn mk_adt(self, def: &'tcx AdtDef, substs: SubstsRef<'tcx>) -> Ty<'tcx> {
-        // Take a copy of substs so that we own the vectors inside.
-        self.mk_ty(Adt(def, substs))
-    }
-
-    #[inline]
-    pub fn mk_foreign(self, def_id: DefId) -> Ty<'tcx> {
-        self.mk_ty(Foreign(def_id))
-    }
-
-    fn mk_generic_adt(self, wrapper_def_id: DefId, ty_param: Ty<'tcx>) -> Ty<'tcx> {
-        let adt_def = self.adt_def(wrapper_def_id);
-        let substs =
-            InternalSubsts::for_item(self, wrapper_def_id, |param, substs| match param.kind {
-                GenericParamDefKind::Lifetime | GenericParamDefKind::Const => bug!(),
-                GenericParamDefKind::Type { has_default, .. } => {
-                    if param.index == 0 {
-                        ty_param.into()
-                    } else {
-                        assert!(has_default);
-                        self.type_of(param.def_id).subst(self, substs).into()
-                    }
-                }
-            });
-        self.mk_ty(Adt(adt_def, substs))
-    }
-
-    #[inline]
-    pub fn mk_box(self, ty: Ty<'tcx>) -> Ty<'tcx> {
-        let def_id = self.require_lang_item(lang_items::OwnedBoxLangItem, None);
-        self.mk_generic_adt(def_id, ty)
-    }
-
-    #[inline]
-    pub fn mk_lang_item(self, ty: Ty<'tcx>, item: lang_items::LangItem) -> Option<Ty<'tcx>> {
-        let def_id = self.lang_items().require(item).ok()?;
-        Some(self.mk_generic_adt(def_id, ty))
-    }
-
-    #[inline]
-    pub fn mk_maybe_uninit(self, ty: Ty<'tcx>) -> Ty<'tcx> {
-        let def_id = self.require_lang_item(lang_items::MaybeUninitLangItem, None);
-        self.mk_generic_adt(def_id, ty)
-    }
-
-    #[inline]
-    pub fn mk_ptr(self, tm: TypeAndMut<'tcx>) -> Ty<'tcx> {
-        self.mk_ty(RawPtr(tm))
-    }
-
-    #[inline]
-    pub fn mk_ref(self, r: Region<'tcx>, tm: TypeAndMut<'tcx>) -> Ty<'tcx> {
-        self.mk_ty(Ref(r, tm.ty, tm.mutbl))
-    }
-
-    #[inline]
-    pub fn mk_mut_ref(self, r: Region<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
-        self.mk_ref(r, TypeAndMut { ty: ty, mutbl: hir::Mutability::Mut })
-    }
-
-    #[inline]
-    pub fn mk_imm_ref(self, r: Region<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
-        self.mk_ref(r, TypeAndMut { ty: ty, mutbl: hir::Mutability::Not })
-    }
-
-    #[inline]
-    pub fn mk_mut_ptr(self, ty: Ty<'tcx>) -> Ty<'tcx> {
-        self.mk_ptr(TypeAndMut { ty: ty, mutbl: hir::Mutability::Mut })
-    }
-
-    #[inline]
-    pub fn mk_imm_ptr(self, ty: Ty<'tcx>) -> Ty<'tcx> {
-        self.mk_ptr(TypeAndMut { ty: ty, mutbl: hir::Mutability::Not })
-    }
-
-    #[inline]
-    pub fn mk_nil_ptr(self) -> Ty<'tcx> {
-        self.mk_imm_ptr(self.mk_unit())
-    }
-
-    #[inline]
-    pub fn mk_array(self, ty: Ty<'tcx>, n: u64) -> Ty<'tcx> {
-        self.mk_ty(Array(ty, ty::Const::from_usize(self, n)))
-    }
-
-    #[inline]
-    pub fn mk_slice(self, ty: Ty<'tcx>) -> Ty<'tcx> {
-        self.mk_ty(Slice(ty))
-    }
-
-    #[inline]
-    pub fn intern_tup(self, ts: &[Ty<'tcx>]) -> Ty<'tcx> {
-        let kinds: Vec<_> = ts.into_iter().map(|&t| GenericArg::from(t)).collect();
-        self.mk_ty(Tuple(self.intern_substs(&kinds)))
-    }
-
-    pub fn mk_tup<I: InternAs<[Ty<'tcx>], Ty<'tcx>>>(self, iter: I) -> I::Output {
-        iter.intern_with(|ts| {
-            let kinds: Vec<_> = ts.into_iter().map(|&t| GenericArg::from(t)).collect();
-            self.mk_ty(Tuple(self.intern_substs(&kinds)))
-        })
-    }
-
-    #[inline]
-    pub fn mk_unit(self) -> Ty<'tcx> {
-        self.types.unit
-    }
-
-    #[inline]
-    pub fn mk_diverging_default(self) -> Ty<'tcx> {
-        if self.features().never_type_fallback { self.types.never } else { self.types.unit }
-    }
-
-    #[inline]
-    pub fn mk_bool(self) -> Ty<'tcx> {
-        self.mk_ty(Bool)
-    }
-
-    #[inline]
-    pub fn mk_fn_def(self, def_id: DefId, substs: SubstsRef<'tcx>) -> Ty<'tcx> {
-        self.mk_ty(FnDef(def_id, substs))
-    }
-
-    #[inline]
-    pub fn mk_fn_ptr(self, fty: PolyFnSig<'tcx>) -> Ty<'tcx> {
-        self.mk_ty(FnPtr(fty))
-    }
-
-    #[inline]
-    pub fn mk_dynamic(
-        self,
-        obj: ty::Binder<&'tcx List<ExistentialPredicate<'tcx>>>,
-        reg: ty::Region<'tcx>,
-    ) -> Ty<'tcx> {
-        self.mk_ty(Dynamic(obj, reg))
-    }
-
-    #[inline]
-    pub fn mk_projection(self, item_def_id: DefId, substs: SubstsRef<'tcx>) -> Ty<'tcx> {
-        self.mk_ty(Projection(ProjectionTy { item_def_id, substs }))
-    }
-
-    #[inline]
-    pub fn mk_closure(self, closure_id: DefId, closure_substs: SubstsRef<'tcx>) -> Ty<'tcx> {
-        self.mk_ty(Closure(closure_id, closure_substs))
-    }
-
-    #[inline]
-    pub fn mk_generator(
-        self,
-        id: DefId,
-        generator_substs: SubstsRef<'tcx>,
-        movability: hir::Movability,
-    ) -> Ty<'tcx> {
-        self.mk_ty(Generator(id, generator_substs, movability))
-    }
-
-    #[inline]
-    pub fn mk_generator_witness(self, types: ty::Binder<&'tcx List<Ty<'tcx>>>) -> Ty<'tcx> {
-        self.mk_ty(GeneratorWitness(types))
-    }
-
-    #[inline]
-    pub fn mk_ty_var(self, v: TyVid) -> Ty<'tcx> {
-        self.mk_ty_infer(TyVar(v))
-    }
-
-    #[inline]
-    pub fn mk_const_var(self, v: ConstVid<'tcx>, ty: Ty<'tcx>) -> &'tcx Const<'tcx> {
-        self.mk_const(ty::Const { val: ty::ConstKind::Infer(InferConst::Var(v)), ty })
-    }
-
-    #[inline]
-    pub fn mk_int_var(self, v: IntVid) -> Ty<'tcx> {
-        self.mk_ty_infer(IntVar(v))
-    }
-
-    #[inline]
-    pub fn mk_float_var(self, v: FloatVid) -> Ty<'tcx> {
-        self.mk_ty_infer(FloatVar(v))
-    }
-
-    #[inline]
-    pub fn mk_ty_infer(self, it: InferTy) -> Ty<'tcx> {
-        self.mk_ty(Infer(it))
-    }
-
-    #[inline]
-    pub fn mk_const_infer(self, ic: InferConst<'tcx>, ty: Ty<'tcx>) -> &'tcx ty::Const<'tcx> {
-        self.mk_const(ty::Const { val: ty::ConstKind::Infer(ic), ty })
-    }
-
-    #[inline]
-    pub fn mk_ty_param(self, index: u32, name: Symbol) -> Ty<'tcx> {
-        self.mk_ty(Param(ParamTy { index, name: name }))
-    }
-
-    #[inline]
-    pub fn mk_const_param(self, index: u32, name: Symbol, ty: Ty<'tcx>) -> &'tcx Const<'tcx> {
-        self.mk_const(ty::Const { val: ty::ConstKind::Param(ParamConst { index, name }), ty })
-    }
-
-    pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
-        match param.kind {
-            GenericParamDefKind::Lifetime => {
-                self.mk_region(ty::ReEarlyBound(param.to_early_bound_region_data())).into()
-            }
-            GenericParamDefKind::Type { .. } => self.mk_ty_param(param.index, param.name).into(),
-            GenericParamDefKind::Const => {
-                self.mk_const_param(param.index, param.name, self.type_of(param.def_id)).into()
-            }
-        }
-    }
-
-    #[inline]
-    pub fn mk_opaque(self, def_id: DefId, substs: SubstsRef<'tcx>) -> Ty<'tcx> {
-        self.mk_ty(Opaque(def_id, substs))
-    }
-
-    pub fn mk_place_field(self, place: Place<'tcx>, f: Field, ty: Ty<'tcx>) -> Place<'tcx> {
-        self.mk_place_elem(place, PlaceElem::Field(f, ty))
-    }
-
-    pub fn mk_place_deref(self, place: Place<'tcx>) -> Place<'tcx> {
-        self.mk_place_elem(place, PlaceElem::Deref)
-    }
-
-    pub fn mk_place_downcast(
-        self,
-        place: Place<'tcx>,
-        adt_def: &'tcx AdtDef,
-        variant_index: VariantIdx,
-    ) -> Place<'tcx> {
-        self.mk_place_elem(
-            place,
-            PlaceElem::Downcast(Some(adt_def.variants[variant_index].ident.name), variant_index),
-        )
-    }
-
-    pub fn mk_place_downcast_unnamed(
-        self,
-        place: Place<'tcx>,
-        variant_index: VariantIdx,
-    ) -> Place<'tcx> {
-        self.mk_place_elem(place, PlaceElem::Downcast(None, variant_index))
-    }
-
-    pub fn mk_place_index(self, place: Place<'tcx>, index: Local) -> Place<'tcx> {
-        self.mk_place_elem(place, PlaceElem::Index(index))
-    }
-
-    /// This method copies `Place`'s projection, add an element and reintern it. Should not be used
-    /// to build a full `Place` it's just a convenient way to grab a projection and modify it in
-    /// flight.
-    pub fn mk_place_elem(self, place: Place<'tcx>, elem: PlaceElem<'tcx>) -> Place<'tcx> {
-        let mut projection = place.projection.to_vec();
-        projection.push(elem);
-
-        Place { local: place.local, projection: self.intern_place_elems(&projection) }
-    }
-
-    pub fn intern_existential_predicates(
-        self,
-        eps: &[ExistentialPredicate<'tcx>],
-    ) -> &'tcx List<ExistentialPredicate<'tcx>> {
-        assert!(!eps.is_empty());
-        assert!(eps.windows(2).all(|w| w[0].stable_cmp(self, &w[1]) != Ordering::Greater));
-        self._intern_existential_predicates(eps)
-    }
-
-    pub fn intern_predicates(self, preds: &[Predicate<'tcx>]) -> &'tcx List<Predicate<'tcx>> {
-        // FIXME consider asking the input slice to be sorted to avoid
-        // re-interning permutations, in which case that would be asserted
-        // here.
-        if preds.len() == 0 {
-            // The macro-generated method below asserts we don't intern an empty slice.
-            List::empty()
-        } else {
-            self._intern_predicates(preds)
-        }
-    }
-
-    pub fn intern_type_list(self, ts: &[Ty<'tcx>]) -> &'tcx List<Ty<'tcx>> {
-        if ts.len() == 0 { List::empty() } else { self._intern_type_list(ts) }
-    }
-
-    pub fn intern_substs(self, ts: &[GenericArg<'tcx>]) -> &'tcx List<GenericArg<'tcx>> {
-        if ts.len() == 0 { List::empty() } else { self._intern_substs(ts) }
-    }
-
-    pub fn intern_projs(self, ps: &[ProjectionKind]) -> &'tcx List<ProjectionKind> {
-        if ps.len() == 0 { List::empty() } else { self._intern_projs(ps) }
-    }
-
-    pub fn intern_place_elems(self, ts: &[PlaceElem<'tcx>]) -> &'tcx List<PlaceElem<'tcx>> {
-        if ts.len() == 0 { List::empty() } else { self._intern_place_elems(ts) }
-    }
-
-    pub fn intern_canonical_var_infos(self, ts: &[CanonicalVarInfo]) -> CanonicalVarInfos<'tcx> {
-        if ts.len() == 0 { List::empty() } else { self._intern_canonical_var_infos(ts) }
-    }
-
-    pub fn intern_clauses(self, ts: &[Clause<'tcx>]) -> Clauses<'tcx> {
-        if ts.len() == 0 { List::empty() } else { self._intern_clauses(ts) }
-    }
-
-    pub fn intern_goals(self, ts: &[Goal<'tcx>]) -> Goals<'tcx> {
-        if ts.len() == 0 { List::empty() } else { self._intern_goals(ts) }
-    }
-
-    pub fn mk_fn_sig<I>(
-        self,
-        inputs: I,
-        output: I::Item,
-        c_variadic: bool,
-        unsafety: hir::Unsafety,
-        abi: abi::Abi,
-    ) -> <I::Item as InternIteratorElement<Ty<'tcx>, ty::FnSig<'tcx>>>::Output
-    where
-        I: Iterator<Item: InternIteratorElement<Ty<'tcx>, ty::FnSig<'tcx>>>,
-    {
-        inputs.chain(iter::once(output)).intern_with(|xs| ty::FnSig {
-            inputs_and_output: self.intern_type_list(xs),
-            c_variadic,
-            unsafety,
-            abi,
-        })
-    }
-
-    pub fn mk_existential_predicates<
-        I: InternAs<[ExistentialPredicate<'tcx>], &'tcx List<ExistentialPredicate<'tcx>>>,
-    >(
-        self,
-        iter: I,
-    ) -> I::Output {
-        iter.intern_with(|xs| self.intern_existential_predicates(xs))
-    }
-
-    pub fn mk_predicates<I: InternAs<[Predicate<'tcx>], &'tcx List<Predicate<'tcx>>>>(
-        self,
-        iter: I,
-    ) -> I::Output {
-        iter.intern_with(|xs| self.intern_predicates(xs))
-    }
-
-    pub fn mk_type_list<I: InternAs<[Ty<'tcx>], &'tcx List<Ty<'tcx>>>>(self, iter: I) -> I::Output {
-        iter.intern_with(|xs| self.intern_type_list(xs))
-    }
-
-    pub fn mk_substs<I: InternAs<[GenericArg<'tcx>], &'tcx List<GenericArg<'tcx>>>>(
-        self,
-        iter: I,
-    ) -> I::Output {
-        iter.intern_with(|xs| self.intern_substs(xs))
-    }
-
-    pub fn mk_place_elems<I: InternAs<[PlaceElem<'tcx>], &'tcx List<PlaceElem<'tcx>>>>(
-        self,
-        iter: I,
-    ) -> I::Output {
-        iter.intern_with(|xs| self.intern_place_elems(xs))
-    }
-
-    pub fn mk_substs_trait(self, self_ty: Ty<'tcx>, rest: &[GenericArg<'tcx>]) -> SubstsRef<'tcx> {
-        self.mk_substs(iter::once(self_ty.into()).chain(rest.iter().cloned()))
-    }
-
-    pub fn mk_clauses<I: InternAs<[Clause<'tcx>], Clauses<'tcx>>>(self, iter: I) -> I::Output {
-        iter.intern_with(|xs| self.intern_clauses(xs))
-    }
-
-    pub fn mk_goals<I: InternAs<[Goal<'tcx>], Goals<'tcx>>>(self, iter: I) -> I::Output {
-        iter.intern_with(|xs| self.intern_goals(xs))
-    }
-
-    /// Walks upwards from `id` to find a node which might change lint levels with attributes.
-    /// It stops at `bound` and just returns it if reached.
-    pub fn maybe_lint_level_root_bounded(self, mut id: HirId, bound: HirId) -> HirId {
-        let hir = self.hir();
-        loop {
-            if id == bound {
-                return bound;
-            }
-
-            if hir.attrs(id).iter().any(|attr| Level::from_symbol(attr.name_or_empty()).is_some()) {
-                return id;
-            }
-            let next = hir.get_parent_node(id);
-            if next == id {
-                bug!("lint traversal reached the root of the crate");
-            }
-            id = next;
-        }
-    }
-
-    pub fn lint_level_at_node(
-        self,
-        lint: &'static Lint,
-        mut id: hir::HirId,
-    ) -> (Level, LintSource) {
-        let sets = self.lint_levels(LOCAL_CRATE);
-        loop {
-            if let Some(pair) = sets.level_and_source(lint, id, self.sess) {
-                return pair;
-            }
-            let next = self.hir().get_parent_node(id);
-            if next == id {
-                bug!("lint traversal reached the root of the crate");
-            }
-            id = next;
-        }
-    }
-
-    pub fn struct_span_lint_hir(
-        self,
-        lint: &'static Lint,
-        hir_id: HirId,
-        span: impl Into<MultiSpan>,
-        decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a>),
-    ) {
-        let (level, src) = self.lint_level_at_node(lint, hir_id);
-        struct_lint_level(self.sess, lint, level, src, Some(span.into()), decorate);
-    }
-
-    pub fn struct_lint_node(
-        self,
-        lint: &'static Lint,
-        id: HirId,
-        decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a>),
-    ) {
-        let (level, src) = self.lint_level_at_node(lint, id);
-        struct_lint_level(self.sess, lint, level, src, None, decorate);
-    }
-
-    pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx StableVec<TraitCandidate>> {
-        self.in_scope_traits_map(id.owner).and_then(|map| map.get(&id.local_id))
-    }
-
-    pub fn named_region(self, id: HirId) -> Option<resolve_lifetime::Region> {
-        self.named_region_map(id.owner).and_then(|map| map.get(&id.local_id).cloned())
-    }
-
-    pub fn is_late_bound(self, id: HirId) -> bool {
-        self.is_late_bound_map(id.owner).map(|set| set.contains(&id.local_id)).unwrap_or(false)
-    }
-
-    pub fn object_lifetime_defaults(self, id: HirId) -> Option<&'tcx [ObjectLifetimeDefault]> {
-        self.object_lifetime_defaults_map(id.owner)
-            .and_then(|map| map.get(&id.local_id).map(|v| &**v))
-    }
-}
-
-pub trait InternAs<T: ?Sized, R> {
-    type Output;
-    fn intern_with<F>(self, f: F) -> Self::Output
-    where
-        F: FnOnce(&T) -> R;
-}
-
-impl<I, T, R, E> InternAs<[T], R> for I
-where
-    E: InternIteratorElement<T, R>,
-    I: Iterator<Item = E>,
-{
-    type Output = E::Output;
-    fn intern_with<F>(self, f: F) -> Self::Output
-    where
-        F: FnOnce(&[T]) -> R,
-    {
-        E::intern_with(self, f)
-    }
-}
-
-pub trait InternIteratorElement<T, R>: Sized {
-    type Output;
-    fn intern_with<I: Iterator<Item = Self>, F: FnOnce(&[T]) -> R>(iter: I, f: F) -> Self::Output;
-}
-
-impl<T, R> InternIteratorElement<T, R> for T {
-    type Output = R;
-    fn intern_with<I: Iterator<Item = Self>, F: FnOnce(&[T]) -> R>(iter: I, f: F) -> Self::Output {
-        f(&iter.collect::<SmallVec<[_; 8]>>())
-    }
-}
-
-impl<'a, T, R> InternIteratorElement<T, R> for &'a T
-where
-    T: Clone + 'a,
-{
-    type Output = R;
-    fn intern_with<I: Iterator<Item = Self>, F: FnOnce(&[T]) -> R>(iter: I, f: F) -> Self::Output {
-        f(&iter.cloned().collect::<SmallVec<[_; 8]>>())
-    }
-}
-
-impl<T, R, E> InternIteratorElement<T, R> for Result<T, E> {
-    type Output = Result<R, E>;
-    fn intern_with<I: Iterator<Item = Self>, F: FnOnce(&[T]) -> R>(
-        mut iter: I,
-        f: F,
-    ) -> Self::Output {
-        // This code is hot enough that it's worth specializing for the most
-        // common length lists, to avoid the overhead of `SmallVec` creation.
-        // The match arms are in order of frequency. The 1, 2, and 0 cases are
-        // typically hit in ~95% of cases. We assume that if the upper and
-        // lower bounds from `size_hint` agree they are correct.
-        Ok(match iter.size_hint() {
-            (1, Some(1)) => {
-                let t0 = iter.next().unwrap()?;
-                assert!(iter.next().is_none());
-                f(&[t0])
-            }
-            (2, Some(2)) => {
-                let t0 = iter.next().unwrap()?;
-                let t1 = iter.next().unwrap()?;
-                assert!(iter.next().is_none());
-                f(&[t0, t1])
-            }
-            (0, Some(0)) => {
-                assert!(iter.next().is_none());
-                f(&[])
-            }
-            _ => f(&iter.collect::<Result<SmallVec<[_; 8]>, _>>()?),
-        })
-    }
-}
-
-// We are comparing types with different invariant lifetimes, so `ptr::eq`
-// won't work for us.
-fn ptr_eq<T, U>(t: *const T, u: *const U) -> bool {
-    t as *const () == u as *const ()
-}
-
-pub fn provide(providers: &mut ty::query::Providers<'_>) {
-    providers.in_scope_traits_map = |tcx, id| tcx.gcx.trait_map.get(&id);
-    providers.module_exports = |tcx, id| tcx.gcx.export_map.get(&id).map(|v| &v[..]);
-    providers.crate_name = |tcx, id| {
-        assert_eq!(id, LOCAL_CRATE);
-        tcx.crate_name
-    };
-    providers.maybe_unused_trait_import = |tcx, id| tcx.maybe_unused_trait_imports.contains(&id);
-    providers.maybe_unused_extern_crates = |tcx, cnum| {
-        assert_eq!(cnum, LOCAL_CRATE);
-        &tcx.maybe_unused_extern_crates[..]
-    };
-    providers.names_imported_by_glob_use = |tcx, id| {
-        assert_eq!(id.krate, LOCAL_CRATE);
-        Lrc::new(tcx.glob_map.get(&id).cloned().unwrap_or_default())
-    };
-
-    providers.lookup_stability = |tcx, id| {
-        assert_eq!(id.krate, LOCAL_CRATE);
-        let id = tcx.hir().definitions().def_index_to_hir_id(id.index);
-        tcx.stability().local_stability(id)
-    };
-    providers.lookup_const_stability = |tcx, id| {
-        assert_eq!(id.krate, LOCAL_CRATE);
-        let id = tcx.hir().definitions().def_index_to_hir_id(id.index);
-        tcx.stability().local_const_stability(id)
-    };
-    providers.lookup_deprecation_entry = |tcx, id| {
-        assert_eq!(id.krate, LOCAL_CRATE);
-        let id = tcx.hir().definitions().def_index_to_hir_id(id.index);
-        tcx.stability().local_deprecation_entry(id)
-    };
-    providers.extern_mod_stmt_cnum = |tcx, id| {
-        let id = tcx.hir().as_local_node_id(id).unwrap();
-        tcx.extern_crate_map.get(&id).cloned()
-    };
-    providers.all_crate_nums = |tcx, cnum| {
-        assert_eq!(cnum, LOCAL_CRATE);
-        tcx.arena.alloc_slice(&tcx.cstore.crates_untracked())
-    };
-    providers.output_filenames = |tcx, cnum| {
-        assert_eq!(cnum, LOCAL_CRATE);
-        tcx.output_filenames.clone()
-    };
-    providers.features_query = |tcx, cnum| {
-        assert_eq!(cnum, LOCAL_CRATE);
-        tcx.arena.alloc(tcx.sess.features_untracked().clone())
-    };
-    providers.is_panic_runtime = |tcx, cnum| {
-        assert_eq!(cnum, LOCAL_CRATE);
-        attr::contains_name(tcx.hir().krate_attrs(), sym::panic_runtime)
-    };
-    providers.is_compiler_builtins = |tcx, cnum| {
-        assert_eq!(cnum, LOCAL_CRATE);
-        attr::contains_name(tcx.hir().krate_attrs(), sym::compiler_builtins)
-    };
-    providers.has_panic_handler = |tcx, cnum| {
-        assert_eq!(cnum, LOCAL_CRATE);
-        // We want to check if the panic handler was defined in this crate
-        tcx.lang_items().panic_impl().map_or(false, |did| did.is_local())
-    };
-}
diff --git a/src/librustc/ty/diagnostics.rs b/src/librustc/ty/diagnostics.rs
deleted file mode 100644
index d1eb21e25ff..00000000000
--- a/src/librustc/ty/diagnostics.rs
+++ /dev/null
@@ -1,65 +0,0 @@
-//! Diagnostics related methods for `TyS`.
-
-use crate::ty::sty::InferTy;
-use crate::ty::TyKind::*;
-use crate::ty::TyS;
-
-impl<'tcx> TyS<'tcx> {
-    /// Similar to `TyS::is_primitive`, but also considers inferred numeric values to be primitive.
-    pub fn is_primitive_ty(&self) -> bool {
-        match self.kind {
-            Bool
-            | Char
-            | Str
-            | Int(_)
-            | Uint(_)
-            | Float(_)
-            | Infer(InferTy::IntVar(_))
-            | Infer(InferTy::FloatVar(_))
-            | Infer(InferTy::FreshIntTy(_))
-            | Infer(InferTy::FreshFloatTy(_)) => true,
-            _ => false,
-        }
-    }
-
-    /// Whether the type is succinctly representable as a type instead of just referred to with a
-    /// description in error messages. This is used in the main error message.
-    pub fn is_simple_ty(&self) -> bool {
-        match self.kind {
-            Bool
-            | Char
-            | Str
-            | Int(_)
-            | Uint(_)
-            | Float(_)
-            | Infer(InferTy::IntVar(_))
-            | Infer(InferTy::FloatVar(_))
-            | Infer(InferTy::FreshIntTy(_))
-            | Infer(InferTy::FreshFloatTy(_)) => true,
-            Ref(_, x, _) | Array(x, _) | Slice(x) => x.peel_refs().is_simple_ty(),
-            Tuple(tys) if tys.is_empty() => true,
-            _ => false,
-        }
-    }
-
-    /// Whether the type is succinctly representable as a type instead of just referred to with a
-    /// description in error messages. This is used in the primary span label. Beyond what
-    /// `is_simple_ty` includes, it also accepts ADTs with no type arguments and references to
-    /// ADTs with no type arguments.
-    pub fn is_simple_text(&self) -> bool {
-        match self.kind {
-            Adt(_, substs) => substs.types().next().is_none(),
-            Ref(_, ty, _) => ty.is_simple_text(),
-            _ => self.is_simple_ty(),
-        }
-    }
-
-    /// Whether the type can be safely suggested during error recovery.
-    pub fn is_suggestable(&self) -> bool {
-        match self.kind {
-            Opaque(..) | FnDef(..) | FnPtr(..) | Dynamic(..) | Closure(..) | Infer(..)
-            | Projection(..) => false,
-            _ => true,
-        }
-    }
-}
diff --git a/src/librustc/ty/erase_regions.rs b/src/librustc/ty/erase_regions.rs
deleted file mode 100644
index 4bf08096ede..00000000000
--- a/src/librustc/ty/erase_regions.rs
+++ /dev/null
@@ -1,68 +0,0 @@
-use crate::ty::fold::{TypeFoldable, TypeFolder};
-use crate::ty::{self, Ty, TyCtxt, TypeFlags};
-
-pub(super) fn provide(providers: &mut ty::query::Providers<'_>) {
-    *providers = ty::query::Providers { erase_regions_ty, ..*providers };
-}
-
-fn erase_regions_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
-    // N.B., use `super_fold_with` here. If we used `fold_with`, it
-    // could invoke the `erase_regions_ty` query recursively.
-    ty.super_fold_with(&mut RegionEraserVisitor { tcx })
-}
-
-impl<'tcx> TyCtxt<'tcx> {
-    /// Returns an equivalent value with all free regions removed (note
-    /// that late-bound regions remain, because they are important for
-    /// subtyping, but they are anonymized and normalized as well)..
-    pub fn erase_regions<T>(self, value: &T) -> T
-    where
-        T: TypeFoldable<'tcx>,
-    {
-        // If there's nothing to erase avoid performing the query at all
-        if !value.has_type_flags(TypeFlags::HAS_RE_LATE_BOUND | TypeFlags::HAS_FREE_REGIONS) {
-            return value.clone();
-        }
-
-        let value1 = value.fold_with(&mut RegionEraserVisitor { tcx: self });
-        debug!("erase_regions({:?}) = {:?}", value, value1);
-        value1
-    }
-}
-
-struct RegionEraserVisitor<'tcx> {
-    tcx: TyCtxt<'tcx>,
-}
-
-impl TypeFolder<'tcx> for RegionEraserVisitor<'tcx> {
-    fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
-        self.tcx
-    }
-
-    fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
-        if ty.has_local_value() { ty.super_fold_with(self) } else { self.tcx.erase_regions_ty(ty) }
-    }
-
-    fn fold_binder<T>(&mut self, t: &ty::Binder<T>) -> ty::Binder<T>
-    where
-        T: TypeFoldable<'tcx>,
-    {
-        let u = self.tcx.anonymize_late_bound_regions(t);
-        u.super_fold_with(self)
-    }
-
-    fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
-        // because late-bound regions affect subtyping, we can't
-        // erase the bound/free distinction, but we can replace
-        // all free regions with 'erased.
-        //
-        // Note that we *CAN* replace early-bound regions -- the
-        // type system never "sees" those, they get substituted
-        // away. In codegen, they will always be erased to 'erased
-        // whenever a substitution occurs.
-        match *r {
-            ty::ReLateBound(..) => r,
-            _ => self.tcx.lifetimes.re_erased,
-        }
-    }
-}
diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs
deleted file mode 100644
index 6c5458e6e58..00000000000
--- a/src/librustc/ty/error.rs
+++ /dev/null
@@ -1,495 +0,0 @@
-use crate::ty::{self, BoundRegion, Region, Ty, TyCtxt};
-use rustc_errors::{pluralize, Applicability, DiagnosticBuilder};
-use rustc_hir as hir;
-use rustc_hir::def_id::DefId;
-use rustc_span::Span;
-use rustc_target::spec::abi;
-use syntax::ast;
-
-use std::borrow::Cow;
-use std::fmt;
-
-#[derive(Clone, Copy, Debug, PartialEq, Eq, TypeFoldable)]
-pub struct ExpectedFound<T> {
-    pub expected: T,
-    pub found: T,
-}
-
-impl<T> ExpectedFound<T> {
-    pub fn new(a_is_expected: bool, a: T, b: T) -> Self {
-        if a_is_expected {
-            ExpectedFound { expected: a, found: b }
-        } else {
-            ExpectedFound { expected: b, found: a }
-        }
-    }
-}
-
-// Data structures used in type unification
-#[derive(Clone, Debug, TypeFoldable)]
-pub enum TypeError<'tcx> {
-    Mismatch,
-    UnsafetyMismatch(ExpectedFound<hir::Unsafety>),
-    AbiMismatch(ExpectedFound<abi::Abi>),
-    Mutability,
-    TupleSize(ExpectedFound<usize>),
-    FixedArraySize(ExpectedFound<u64>),
-    ArgCount,
-
-    RegionsDoesNotOutlive(Region<'tcx>, Region<'tcx>),
-    RegionsInsufficientlyPolymorphic(BoundRegion, Region<'tcx>),
-    RegionsOverlyPolymorphic(BoundRegion, Region<'tcx>),
-    RegionsPlaceholderMismatch,
-
-    Sorts(ExpectedFound<Ty<'tcx>>),
-    IntMismatch(ExpectedFound<ty::IntVarValue>),
-    FloatMismatch(ExpectedFound<ast::FloatTy>),
-    Traits(ExpectedFound<DefId>),
-    VariadicMismatch(ExpectedFound<bool>),
-
-    /// Instantiating a type variable with the given type would have
-    /// created a cycle (because it appears somewhere within that
-    /// type).
-    CyclicTy(Ty<'tcx>),
-    ProjectionMismatched(ExpectedFound<DefId>),
-    ProjectionBoundsLength(ExpectedFound<usize>),
-    ExistentialMismatch(ExpectedFound<&'tcx ty::List<ty::ExistentialPredicate<'tcx>>>),
-    ObjectUnsafeCoercion(DefId),
-    ConstMismatch(ExpectedFound<&'tcx ty::Const<'tcx>>),
-
-    IntrinsicCast,
-}
-
-pub enum UnconstrainedNumeric {
-    UnconstrainedFloat,
-    UnconstrainedInt,
-    Neither,
-}
-
-/// Explains the source of a type err in a short, human readable way. This is meant to be placed
-/// in parentheses after some larger message. You should also invoke `note_and_explain_type_err()`
-/// afterwards to present additional details, particularly when it comes to lifetime-related
-/// errors.
-impl<'tcx> fmt::Display for TypeError<'tcx> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        use self::TypeError::*;
-        fn report_maybe_different(
-            f: &mut fmt::Formatter<'_>,
-            expected: &str,
-            found: &str,
-        ) -> fmt::Result {
-            // A naive approach to making sure that we're not reporting silly errors such as:
-            // (expected closure, found closure).
-            if expected == found {
-                write!(f, "expected {}, found a different {}", expected, found)
-            } else {
-                write!(f, "expected {}, found {}", expected, found)
-            }
-        }
-
-        let br_string = |br: ty::BoundRegion| match br {
-            ty::BrNamed(_, name) => format!(" {}", name),
-            _ => String::new(),
-        };
-
-        match *self {
-            CyclicTy(_) => write!(f, "cyclic type of infinite size"),
-            Mismatch => write!(f, "types differ"),
-            UnsafetyMismatch(values) => {
-                write!(f, "expected {} fn, found {} fn", values.expected, values.found)
-            }
-            AbiMismatch(values) => {
-                write!(f, "expected {} fn, found {} fn", values.expected, values.found)
-            }
-            Mutability => write!(f, "types differ in mutability"),
-            TupleSize(values) => write!(
-                f,
-                "expected a tuple with {} element{}, \
-                           found one with {} element{}",
-                values.expected,
-                pluralize!(values.expected),
-                values.found,
-                pluralize!(values.found)
-            ),
-            FixedArraySize(values) => write!(
-                f,
-                "expected an array with a fixed size of {} element{}, \
-                           found one with {} element{}",
-                values.expected,
-                pluralize!(values.expected),
-                values.found,
-                pluralize!(values.found)
-            ),
-            ArgCount => write!(f, "incorrect number of function parameters"),
-            RegionsDoesNotOutlive(..) => write!(f, "lifetime mismatch"),
-            RegionsInsufficientlyPolymorphic(br, _) => write!(
-                f,
-                "expected bound lifetime parameter{}, found concrete lifetime",
-                br_string(br)
-            ),
-            RegionsOverlyPolymorphic(br, _) => write!(
-                f,
-                "expected concrete lifetime, found bound lifetime parameter{}",
-                br_string(br)
-            ),
-            RegionsPlaceholderMismatch => write!(f, "one type is more general than the other"),
-            Sorts(values) => ty::tls::with(|tcx| {
-                report_maybe_different(
-                    f,
-                    &values.expected.sort_string(tcx),
-                    &values.found.sort_string(tcx),
-                )
-            }),
-            Traits(values) => ty::tls::with(|tcx| {
-                report_maybe_different(
-                    f,
-                    &format!("trait `{}`", tcx.def_path_str(values.expected)),
-                    &format!("trait `{}`", tcx.def_path_str(values.found)),
-                )
-            }),
-            IntMismatch(ref values) => {
-                write!(f, "expected `{:?}`, found `{:?}`", values.expected, values.found)
-            }
-            FloatMismatch(ref values) => {
-                write!(f, "expected `{:?}`, found `{:?}`", values.expected, values.found)
-            }
-            VariadicMismatch(ref values) => write!(
-                f,
-                "expected {} fn, found {} function",
-                if values.expected { "variadic" } else { "non-variadic" },
-                if values.found { "variadic" } else { "non-variadic" }
-            ),
-            ProjectionMismatched(ref values) => ty::tls::with(|tcx| {
-                write!(
-                    f,
-                    "expected {}, found {}",
-                    tcx.def_path_str(values.expected),
-                    tcx.def_path_str(values.found)
-                )
-            }),
-            ProjectionBoundsLength(ref values) => write!(
-                f,
-                "expected {} associated type binding{}, found {}",
-                values.expected,
-                pluralize!(values.expected),
-                values.found
-            ),
-            ExistentialMismatch(ref values) => report_maybe_different(
-                f,
-                &format!("trait `{}`", values.expected),
-                &format!("trait `{}`", values.found),
-            ),
-            ConstMismatch(ref values) => {
-                write!(f, "expected `{}`, found `{}`", values.expected, values.found)
-            }
-            IntrinsicCast => write!(f, "cannot coerce intrinsics to function pointers"),
-            ObjectUnsafeCoercion(_) => write!(f, "coercion to object-unsafe trait object"),
-        }
-    }
-}
-
-impl<'tcx> TypeError<'tcx> {
-    pub fn must_include_note(&self) -> bool {
-        use self::TypeError::*;
-        match self {
-            CyclicTy(_) | UnsafetyMismatch(_) | Mismatch | AbiMismatch(_) | FixedArraySize(_)
-            | Sorts(_) | IntMismatch(_) | FloatMismatch(_) | VariadicMismatch(_) => false,
-
-            Mutability
-            | TupleSize(_)
-            | ArgCount
-            | RegionsDoesNotOutlive(..)
-            | RegionsInsufficientlyPolymorphic(..)
-            | RegionsOverlyPolymorphic(..)
-            | RegionsPlaceholderMismatch
-            | Traits(_)
-            | ProjectionMismatched(_)
-            | ProjectionBoundsLength(_)
-            | ExistentialMismatch(_)
-            | ConstMismatch(_)
-            | IntrinsicCast
-            | ObjectUnsafeCoercion(_) => true,
-        }
-    }
-}
-
-impl<'tcx> ty::TyS<'tcx> {
-    pub fn sort_string(&self, tcx: TyCtxt<'_>) -> Cow<'static, str> {
-        match self.kind {
-            ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Str | ty::Never => {
-                format!("`{}`", self).into()
-            }
-            ty::Tuple(ref tys) if tys.is_empty() => format!("`{}`", self).into(),
-
-            ty::Adt(def, _) => format!("{} `{}`", def.descr(), tcx.def_path_str(def.did)).into(),
-            ty::Foreign(def_id) => format!("extern type `{}`", tcx.def_path_str(def_id)).into(),
-            ty::Array(t, n) => {
-                let n = tcx.lift(&n).unwrap();
-                match n.try_eval_usize(tcx, ty::ParamEnv::empty()) {
-                    _ if t.is_simple_ty() => format!("array `{}`", self).into(),
-                    Some(n) => format!("array of {} element{} ", n, pluralize!(n)).into(),
-                    None => "array".into(),
-                }
-            }
-            ty::Slice(ty) if ty.is_simple_ty() => format!("slice `{}`", self).into(),
-            ty::Slice(_) => "slice".into(),
-            ty::RawPtr(_) => "*-ptr".into(),
-            ty::Ref(_, ty, mutbl) => {
-                let tymut = ty::TypeAndMut { ty, mutbl };
-                let tymut_string = tymut.to_string();
-                if tymut_string != "_"
-                    && (ty.is_simple_text() || tymut_string.len() < "mutable reference".len())
-                {
-                    format!("`&{}`", tymut_string).into()
-                } else {
-                    // Unknown type name, it's long or has type arguments
-                    match mutbl {
-                        hir::Mutability::Mut => "mutable reference",
-                        _ => "reference",
-                    }
-                    .into()
-                }
-            }
-            ty::FnDef(..) => "fn item".into(),
-            ty::FnPtr(_) => "fn pointer".into(),
-            ty::Dynamic(ref inner, ..) => {
-                if let Some(principal) = inner.principal() {
-                    format!("trait object `dyn {}`", tcx.def_path_str(principal.def_id())).into()
-                } else {
-                    "trait object".into()
-                }
-            }
-            ty::Closure(..) => "closure".into(),
-            ty::Generator(..) => "generator".into(),
-            ty::GeneratorWitness(..) => "generator witness".into(),
-            ty::Tuple(..) => "tuple".into(),
-            ty::Infer(ty::TyVar(_)) => "inferred type".into(),
-            ty::Infer(ty::IntVar(_)) => "integer".into(),
-            ty::Infer(ty::FloatVar(_)) => "floating-point number".into(),
-            ty::Placeholder(..) => "placeholder type".into(),
-            ty::Bound(..) => "bound type".into(),
-            ty::Infer(ty::FreshTy(_)) => "fresh type".into(),
-            ty::Infer(ty::FreshIntTy(_)) => "fresh integral type".into(),
-            ty::Infer(ty::FreshFloatTy(_)) => "fresh floating-point type".into(),
-            ty::Projection(_) => "associated type".into(),
-            ty::UnnormalizedProjection(_) => "non-normalized associated type".into(),
-            ty::Param(p) => format!("type parameter `{}`", p).into(),
-            ty::Opaque(..) => "opaque type".into(),
-            ty::Error => "type error".into(),
-        }
-    }
-
-    pub fn prefix_string(&self) -> Cow<'static, str> {
-        match self.kind {
-            ty::Infer(_)
-            | ty::Error
-            | ty::Bool
-            | ty::Char
-            | ty::Int(_)
-            | ty::Uint(_)
-            | ty::Float(_)
-            | ty::Str
-            | ty::Never => "type".into(),
-            ty::Tuple(ref tys) if tys.is_empty() => "unit type".into(),
-            ty::Adt(def, _) => def.descr().into(),
-            ty::Foreign(_) => "extern type".into(),
-            ty::Array(..) => "array".into(),
-            ty::Slice(_) => "slice".into(),
-            ty::RawPtr(_) => "raw pointer".into(),
-            ty::Ref(.., mutbl) => match mutbl {
-                hir::Mutability::Mut => "mutable reference",
-                _ => "reference",
-            }
-            .into(),
-            ty::FnDef(..) => "fn item".into(),
-            ty::FnPtr(_) => "fn pointer".into(),
-            ty::Dynamic(..) => "trait object".into(),
-            ty::Closure(..) => "closure".into(),
-            ty::Generator(..) => "generator".into(),
-            ty::GeneratorWitness(..) => "generator witness".into(),
-            ty::Tuple(..) => "tuple".into(),
-            ty::Placeholder(..) => "higher-ranked type".into(),
-            ty::Bound(..) => "bound type variable".into(),
-            ty::Projection(_) => "associated type".into(),
-            ty::UnnormalizedProjection(_) => "associated type".into(),
-            ty::Param(_) => "type parameter".into(),
-            ty::Opaque(..) => "opaque type".into(),
-        }
-    }
-}
-
-impl<'tcx> TyCtxt<'tcx> {
-    pub fn note_and_explain_type_err(
-        self,
-        db: &mut DiagnosticBuilder<'_>,
-        err: &TypeError<'tcx>,
-        sp: Span,
-        body_owner_def_id: DefId,
-    ) {
-        use self::TypeError::*;
-
-        match err {
-            Sorts(values) => {
-                let expected_str = values.expected.sort_string(self);
-                let found_str = values.found.sort_string(self);
-                if expected_str == found_str && expected_str == "closure" {
-                    db.note("no two closures, even if identical, have the same type");
-                    db.help("consider boxing your closure and/or using it as a trait object");
-                }
-                if expected_str == found_str && expected_str == "opaque type" {
-                    // Issue #63167
-                    db.note("distinct uses of `impl Trait` result in different opaque types");
-                    let e_str = values.expected.to_string();
-                    let f_str = values.found.to_string();
-                    if &e_str == &f_str && &e_str == "impl std::future::Future" {
-                        // FIXME: use non-string based check.
-                        db.help(
-                            "if both `Future`s have the same `Output` type, consider \
-                                 `.await`ing on both of them",
-                        );
-                    }
-                }
-                match (&values.expected.kind, &values.found.kind) {
-                    (ty::Float(_), ty::Infer(ty::IntVar(_))) => {
-                        if let Ok(
-                            // Issue #53280
-                            snippet,
-                        ) = self.sess.source_map().span_to_snippet(sp)
-                        {
-                            if snippet.chars().all(|c| c.is_digit(10) || c == '-' || c == '_') {
-                                db.span_suggestion(
-                                    sp,
-                                    "use a float literal",
-                                    format!("{}.0", snippet),
-                                    Applicability::MachineApplicable,
-                                );
-                            }
-                        }
-                    }
-                    (ty::Param(expected), ty::Param(found)) => {
-                        let generics = self.generics_of(body_owner_def_id);
-                        let e_span = self.def_span(generics.type_param(expected, self).def_id);
-                        if !sp.contains(e_span) {
-                            db.span_label(e_span, "expected type parameter");
-                        }
-                        let f_span = self.def_span(generics.type_param(found, self).def_id);
-                        if !sp.contains(f_span) {
-                            db.span_label(f_span, "found type parameter");
-                        }
-                        db.note(
-                            "a type parameter was expected, but a different one was found; \
-                                 you might be missing a type parameter or trait bound",
-                        );
-                        db.note(
-                            "for more information, visit \
-                                 https://doc.rust-lang.org/book/ch10-02-traits.html\
-                                 #traits-as-parameters",
-                        );
-                    }
-                    (ty::Projection(_), ty::Projection(_)) => {
-                        db.note("an associated type was expected, but a different one was found");
-                    }
-                    (ty::Param(_), ty::Projection(_)) | (ty::Projection(_), ty::Param(_)) => {
-                        db.note("you might be missing a type parameter or trait bound");
-                    }
-                    (ty::Param(p), _) | (_, ty::Param(p)) => {
-                        let generics = self.generics_of(body_owner_def_id);
-                        let p_span = self.def_span(generics.type_param(p, self).def_id);
-                        if !sp.contains(p_span) {
-                            db.span_label(p_span, "this type parameter");
-                        }
-                        db.help("type parameters must be constrained to match other types");
-                        if self.sess.teach(&db.get_code().unwrap()) {
-                            db.help(
-                                "given a type parameter `T` and a method `foo`:
-```
-trait Trait<T> { fn foo(&self) -> T; }
-```
-the only ways to implement method `foo` are:
-- constrain `T` with an explicit type:
-```
-impl Trait<String> for X {
-    fn foo(&self) -> String { String::new() }
-}
-```
-- add a trait bound to `T` and call a method on that trait that returns `Self`:
-```
-impl<T: std::default::Default> Trait<T> for X {
-    fn foo(&self) -> T { <T as std::default::Default>::default() }
-}
-```
-- change `foo` to return an argument of type `T`:
-```
-impl<T> Trait<T> for X {
-    fn foo(&self, x: T) -> T { x }
-}
-```",
-                            );
-                        }
-                        db.note(
-                            "for more information, visit \
-                                 https://doc.rust-lang.org/book/ch10-02-traits.html\
-                                 #traits-as-parameters",
-                        );
-                    }
-                    (ty::Projection(_), _) => {
-                        db.note(&format!(
-                            "consider constraining the associated type `{}` to `{}` or calling a \
-                             method that returns `{}`",
-                            values.expected, values.found, values.expected,
-                        ));
-                        if self.sess.teach(&db.get_code().unwrap()) {
-                            db.help(
-                                "given an associated type `T` and a method `foo`:
-```
-trait Trait {
-    type T;
-    fn foo(&self) -> Self::T;
-}
-```
-the only way of implementing method `foo` is to constrain `T` with an explicit associated type:
-```
-impl Trait for X {
-    type T = String;
-    fn foo(&self) -> Self::T { String::new() }
-}
-```",
-                            );
-                        }
-                        db.note(
-                            "for more information, visit \
-                                 https://doc.rust-lang.org/book/ch19-03-advanced-traits.html",
-                        );
-                    }
-                    (_, ty::Projection(_)) => {
-                        db.note(&format!(
-                            "consider constraining the associated type `{}` to `{}`",
-                            values.found, values.expected,
-                        ));
-                        db.note(
-                            "for more information, visit \
-                                 https://doc.rust-lang.org/book/ch19-03-advanced-traits.html",
-                        );
-                    }
-                    _ => {}
-                }
-                debug!(
-                    "note_and_explain_type_err expected={:?} ({:?}) found={:?} ({:?})",
-                    values.expected, values.expected.kind, values.found, values.found.kind,
-                );
-            }
-            CyclicTy(ty) => {
-                // Watch out for various cases of cyclic types and try to explain.
-                if ty.is_closure() || ty.is_generator() {
-                    db.note(
-                        "closures cannot capture themselves or take themselves as argument;\n\
-                         this error may be the result of a recent compiler bug-fix,\n\
-                         see issue #46062 <https://github.com/rust-lang/rust/issues/46062>\n\
-                         for more information",
-                    );
-                }
-            }
-            _ => {}
-        }
-    }
-}
diff --git a/src/librustc/ty/fast_reject.rs b/src/librustc/ty/fast_reject.rs
deleted file mode 100644
index 5aa8bd9df2a..00000000000
--- a/src/librustc/ty/fast_reject.rs
+++ /dev/null
@@ -1,174 +0,0 @@
-use crate::ich::StableHashingContext;
-use crate::ty::{self, Ty, TyCtxt};
-use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
-use rustc_hir::def_id::DefId;
-use std::fmt::Debug;
-use std::hash::Hash;
-use std::mem;
-use syntax::ast;
-
-use self::SimplifiedTypeGen::*;
-
-pub type SimplifiedType = SimplifiedTypeGen<DefId>;
-
-/// See `simplify_type`
-///
-/// Note that we keep this type generic over the type of identifier it uses
-/// because we sometimes need to use SimplifiedTypeGen values as stable sorting
-/// keys (in which case we use a DefPathHash as id-type) but in the general case
-/// the non-stable but fast to construct DefId-version is the better choice.
-#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, RustcEncodable, RustcDecodable)]
-pub enum SimplifiedTypeGen<D>
-where
-    D: Copy + Debug + Ord + Eq,
-{
-    BoolSimplifiedType,
-    CharSimplifiedType,
-    IntSimplifiedType(ast::IntTy),
-    UintSimplifiedType(ast::UintTy),
-    FloatSimplifiedType(ast::FloatTy),
-    AdtSimplifiedType(D),
-    StrSimplifiedType,
-    ArraySimplifiedType,
-    PtrSimplifiedType,
-    NeverSimplifiedType,
-    TupleSimplifiedType(usize),
-    /// A trait object, all of whose components are markers
-    /// (e.g., `dyn Send + Sync`).
-    MarkerTraitObjectSimplifiedType,
-    TraitSimplifiedType(D),
-    ClosureSimplifiedType(D),
-    GeneratorSimplifiedType(D),
-    GeneratorWitnessSimplifiedType(usize),
-    OpaqueSimplifiedType(D),
-    FunctionSimplifiedType(usize),
-    ParameterSimplifiedType,
-    ForeignSimplifiedType(DefId),
-}
-
-/// Tries to simplify a type by dropping type parameters, deref'ing away any reference types, etc.
-/// The idea is to get something simple that we can use to quickly decide if two types could unify
-/// during method lookup.
-///
-/// If `can_simplify_params` is false, then we will fail to simplify type parameters entirely. This
-/// is useful when those type parameters would be instantiated with fresh type variables, since
-/// then we can't say much about whether two types would unify. Put another way,
-/// `can_simplify_params` should be true if type parameters appear free in `ty` and `false` if they
-/// are to be considered bound.
-pub fn simplify_type(
-    tcx: TyCtxt<'_>,
-    ty: Ty<'_>,
-    can_simplify_params: bool,
-) -> Option<SimplifiedType> {
-    match ty.kind {
-        ty::Bool => Some(BoolSimplifiedType),
-        ty::Char => Some(CharSimplifiedType),
-        ty::Int(int_type) => Some(IntSimplifiedType(int_type)),
-        ty::Uint(uint_type) => Some(UintSimplifiedType(uint_type)),
-        ty::Float(float_type) => Some(FloatSimplifiedType(float_type)),
-        ty::Adt(def, _) => Some(AdtSimplifiedType(def.did)),
-        ty::Str => Some(StrSimplifiedType),
-        ty::Array(..) | ty::Slice(_) => Some(ArraySimplifiedType),
-        ty::RawPtr(_) => Some(PtrSimplifiedType),
-        ty::Dynamic(ref trait_info, ..) => match trait_info.principal_def_id() {
-            Some(principal_def_id) if !tcx.trait_is_auto(principal_def_id) => {
-                Some(TraitSimplifiedType(principal_def_id))
-            }
-            _ => Some(MarkerTraitObjectSimplifiedType),
-        },
-        ty::Ref(_, ty, _) => {
-            // since we introduce auto-refs during method lookup, we
-            // just treat &T and T as equivalent from the point of
-            // view of possibly unifying
-            simplify_type(tcx, ty, can_simplify_params)
-        }
-        ty::FnDef(def_id, _) | ty::Closure(def_id, _) => Some(ClosureSimplifiedType(def_id)),
-        ty::Generator(def_id, _, _) => Some(GeneratorSimplifiedType(def_id)),
-        ty::GeneratorWitness(ref tys) => {
-            Some(GeneratorWitnessSimplifiedType(tys.skip_binder().len()))
-        }
-        ty::Never => Some(NeverSimplifiedType),
-        ty::Tuple(ref tys) => Some(TupleSimplifiedType(tys.len())),
-        ty::FnPtr(ref f) => Some(FunctionSimplifiedType(f.skip_binder().inputs().len())),
-        ty::UnnormalizedProjection(..) => bug!("only used with chalk-engine"),
-        ty::Projection(_) | ty::Param(_) => {
-            if can_simplify_params {
-                // In normalized types, projections don't unify with
-                // anything. when lazy normalization happens, this
-                // will change. It would still be nice to have a way
-                // to deal with known-not-to-unify-with-anything
-                // projections (e.g., the likes of <__S as Encoder>::Error).
-                Some(ParameterSimplifiedType)
-            } else {
-                None
-            }
-        }
-        ty::Opaque(def_id, _) => Some(OpaqueSimplifiedType(def_id)),
-        ty::Foreign(def_id) => Some(ForeignSimplifiedType(def_id)),
-        ty::Placeholder(..) | ty::Bound(..) | ty::Infer(_) | ty::Error => None,
-    }
-}
-
-impl<D: Copy + Debug + Ord + Eq> SimplifiedTypeGen<D> {
-    pub fn map_def<U, F>(self, map: F) -> SimplifiedTypeGen<U>
-    where
-        F: Fn(D) -> U,
-        U: Copy + Debug + Ord + Eq,
-    {
-        match self {
-            BoolSimplifiedType => BoolSimplifiedType,
-            CharSimplifiedType => CharSimplifiedType,
-            IntSimplifiedType(t) => IntSimplifiedType(t),
-            UintSimplifiedType(t) => UintSimplifiedType(t),
-            FloatSimplifiedType(t) => FloatSimplifiedType(t),
-            AdtSimplifiedType(d) => AdtSimplifiedType(map(d)),
-            StrSimplifiedType => StrSimplifiedType,
-            ArraySimplifiedType => ArraySimplifiedType,
-            PtrSimplifiedType => PtrSimplifiedType,
-            NeverSimplifiedType => NeverSimplifiedType,
-            MarkerTraitObjectSimplifiedType => MarkerTraitObjectSimplifiedType,
-            TupleSimplifiedType(n) => TupleSimplifiedType(n),
-            TraitSimplifiedType(d) => TraitSimplifiedType(map(d)),
-            ClosureSimplifiedType(d) => ClosureSimplifiedType(map(d)),
-            GeneratorSimplifiedType(d) => GeneratorSimplifiedType(map(d)),
-            GeneratorWitnessSimplifiedType(n) => GeneratorWitnessSimplifiedType(n),
-            OpaqueSimplifiedType(d) => OpaqueSimplifiedType(map(d)),
-            FunctionSimplifiedType(n) => FunctionSimplifiedType(n),
-            ParameterSimplifiedType => ParameterSimplifiedType,
-            ForeignSimplifiedType(d) => ForeignSimplifiedType(d),
-        }
-    }
-}
-
-impl<'a, D> HashStable<StableHashingContext<'a>> for SimplifiedTypeGen<D>
-where
-    D: Copy + Debug + Ord + Eq + HashStable<StableHashingContext<'a>>,
-{
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        mem::discriminant(self).hash_stable(hcx, hasher);
-        match *self {
-            BoolSimplifiedType
-            | CharSimplifiedType
-            | StrSimplifiedType
-            | ArraySimplifiedType
-            | PtrSimplifiedType
-            | NeverSimplifiedType
-            | ParameterSimplifiedType
-            | MarkerTraitObjectSimplifiedType => {
-                // nothing to do
-            }
-            IntSimplifiedType(t) => t.hash_stable(hcx, hasher),
-            UintSimplifiedType(t) => t.hash_stable(hcx, hasher),
-            FloatSimplifiedType(t) => t.hash_stable(hcx, hasher),
-            AdtSimplifiedType(d) => d.hash_stable(hcx, hasher),
-            TupleSimplifiedType(n) => n.hash_stable(hcx, hasher),
-            TraitSimplifiedType(d) => d.hash_stable(hcx, hasher),
-            ClosureSimplifiedType(d) => d.hash_stable(hcx, hasher),
-            GeneratorSimplifiedType(d) => d.hash_stable(hcx, hasher),
-            GeneratorWitnessSimplifiedType(n) => n.hash_stable(hcx, hasher),
-            OpaqueSimplifiedType(d) => d.hash_stable(hcx, hasher),
-            FunctionSimplifiedType(n) => n.hash_stable(hcx, hasher),
-            ForeignSimplifiedType(d) => d.hash_stable(hcx, hasher),
-        }
-    }
-}
diff --git a/src/librustc/ty/flags.rs b/src/librustc/ty/flags.rs
deleted file mode 100644
index 4546eadc6e6..00000000000
--- a/src/librustc/ty/flags.rs
+++ /dev/null
@@ -1,264 +0,0 @@
-use crate::ty::subst::{GenericArgKind, SubstsRef};
-use crate::ty::{self, InferConst, Ty, TypeFlags};
-
-#[derive(Debug)]
-pub struct FlagComputation {
-    pub flags: TypeFlags,
-
-    // see `TyS::outer_exclusive_binder` for details
-    pub outer_exclusive_binder: ty::DebruijnIndex,
-}
-
-impl FlagComputation {
-    fn new() -> FlagComputation {
-        FlagComputation { flags: TypeFlags::empty(), outer_exclusive_binder: ty::INNERMOST }
-    }
-
-    #[allow(rustc::usage_of_ty_tykind)]
-    pub fn for_kind(kind: &ty::TyKind<'_>) -> FlagComputation {
-        let mut result = FlagComputation::new();
-        result.add_kind(kind);
-        result
-    }
-
-    pub fn for_const(c: &ty::Const<'_>) -> TypeFlags {
-        let mut result = FlagComputation::new();
-        result.add_const(c);
-        result.flags
-    }
-
-    fn add_flags(&mut self, flags: TypeFlags) {
-        self.flags = self.flags | (flags & TypeFlags::NOMINAL_FLAGS);
-    }
-
-    /// indicates that `self` refers to something at binding level `binder`
-    fn add_binder(&mut self, binder: ty::DebruijnIndex) {
-        let exclusive_binder = binder.shifted_in(1);
-        self.add_exclusive_binder(exclusive_binder);
-    }
-
-    /// indicates that `self` refers to something *inside* binding
-    /// level `binder` -- not bound by `binder`, but bound by the next
-    /// binder internal to it
-    fn add_exclusive_binder(&mut self, exclusive_binder: ty::DebruijnIndex) {
-        self.outer_exclusive_binder = self.outer_exclusive_binder.max(exclusive_binder);
-    }
-
-    /// Adds the flags/depth from a set of types that appear within the current type, but within a
-    /// region binder.
-    fn add_bound_computation(&mut self, computation: &FlagComputation) {
-        self.add_flags(computation.flags);
-
-        // The types that contributed to `computation` occurred within
-        // a region binder, so subtract one from the region depth
-        // within when adding the depth to `self`.
-        let outer_exclusive_binder = computation.outer_exclusive_binder;
-        if outer_exclusive_binder > ty::INNERMOST {
-            self.add_exclusive_binder(outer_exclusive_binder.shifted_out(1));
-        } // otherwise, this binder captures nothing
-    }
-
-    #[allow(rustc::usage_of_ty_tykind)]
-    fn add_kind(&mut self, kind: &ty::TyKind<'_>) {
-        match kind {
-            &ty::Bool
-            | &ty::Char
-            | &ty::Int(_)
-            | &ty::Float(_)
-            | &ty::Uint(_)
-            | &ty::Never
-            | &ty::Str
-            | &ty::Foreign(..) => {}
-
-            // You might think that we could just return Error for
-            // any type containing Error as a component, and get
-            // rid of the TypeFlags::HAS_TY_ERR flag -- likewise for ty_bot (with
-            // the exception of function types that return bot).
-            // But doing so caused sporadic memory corruption, and
-            // neither I (tjc) nor nmatsakis could figure out why,
-            // so we're doing it this way.
-            &ty::Error => self.add_flags(TypeFlags::HAS_TY_ERR),
-
-            &ty::Param(_) => {
-                self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES);
-                self.add_flags(TypeFlags::HAS_PARAMS);
-            }
-
-            &ty::Generator(_, ref substs, _) => {
-                self.add_flags(TypeFlags::HAS_TY_CLOSURE);
-                self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES);
-                self.add_substs(substs);
-            }
-
-            &ty::GeneratorWitness(ref ts) => {
-                let mut computation = FlagComputation::new();
-                computation.add_tys(&ts.skip_binder()[..]);
-                self.add_bound_computation(&computation);
-            }
-
-            &ty::Closure(_, ref substs) => {
-                self.add_flags(TypeFlags::HAS_TY_CLOSURE);
-                self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES);
-                self.add_substs(substs);
-            }
-
-            &ty::Bound(debruijn, _) => {
-                self.add_binder(debruijn);
-            }
-
-            &ty::Placeholder(..) => {
-                self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES);
-                self.add_flags(TypeFlags::HAS_TY_PLACEHOLDER);
-            }
-
-            &ty::Infer(infer) => {
-                self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES); // it might, right?
-                self.add_flags(TypeFlags::HAS_TY_INFER);
-                match infer {
-                    ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) => {}
-
-                    ty::TyVar(_) | ty::IntVar(_) | ty::FloatVar(_) => {
-                        self.add_flags(TypeFlags::KEEP_IN_LOCAL_TCX)
-                    }
-                }
-            }
-
-            &ty::Adt(_, substs) => {
-                self.add_substs(substs);
-            }
-
-            &ty::Projection(ref data) => {
-                self.add_flags(TypeFlags::HAS_PROJECTION);
-                self.add_projection_ty(data);
-            }
-
-            &ty::UnnormalizedProjection(ref data) => {
-                self.add_flags(TypeFlags::HAS_PROJECTION);
-                self.add_projection_ty(data);
-            }
-
-            &ty::Opaque(_, substs) => {
-                self.add_flags(TypeFlags::HAS_PROJECTION | TypeFlags::HAS_TY_OPAQUE);
-                self.add_substs(substs);
-            }
-
-            &ty::Dynamic(ref obj, r) => {
-                let mut computation = FlagComputation::new();
-                for predicate in obj.skip_binder().iter() {
-                    match *predicate {
-                        ty::ExistentialPredicate::Trait(tr) => computation.add_substs(tr.substs),
-                        ty::ExistentialPredicate::Projection(p) => {
-                            let mut proj_computation = FlagComputation::new();
-                            proj_computation.add_existential_projection(&p);
-                            self.add_bound_computation(&proj_computation);
-                        }
-                        ty::ExistentialPredicate::AutoTrait(_) => {}
-                    }
-                }
-                self.add_bound_computation(&computation);
-                self.add_region(r);
-            }
-
-            &ty::Array(tt, len) => {
-                self.add_ty(tt);
-                self.add_const(len);
-            }
-
-            &ty::Slice(tt) => self.add_ty(tt),
-
-            &ty::RawPtr(ref m) => {
-                self.add_ty(m.ty);
-            }
-
-            &ty::Ref(r, ty, _) => {
-                self.add_region(r);
-                self.add_ty(ty);
-            }
-
-            &ty::Tuple(ref substs) => {
-                self.add_substs(substs);
-            }
-
-            &ty::FnDef(_, substs) => {
-                self.add_substs(substs);
-            }
-
-            &ty::FnPtr(f) => {
-                self.add_fn_sig(f);
-            }
-        }
-    }
-
-    fn add_ty(&mut self, ty: Ty<'_>) {
-        self.add_flags(ty.flags);
-        self.add_exclusive_binder(ty.outer_exclusive_binder);
-    }
-
-    fn add_tys(&mut self, tys: &[Ty<'_>]) {
-        for &ty in tys {
-            self.add_ty(ty);
-        }
-    }
-
-    fn add_fn_sig(&mut self, fn_sig: ty::PolyFnSig<'_>) {
-        let mut computation = FlagComputation::new();
-
-        computation.add_tys(fn_sig.skip_binder().inputs());
-        computation.add_ty(fn_sig.skip_binder().output());
-
-        self.add_bound_computation(&computation);
-    }
-
-    fn add_region(&mut self, r: ty::Region<'_>) {
-        self.add_flags(r.type_flags());
-        if let ty::ReLateBound(debruijn, _) = *r {
-            self.add_binder(debruijn);
-        }
-    }
-
-    fn add_const(&mut self, c: &ty::Const<'_>) {
-        self.add_ty(c.ty);
-        match c.val {
-            ty::ConstKind::Unevaluated(_, substs, _) => {
-                self.add_substs(substs);
-                self.add_flags(TypeFlags::HAS_PROJECTION);
-            }
-            ty::ConstKind::Infer(infer) => {
-                self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES | TypeFlags::HAS_CT_INFER);
-                match infer {
-                    InferConst::Fresh(_) => {}
-                    InferConst::Var(_) => self.add_flags(TypeFlags::KEEP_IN_LOCAL_TCX),
-                }
-            }
-            ty::ConstKind::Bound(debruijn, _) => self.add_binder(debruijn),
-            ty::ConstKind::Param(_) => {
-                self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES);
-                self.add_flags(TypeFlags::HAS_PARAMS);
-            }
-            ty::ConstKind::Placeholder(_) => {
-                self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES);
-                self.add_flags(TypeFlags::HAS_CT_PLACEHOLDER);
-            }
-            ty::ConstKind::Value(_) => {}
-        }
-    }
-
-    fn add_existential_projection(&mut self, projection: &ty::ExistentialProjection<'_>) {
-        self.add_substs(projection.substs);
-        self.add_ty(projection.ty);
-    }
-
-    fn add_projection_ty(&mut self, projection_ty: &ty::ProjectionTy<'_>) {
-        self.add_substs(projection_ty.substs);
-    }
-
-    fn add_substs(&mut self, substs: SubstsRef<'_>) {
-        for kind in substs {
-            match kind.unpack() {
-                GenericArgKind::Type(ty) => self.add_ty(ty),
-                GenericArgKind::Lifetime(lt) => self.add_region(lt),
-                GenericArgKind::Const(ct) => self.add_const(ct),
-            }
-        }
-    }
-}
diff --git a/src/librustc/ty/fold.rs b/src/librustc/ty/fold.rs
deleted file mode 100644
index 3212bc72417..00000000000
--- a/src/librustc/ty/fold.rs
+++ /dev/null
@@ -1,1002 +0,0 @@
-//! Generalized type folding mechanism. The setup is a bit convoluted
-//! but allows for convenient usage. Let T be an instance of some
-//! "foldable type" (one which implements `TypeFoldable`) and F be an
-//! instance of a "folder" (a type which implements `TypeFolder`). Then
-//! the setup is intended to be:
-//!
-//!     T.fold_with(F) --calls--> F.fold_T(T) --calls--> T.super_fold_with(F)
-//!
-//! This way, when you define a new folder F, you can override
-//! `fold_T()` to customize the behavior, and invoke `T.super_fold_with()`
-//! to get the original behavior. Meanwhile, to actually fold
-//! something, you can just write `T.fold_with(F)`, which is
-//! convenient. (Note that `fold_with` will also transparently handle
-//! things like a `Vec<T>` where T is foldable and so on.)
-//!
-//! In this ideal setup, the only function that actually *does*
-//! anything is `T.super_fold_with()`, which traverses the type `T`.
-//! Moreover, `T.super_fold_with()` should only ever call `T.fold_with()`.
-//!
-//! In some cases, we follow a degenerate pattern where we do not have
-//! a `fold_T` method. Instead, `T.fold_with` traverses the structure directly.
-//! This is suboptimal because the behavior cannot be overridden, but it's
-//! much less work to implement. If you ever *do* need an override that
-//! doesn't exist, it's not hard to convert the degenerate pattern into the
-//! proper thing.
-//!
-//! A `TypeFoldable` T can also be visited by a `TypeVisitor` V using similar setup:
-//!
-//!     T.visit_with(V) --calls--> V.visit_T(T) --calls--> T.super_visit_with(V).
-//!
-//! These methods return true to indicate that the visitor has found what it is
-//! looking for, and does not need to visit anything else.
-
-use crate::ty::{self, flags::FlagComputation, Binder, Ty, TyCtxt, TypeFlags};
-use rustc_hir as hir;
-use rustc_hir::def_id::DefId;
-
-use rustc_data_structures::fx::FxHashSet;
-use std::collections::BTreeMap;
-use std::fmt;
-
-/// This trait is implemented for every type that can be folded.
-/// Basically, every type that has a corresponding method in `TypeFolder`.
-///
-/// To implement this conveniently, use the derive macro located in librustc_macros.
-pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
-    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self;
-    fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
-        self.super_fold_with(folder)
-    }
-
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool;
-    fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
-        self.super_visit_with(visitor)
-    }
-
-    /// Returns `true` if `self` has any late-bound regions that are either
-    /// bound by `binder` or bound by some binder outside of `binder`.
-    /// If `binder` is `ty::INNERMOST`, this indicates whether
-    /// there are any late-bound regions that appear free.
-    fn has_vars_bound_at_or_above(&self, binder: ty::DebruijnIndex) -> bool {
-        self.visit_with(&mut HasEscapingVarsVisitor { outer_index: binder })
-    }
-
-    /// Returns `true` if this `self` has any regions that escape `binder` (and
-    /// hence are not bound by it).
-    fn has_vars_bound_above(&self, binder: ty::DebruijnIndex) -> bool {
-        self.has_vars_bound_at_or_above(binder.shifted_in(1))
-    }
-
-    fn has_escaping_bound_vars(&self) -> bool {
-        self.has_vars_bound_at_or_above(ty::INNERMOST)
-    }
-
-    fn has_type_flags(&self, flags: TypeFlags) -> bool {
-        self.visit_with(&mut HasTypeFlagsVisitor { flags })
-    }
-    fn has_projections(&self) -> bool {
-        self.has_type_flags(TypeFlags::HAS_PROJECTION)
-    }
-    fn has_opaque_types(&self) -> bool {
-        self.has_type_flags(TypeFlags::HAS_TY_OPAQUE)
-    }
-    fn references_error(&self) -> bool {
-        self.has_type_flags(TypeFlags::HAS_TY_ERR)
-    }
-    fn has_param_types(&self) -> bool {
-        self.has_type_flags(TypeFlags::HAS_PARAMS)
-    }
-    fn has_infer_types(&self) -> bool {
-        self.has_type_flags(TypeFlags::HAS_TY_INFER)
-    }
-    fn has_infer_consts(&self) -> bool {
-        self.has_type_flags(TypeFlags::HAS_CT_INFER)
-    }
-    fn has_local_value(&self) -> bool {
-        self.has_type_flags(TypeFlags::KEEP_IN_LOCAL_TCX)
-    }
-    fn needs_infer(&self) -> bool {
-        self.has_type_flags(
-            TypeFlags::HAS_TY_INFER | TypeFlags::HAS_RE_INFER | TypeFlags::HAS_CT_INFER,
-        )
-    }
-    fn has_placeholders(&self) -> bool {
-        self.has_type_flags(
-            TypeFlags::HAS_RE_PLACEHOLDER
-                | TypeFlags::HAS_TY_PLACEHOLDER
-                | TypeFlags::HAS_CT_PLACEHOLDER,
-        )
-    }
-    fn needs_subst(&self) -> bool {
-        self.has_type_flags(TypeFlags::NEEDS_SUBST)
-    }
-    fn has_re_placeholders(&self) -> bool {
-        self.has_type_flags(TypeFlags::HAS_RE_PLACEHOLDER)
-    }
-    fn has_closure_types(&self) -> bool {
-        self.has_type_flags(TypeFlags::HAS_TY_CLOSURE)
-    }
-    /// "Free" regions in this context means that it has any region
-    /// that is not (a) erased or (b) late-bound.
-    fn has_free_regions(&self) -> bool {
-        self.has_type_flags(TypeFlags::HAS_FREE_REGIONS)
-    }
-
-    fn has_erased_regions(&self) -> bool {
-        self.has_type_flags(TypeFlags::HAS_RE_ERASED)
-    }
-
-    /// True if there are any un-erased free regions.
-    fn has_erasable_regions(&self) -> bool {
-        self.has_type_flags(TypeFlags::HAS_FREE_REGIONS)
-    }
-
-    /// Indicates whether this value references only 'global'
-    /// generic parameters that are the same regardless of what fn we are
-    /// in. This is used for caching.
-    fn is_global(&self) -> bool {
-        !self.has_type_flags(TypeFlags::HAS_FREE_LOCAL_NAMES)
-    }
-
-    /// True if there are any late-bound regions
-    fn has_late_bound_regions(&self) -> bool {
-        self.has_type_flags(TypeFlags::HAS_RE_LATE_BOUND)
-    }
-
-    /// A visitor that does not recurse into types, works like `fn walk_shallow` in `Ty`.
-    fn visit_tys_shallow(&self, visit: impl FnMut(Ty<'tcx>) -> bool) -> bool {
-        pub struct Visitor<F>(F);
-
-        impl<'tcx, F: FnMut(Ty<'tcx>) -> bool> TypeVisitor<'tcx> for Visitor<F> {
-            fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
-                self.0(ty)
-            }
-        }
-
-        self.visit_with(&mut Visitor(visit))
-    }
-}
-
-impl TypeFoldable<'tcx> for hir::Constness {
-    fn super_fold_with<F: TypeFolder<'tcx>>(&self, _: &mut F) -> Self {
-        *self
-    }
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> bool {
-        false
-    }
-}
-
-/// The `TypeFolder` trait defines the actual *folding*. There is a
-/// method defined for every foldable type. Each of these has a
-/// default implementation that does an "identity" fold. Within each
-/// identity fold, it should invoke `foo.fold_with(self)` to fold each
-/// sub-item.
-pub trait TypeFolder<'tcx>: Sized {
-    fn tcx<'a>(&'a self) -> TyCtxt<'tcx>;
-
-    fn fold_binder<T>(&mut self, t: &Binder<T>) -> Binder<T>
-    where
-        T: TypeFoldable<'tcx>,
-    {
-        t.super_fold_with(self)
-    }
-
-    fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
-        t.super_fold_with(self)
-    }
-
-    fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
-        r.super_fold_with(self)
-    }
-
-    fn fold_const(&mut self, c: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
-        c.super_fold_with(self)
-    }
-}
-
-pub trait TypeVisitor<'tcx>: Sized {
-    fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, t: &Binder<T>) -> bool {
-        t.super_visit_with(self)
-    }
-
-    fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
-        t.super_visit_with(self)
-    }
-
-    fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
-        r.super_visit_with(self)
-    }
-
-    fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> bool {
-        c.super_visit_with(self)
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////
-// Some sample folders
-
-pub struct BottomUpFolder<'tcx, F, G, H>
-where
-    F: FnMut(Ty<'tcx>) -> Ty<'tcx>,
-    G: FnMut(ty::Region<'tcx>) -> ty::Region<'tcx>,
-    H: FnMut(&'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx>,
-{
-    pub tcx: TyCtxt<'tcx>,
-    pub ty_op: F,
-    pub lt_op: G,
-    pub ct_op: H,
-}
-
-impl<'tcx, F, G, H> TypeFolder<'tcx> for BottomUpFolder<'tcx, F, G, H>
-where
-    F: FnMut(Ty<'tcx>) -> Ty<'tcx>,
-    G: FnMut(ty::Region<'tcx>) -> ty::Region<'tcx>,
-    H: FnMut(&'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx>,
-{
-    fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
-        self.tcx
-    }
-
-    fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
-        let t = ty.super_fold_with(self);
-        (self.ty_op)(t)
-    }
-
-    fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
-        let r = r.super_fold_with(self);
-        (self.lt_op)(r)
-    }
-
-    fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
-        let ct = ct.super_fold_with(self);
-        (self.ct_op)(ct)
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////
-// Region folder
-
-impl<'tcx> TyCtxt<'tcx> {
-    /// Collects the free and escaping regions in `value` into `region_set`. Returns
-    /// whether any late-bound regions were skipped
-    pub fn collect_regions<T>(self, value: &T, region_set: &mut FxHashSet<ty::Region<'tcx>>) -> bool
-    where
-        T: TypeFoldable<'tcx>,
-    {
-        let mut have_bound_regions = false;
-        self.fold_regions(value, &mut have_bound_regions, |r, d| {
-            region_set.insert(self.mk_region(r.shifted_out_to_binder(d)));
-            r
-        });
-        have_bound_regions
-    }
-
-    /// Folds the escaping and free regions in `value` using `f`, and
-    /// sets `skipped_regions` to true if any late-bound region was found
-    /// and skipped.
-    pub fn fold_regions<T>(
-        self,
-        value: &T,
-        skipped_regions: &mut bool,
-        mut f: impl FnMut(ty::Region<'tcx>, ty::DebruijnIndex) -> ty::Region<'tcx>,
-    ) -> T
-    where
-        T: TypeFoldable<'tcx>,
-    {
-        value.fold_with(&mut RegionFolder::new(self, skipped_regions, &mut f))
-    }
-
-    /// Invoke `callback` on every region appearing free in `value`.
-    pub fn for_each_free_region(
-        self,
-        value: &impl TypeFoldable<'tcx>,
-        mut callback: impl FnMut(ty::Region<'tcx>),
-    ) {
-        self.any_free_region_meets(value, |r| {
-            callback(r);
-            false
-        });
-    }
-
-    /// Returns `true` if `callback` returns true for every region appearing free in `value`.
-    pub fn all_free_regions_meet(
-        self,
-        value: &impl TypeFoldable<'tcx>,
-        mut callback: impl FnMut(ty::Region<'tcx>) -> bool,
-    ) -> bool {
-        !self.any_free_region_meets(value, |r| !callback(r))
-    }
-
-    /// Returns `true` if `callback` returns true for some region appearing free in `value`.
-    pub fn any_free_region_meets(
-        self,
-        value: &impl TypeFoldable<'tcx>,
-        callback: impl FnMut(ty::Region<'tcx>) -> bool,
-    ) -> bool {
-        return value.visit_with(&mut RegionVisitor { outer_index: ty::INNERMOST, callback });
-
-        struct RegionVisitor<F> {
-            /// The index of a binder *just outside* the things we have
-            /// traversed. If we encounter a bound region bound by this
-            /// binder or one outer to it, it appears free. Example:
-            ///
-            /// ```
-            ///    for<'a> fn(for<'b> fn(), T)
-            /// ^          ^          ^     ^
-            /// |          |          |     | here, would be shifted in 1
-            /// |          |          | here, would be shifted in 2
-            /// |          | here, would be `INNERMOST` shifted in by 1
-            /// | here, initially, binder would be `INNERMOST`
-            /// ```
-            ///
-            /// You see that, initially, *any* bound value is free,
-            /// because we've not traversed any binders. As we pass
-            /// through a binder, we shift the `outer_index` by 1 to
-            /// account for the new binder that encloses us.
-            outer_index: ty::DebruijnIndex,
-            callback: F,
-        }
-
-        impl<'tcx, F> TypeVisitor<'tcx> for RegionVisitor<F>
-        where
-            F: FnMut(ty::Region<'tcx>) -> bool,
-        {
-            fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, t: &Binder<T>) -> bool {
-                self.outer_index.shift_in(1);
-                let result = t.skip_binder().visit_with(self);
-                self.outer_index.shift_out(1);
-                result
-            }
-
-            fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
-                match *r {
-                    ty::ReLateBound(debruijn, _) if debruijn < self.outer_index => {
-                        false // ignore bound regions, keep visiting
-                    }
-                    _ => (self.callback)(r),
-                }
-            }
-
-            fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
-                // We're only interested in types involving regions
-                if ty.flags.intersects(TypeFlags::HAS_FREE_REGIONS) {
-                    ty.super_visit_with(self)
-                } else {
-                    false // keep visiting
-                }
-            }
-        }
-    }
-}
-
-/// Folds over the substructure of a type, visiting its component
-/// types and all regions that occur *free* within it.
-///
-/// That is, `Ty` can contain function or method types that bind
-/// regions at the call site (`ReLateBound`), and occurrences of
-/// regions (aka "lifetimes") that are bound within a type are not
-/// visited by this folder; only regions that occur free will be
-/// visited by `fld_r`.
-
-pub struct RegionFolder<'a, 'tcx> {
-    tcx: TyCtxt<'tcx>,
-    skipped_regions: &'a mut bool,
-
-    /// Stores the index of a binder *just outside* the stuff we have
-    /// visited.  So this begins as INNERMOST; when we pass through a
-    /// binder, it is incremented (via `shift_in`).
-    current_index: ty::DebruijnIndex,
-
-    /// Callback invokes for each free region. The `DebruijnIndex`
-    /// points to the binder *just outside* the ones we have passed
-    /// through.
-    fold_region_fn:
-        &'a mut (dyn FnMut(ty::Region<'tcx>, ty::DebruijnIndex) -> ty::Region<'tcx> + 'a),
-}
-
-impl<'a, 'tcx> RegionFolder<'a, 'tcx> {
-    #[inline]
-    pub fn new(
-        tcx: TyCtxt<'tcx>,
-        skipped_regions: &'a mut bool,
-        fold_region_fn: &'a mut dyn FnMut(ty::Region<'tcx>, ty::DebruijnIndex) -> ty::Region<'tcx>,
-    ) -> RegionFolder<'a, 'tcx> {
-        RegionFolder { tcx, skipped_regions, current_index: ty::INNERMOST, fold_region_fn }
-    }
-}
-
-impl<'a, 'tcx> TypeFolder<'tcx> for RegionFolder<'a, 'tcx> {
-    fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
-        self.tcx
-    }
-
-    fn fold_binder<T: TypeFoldable<'tcx>>(&mut self, t: &ty::Binder<T>) -> ty::Binder<T> {
-        self.current_index.shift_in(1);
-        let t = t.super_fold_with(self);
-        self.current_index.shift_out(1);
-        t
-    }
-
-    fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
-        match *r {
-            ty::ReLateBound(debruijn, _) if debruijn < self.current_index => {
-                debug!(
-                    "RegionFolder.fold_region({:?}) skipped bound region (current index={:?})",
-                    r, self.current_index
-                );
-                *self.skipped_regions = true;
-                r
-            }
-            _ => {
-                debug!(
-                    "RegionFolder.fold_region({:?}) folding free region (current_index={:?})",
-                    r, self.current_index
-                );
-                (self.fold_region_fn)(r, self.current_index)
-            }
-        }
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////
-// Bound vars replacer
-
-/// Replaces the escaping bound vars (late bound regions or bound types) in a type.
-struct BoundVarReplacer<'a, 'tcx> {
-    tcx: TyCtxt<'tcx>,
-
-    /// As with `RegionFolder`, represents the index of a binder *just outside*
-    /// the ones we have visited.
-    current_index: ty::DebruijnIndex,
-
-    fld_r: &'a mut (dyn FnMut(ty::BoundRegion) -> ty::Region<'tcx> + 'a),
-    fld_t: &'a mut (dyn FnMut(ty::BoundTy) -> Ty<'tcx> + 'a),
-    fld_c: &'a mut (dyn FnMut(ty::BoundVar, Ty<'tcx>) -> &'tcx ty::Const<'tcx> + 'a),
-}
-
-impl<'a, 'tcx> BoundVarReplacer<'a, 'tcx> {
-    fn new<F, G, H>(tcx: TyCtxt<'tcx>, fld_r: &'a mut F, fld_t: &'a mut G, fld_c: &'a mut H) -> Self
-    where
-        F: FnMut(ty::BoundRegion) -> ty::Region<'tcx>,
-        G: FnMut(ty::BoundTy) -> Ty<'tcx>,
-        H: FnMut(ty::BoundVar, Ty<'tcx>) -> &'tcx ty::Const<'tcx>,
-    {
-        BoundVarReplacer { tcx, current_index: ty::INNERMOST, fld_r, fld_t, fld_c }
-    }
-}
-
-impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> {
-    fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
-        self.tcx
-    }
-
-    fn fold_binder<T: TypeFoldable<'tcx>>(&mut self, t: &ty::Binder<T>) -> ty::Binder<T> {
-        self.current_index.shift_in(1);
-        let t = t.super_fold_with(self);
-        self.current_index.shift_out(1);
-        t
-    }
-
-    fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
-        match t.kind {
-            ty::Bound(debruijn, bound_ty) => {
-                if debruijn == self.current_index {
-                    let fld_t = &mut self.fld_t;
-                    let ty = fld_t(bound_ty);
-                    ty::fold::shift_vars(self.tcx, &ty, self.current_index.as_u32())
-                } else {
-                    t
-                }
-            }
-            _ => {
-                if !t.has_vars_bound_at_or_above(self.current_index) {
-                    // Nothing more to substitute.
-                    t
-                } else {
-                    t.super_fold_with(self)
-                }
-            }
-        }
-    }
-
-    fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
-        match *r {
-            ty::ReLateBound(debruijn, br) if debruijn == self.current_index => {
-                let fld_r = &mut self.fld_r;
-                let region = fld_r(br);
-                if let ty::ReLateBound(debruijn1, br) = *region {
-                    // If the callback returns a late-bound region,
-                    // that region should always use the INNERMOST
-                    // debruijn index. Then we adjust it to the
-                    // correct depth.
-                    assert_eq!(debruijn1, ty::INNERMOST);
-                    self.tcx.mk_region(ty::ReLateBound(debruijn, br))
-                } else {
-                    region
-                }
-            }
-            _ => r,
-        }
-    }
-
-    fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
-        if let ty::Const { val: ty::ConstKind::Bound(debruijn, bound_const), ty } = *ct {
-            if debruijn == self.current_index {
-                let fld_c = &mut self.fld_c;
-                let ct = fld_c(bound_const, ty);
-                ty::fold::shift_vars(self.tcx, &ct, self.current_index.as_u32())
-            } else {
-                ct
-            }
-        } else {
-            if !ct.has_vars_bound_at_or_above(self.current_index) {
-                // Nothing more to substitute.
-                ct
-            } else {
-                ct.super_fold_with(self)
-            }
-        }
-    }
-}
-
-impl<'tcx> TyCtxt<'tcx> {
-    /// Replaces all regions bound by the given `Binder` with the
-    /// results returned by the closure; the closure is expected to
-    /// return a free region (relative to this binder), and hence the
-    /// binder is removed in the return type. The closure is invoked
-    /// once for each unique `BoundRegion`; multiple references to the
-    /// same `BoundRegion` will reuse the previous result. A map is
-    /// returned at the end with each bound region and the free region
-    /// that replaced it.
-    ///
-    /// This method only replaces late bound regions and the result may still
-    /// contain escaping bound types.
-    pub fn replace_late_bound_regions<T, F>(
-        self,
-        value: &Binder<T>,
-        fld_r: F,
-    ) -> (T, BTreeMap<ty::BoundRegion, ty::Region<'tcx>>)
-    where
-        F: FnMut(ty::BoundRegion) -> ty::Region<'tcx>,
-        T: TypeFoldable<'tcx>,
-    {
-        // identity for bound types and consts
-        let fld_t = |bound_ty| self.mk_ty(ty::Bound(ty::INNERMOST, bound_ty));
-        let fld_c = |bound_ct, ty| {
-            self.mk_const(ty::Const { val: ty::ConstKind::Bound(ty::INNERMOST, bound_ct), ty })
-        };
-        self.replace_escaping_bound_vars(value.skip_binder(), fld_r, fld_t, fld_c)
-    }
-
-    /// Replaces all escaping bound vars. The `fld_r` closure replaces escaping
-    /// bound regions; the `fld_t` closure replaces escaping bound types and the `fld_c`
-    /// closure replaces escaping bound consts.
-    pub fn replace_escaping_bound_vars<T, F, G, H>(
-        self,
-        value: &T,
-        mut fld_r: F,
-        mut fld_t: G,
-        mut fld_c: H,
-    ) -> (T, BTreeMap<ty::BoundRegion, ty::Region<'tcx>>)
-    where
-        F: FnMut(ty::BoundRegion) -> ty::Region<'tcx>,
-        G: FnMut(ty::BoundTy) -> Ty<'tcx>,
-        H: FnMut(ty::BoundVar, Ty<'tcx>) -> &'tcx ty::Const<'tcx>,
-        T: TypeFoldable<'tcx>,
-    {
-        use rustc_data_structures::fx::FxHashMap;
-
-        let mut region_map = BTreeMap::new();
-        let mut type_map = FxHashMap::default();
-        let mut const_map = FxHashMap::default();
-
-        if !value.has_escaping_bound_vars() {
-            (value.clone(), region_map)
-        } else {
-            let mut real_fld_r = |br| *region_map.entry(br).or_insert_with(|| fld_r(br));
-
-            let mut real_fld_t =
-                |bound_ty| *type_map.entry(bound_ty).or_insert_with(|| fld_t(bound_ty));
-
-            let mut real_fld_c =
-                |bound_ct, ty| *const_map.entry(bound_ct).or_insert_with(|| fld_c(bound_ct, ty));
-
-            let mut replacer =
-                BoundVarReplacer::new(self, &mut real_fld_r, &mut real_fld_t, &mut real_fld_c);
-            let result = value.fold_with(&mut replacer);
-            (result, region_map)
-        }
-    }
-
-    /// Replaces all types or regions bound by the given `Binder`. The `fld_r`
-    /// closure replaces bound regions while the `fld_t` closure replaces bound
-    /// types.
-    pub fn replace_bound_vars<T, F, G, H>(
-        self,
-        value: &Binder<T>,
-        fld_r: F,
-        fld_t: G,
-        fld_c: H,
-    ) -> (T, BTreeMap<ty::BoundRegion, ty::Region<'tcx>>)
-    where
-        F: FnMut(ty::BoundRegion) -> ty::Region<'tcx>,
-        G: FnMut(ty::BoundTy) -> Ty<'tcx>,
-        H: FnMut(ty::BoundVar, Ty<'tcx>) -> &'tcx ty::Const<'tcx>,
-        T: TypeFoldable<'tcx>,
-    {
-        self.replace_escaping_bound_vars(value.skip_binder(), fld_r, fld_t, fld_c)
-    }
-
-    /// Replaces any late-bound regions bound in `value` with
-    /// free variants attached to `all_outlive_scope`.
-    pub fn liberate_late_bound_regions<T>(
-        &self,
-        all_outlive_scope: DefId,
-        value: &ty::Binder<T>,
-    ) -> T
-    where
-        T: TypeFoldable<'tcx>,
-    {
-        self.replace_late_bound_regions(value, |br| {
-            self.mk_region(ty::ReFree(ty::FreeRegion {
-                scope: all_outlive_scope,
-                bound_region: br,
-            }))
-        })
-        .0
-    }
-
-    /// Returns a set of all late-bound regions that are constrained
-    /// by `value`, meaning that if we instantiate those LBR with
-    /// variables and equate `value` with something else, those
-    /// variables will also be equated.
-    pub fn collect_constrained_late_bound_regions<T>(
-        &self,
-        value: &Binder<T>,
-    ) -> FxHashSet<ty::BoundRegion>
-    where
-        T: TypeFoldable<'tcx>,
-    {
-        self.collect_late_bound_regions(value, true)
-    }
-
-    /// Returns a set of all late-bound regions that appear in `value` anywhere.
-    pub fn collect_referenced_late_bound_regions<T>(
-        &self,
-        value: &Binder<T>,
-    ) -> FxHashSet<ty::BoundRegion>
-    where
-        T: TypeFoldable<'tcx>,
-    {
-        self.collect_late_bound_regions(value, false)
-    }
-
-    fn collect_late_bound_regions<T>(
-        &self,
-        value: &Binder<T>,
-        just_constraint: bool,
-    ) -> FxHashSet<ty::BoundRegion>
-    where
-        T: TypeFoldable<'tcx>,
-    {
-        let mut collector = LateBoundRegionsCollector::new(just_constraint);
-        let result = value.skip_binder().visit_with(&mut collector);
-        assert!(!result); // should never have stopped early
-        collector.regions
-    }
-
-    /// Replaces any late-bound regions bound in `value` with `'erased`. Useful in codegen but also
-    /// method lookup and a few other places where precise region relationships are not required.
-    pub fn erase_late_bound_regions<T>(self, value: &Binder<T>) -> T
-    where
-        T: TypeFoldable<'tcx>,
-    {
-        self.replace_late_bound_regions(value, |_| self.lifetimes.re_erased).0
-    }
-
-    /// Rewrite any late-bound regions so that they are anonymous. Region numbers are
-    /// assigned starting at 1 and increasing monotonically in the order traversed
-    /// by the fold operation.
-    ///
-    /// The chief purpose of this function is to canonicalize regions so that two
-    /// `FnSig`s or `TraitRef`s which are equivalent up to region naming will become
-    /// structurally identical. For example, `for<'a, 'b> fn(&'a isize, &'b isize)` and
-    /// `for<'a, 'b> fn(&'b isize, &'a isize)` will become identical after anonymization.
-    pub fn anonymize_late_bound_regions<T>(self, sig: &Binder<T>) -> Binder<T>
-    where
-        T: TypeFoldable<'tcx>,
-    {
-        let mut counter = 0;
-        Binder::bind(
-            self.replace_late_bound_regions(sig, |_| {
-                counter += 1;
-                self.mk_region(ty::ReLateBound(ty::INNERMOST, ty::BrAnon(counter)))
-            })
-            .0,
-        )
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////
-// Shifter
-//
-// Shifts the De Bruijn indices on all escaping bound vars by a
-// fixed amount. Useful in substitution or when otherwise introducing
-// a binding level that is not intended to capture the existing bound
-// vars. See comment on `shift_vars_through_binders` method in
-// `subst.rs` for more details.
-
-enum Direction {
-    In,
-    Out,
-}
-
-struct Shifter<'tcx> {
-    tcx: TyCtxt<'tcx>,
-    current_index: ty::DebruijnIndex,
-    amount: u32,
-    direction: Direction,
-}
-
-impl Shifter<'tcx> {
-    pub fn new(tcx: TyCtxt<'tcx>, amount: u32, direction: Direction) -> Self {
-        Shifter { tcx, current_index: ty::INNERMOST, amount, direction }
-    }
-}
-
-impl TypeFolder<'tcx> for Shifter<'tcx> {
-    fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
-        self.tcx
-    }
-
-    fn fold_binder<T: TypeFoldable<'tcx>>(&mut self, t: &ty::Binder<T>) -> ty::Binder<T> {
-        self.current_index.shift_in(1);
-        let t = t.super_fold_with(self);
-        self.current_index.shift_out(1);
-        t
-    }
-
-    fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
-        match *r {
-            ty::ReLateBound(debruijn, br) => {
-                if self.amount == 0 || debruijn < self.current_index {
-                    r
-                } else {
-                    let debruijn = match self.direction {
-                        Direction::In => debruijn.shifted_in(self.amount),
-                        Direction::Out => {
-                            assert!(debruijn.as_u32() >= self.amount);
-                            debruijn.shifted_out(self.amount)
-                        }
-                    };
-                    let shifted = ty::ReLateBound(debruijn, br);
-                    self.tcx.mk_region(shifted)
-                }
-            }
-            _ => r,
-        }
-    }
-
-    fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
-        match ty.kind {
-            ty::Bound(debruijn, bound_ty) => {
-                if self.amount == 0 || debruijn < self.current_index {
-                    ty
-                } else {
-                    let debruijn = match self.direction {
-                        Direction::In => debruijn.shifted_in(self.amount),
-                        Direction::Out => {
-                            assert!(debruijn.as_u32() >= self.amount);
-                            debruijn.shifted_out(self.amount)
-                        }
-                    };
-                    self.tcx.mk_ty(ty::Bound(debruijn, bound_ty))
-                }
-            }
-
-            _ => ty.super_fold_with(self),
-        }
-    }
-
-    fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
-        if let ty::Const { val: ty::ConstKind::Bound(debruijn, bound_ct), ty } = *ct {
-            if self.amount == 0 || debruijn < self.current_index {
-                ct
-            } else {
-                let debruijn = match self.direction {
-                    Direction::In => debruijn.shifted_in(self.amount),
-                    Direction::Out => {
-                        assert!(debruijn.as_u32() >= self.amount);
-                        debruijn.shifted_out(self.amount)
-                    }
-                };
-                self.tcx.mk_const(ty::Const { val: ty::ConstKind::Bound(debruijn, bound_ct), ty })
-            }
-        } else {
-            ct.super_fold_with(self)
-        }
-    }
-}
-
-pub fn shift_region<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    region: ty::Region<'tcx>,
-    amount: u32,
-) -> ty::Region<'tcx> {
-    match region {
-        ty::ReLateBound(debruijn, br) if amount > 0 => {
-            tcx.mk_region(ty::ReLateBound(debruijn.shifted_in(amount), *br))
-        }
-        _ => region,
-    }
-}
-
-pub fn shift_vars<'tcx, T>(tcx: TyCtxt<'tcx>, value: &T, amount: u32) -> T
-where
-    T: TypeFoldable<'tcx>,
-{
-    debug!("shift_vars(value={:?}, amount={})", value, amount);
-
-    value.fold_with(&mut Shifter::new(tcx, amount, Direction::In))
-}
-
-pub fn shift_out_vars<'tcx, T>(tcx: TyCtxt<'tcx>, value: &T, amount: u32) -> T
-where
-    T: TypeFoldable<'tcx>,
-{
-    debug!("shift_out_vars(value={:?}, amount={})", value, amount);
-
-    value.fold_with(&mut Shifter::new(tcx, amount, Direction::Out))
-}
-
-/// An "escaping var" is a bound var whose binder is not part of `t`. A bound var can be a
-/// bound region or a bound type.
-///
-/// So, for example, consider a type like the following, which has two binders:
-///
-///    for<'a> fn(x: for<'b> fn(&'a isize, &'b isize))
-///    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ outer scope
-///                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~  inner scope
-///
-/// This type has *bound regions* (`'a`, `'b`), but it does not have escaping regions, because the
-/// binders of both `'a` and `'b` are part of the type itself. However, if we consider the *inner
-/// fn type*, that type has an escaping region: `'a`.
-///
-/// Note that what I'm calling an "escaping var" is often just called a "free var". However,
-/// we already use the term "free var". It refers to the regions or types that we use to represent
-/// bound regions or type params on a fn definition while we are type checking its body.
-///
-/// To clarify, conceptually there is no particular difference between
-/// an "escaping" var and a "free" var. However, there is a big
-/// difference in practice. Basically, when "entering" a binding
-/// level, one is generally required to do some sort of processing to
-/// a bound var, such as replacing it with a fresh/placeholder
-/// var, or making an entry in the environment to represent the
-/// scope to which it is attached, etc. An escaping var represents
-/// a bound var for which this processing has not yet been done.
-struct HasEscapingVarsVisitor {
-    /// Anything bound by `outer_index` or "above" is escaping.
-    outer_index: ty::DebruijnIndex,
-}
-
-impl<'tcx> TypeVisitor<'tcx> for HasEscapingVarsVisitor {
-    fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, t: &Binder<T>) -> bool {
-        self.outer_index.shift_in(1);
-        let result = t.super_visit_with(self);
-        self.outer_index.shift_out(1);
-        result
-    }
-
-    fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
-        // If the outer-exclusive-binder is *strictly greater* than
-        // `outer_index`, that means that `t` contains some content
-        // bound at `outer_index` or above (because
-        // `outer_exclusive_binder` is always 1 higher than the
-        // content in `t`). Therefore, `t` has some escaping vars.
-        t.outer_exclusive_binder > self.outer_index
-    }
-
-    fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
-        // If the region is bound by `outer_index` or anything outside
-        // of outer index, then it escapes the binders we have
-        // visited.
-        r.bound_at_or_above_binder(self.outer_index)
-    }
-
-    fn visit_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> bool {
-        // we don't have a `visit_infer_const` callback, so we have to
-        // hook in here to catch this case (annoying...), but
-        // otherwise we do want to remember to visit the rest of the
-        // const, as it has types/regions embedded in a lot of other
-        // places.
-        match ct.val {
-            ty::ConstKind::Bound(debruijn, _) if debruijn >= self.outer_index => true,
-            _ => ct.super_visit_with(self),
-        }
-    }
-}
-
-// FIXME: Optimize for checking for infer flags
-struct HasTypeFlagsVisitor {
-    flags: ty::TypeFlags,
-}
-
-impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor {
-    fn visit_ty(&mut self, t: Ty<'_>) -> bool {
-        debug!("HasTypeFlagsVisitor: t={:?} t.flags={:?} self.flags={:?}", t, t.flags, self.flags);
-        t.flags.intersects(self.flags)
-    }
-
-    fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
-        let flags = r.type_flags();
-        debug!("HasTypeFlagsVisitor: r={:?} r.flags={:?} self.flags={:?}", r, flags, self.flags);
-        flags.intersects(self.flags)
-    }
-
-    fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> bool {
-        let flags = FlagComputation::for_const(c);
-        debug!("HasTypeFlagsVisitor: c={:?} c.flags={:?} self.flags={:?}", c, flags, self.flags);
-        flags.intersects(self.flags)
-    }
-}
-
-/// Collects all the late-bound regions at the innermost binding level
-/// into a hash set.
-struct LateBoundRegionsCollector {
-    current_index: ty::DebruijnIndex,
-    regions: FxHashSet<ty::BoundRegion>,
-
-    /// `true` if we only want regions that are known to be
-    /// "constrained" when you equate this type with another type. In
-    /// particular, if you have e.g., `&'a u32` and `&'b u32`, equating
-    /// them constraints `'a == 'b`. But if you have `<&'a u32 as
-    /// Trait>::Foo` and `<&'b u32 as Trait>::Foo`, normalizing those
-    /// types may mean that `'a` and `'b` don't appear in the results,
-    /// so they are not considered *constrained*.
-    just_constrained: bool,
-}
-
-impl LateBoundRegionsCollector {
-    fn new(just_constrained: bool) -> Self {
-        LateBoundRegionsCollector {
-            current_index: ty::INNERMOST,
-            regions: Default::default(),
-            just_constrained,
-        }
-    }
-}
-
-impl<'tcx> TypeVisitor<'tcx> for LateBoundRegionsCollector {
-    fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, t: &Binder<T>) -> bool {
-        self.current_index.shift_in(1);
-        let result = t.super_visit_with(self);
-        self.current_index.shift_out(1);
-        result
-    }
-
-    fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
-        // if we are only looking for "constrained" region, we have to
-        // ignore the inputs to a projection, as they may not appear
-        // in the normalized form
-        if self.just_constrained {
-            match t.kind {
-                ty::Projection(..) | ty::Opaque(..) => {
-                    return false;
-                }
-                _ => {}
-            }
-        }
-
-        t.super_visit_with(self)
-    }
-
-    fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
-        if let ty::ReLateBound(debruijn, br) = *r {
-            if debruijn == self.current_index {
-                self.regions.insert(br);
-            }
-        }
-        false
-    }
-}
diff --git a/src/librustc/ty/free_region_map.rs b/src/librustc/ty/free_region_map.rs
deleted file mode 100644
index 2ab12a4acbf..00000000000
--- a/src/librustc/ty/free_region_map.rs
+++ /dev/null
@@ -1,133 +0,0 @@
-use crate::ty::{self, Lift, Region, TyCtxt};
-use rustc_data_structures::transitive_relation::TransitiveRelation;
-
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Default, HashStable)]
-pub struct FreeRegionMap<'tcx> {
-    // Stores the relation `a < b`, where `a` and `b` are regions.
-    //
-    // Invariant: only free regions like `'x` or `'static` are stored
-    // in this relation, not scopes.
-    relation: TransitiveRelation<Region<'tcx>>,
-}
-
-impl<'tcx> FreeRegionMap<'tcx> {
-    pub fn elements(&self) -> impl Iterator<Item = &Region<'tcx>> {
-        self.relation.elements()
-    }
-
-    pub fn is_empty(&self) -> bool {
-        self.relation.is_empty()
-    }
-
-    // Record that `'sup:'sub`. Or, put another way, `'sub <= 'sup`.
-    // (with the exception that `'static: 'x` is not notable)
-    pub fn relate_regions(&mut self, sub: Region<'tcx>, sup: Region<'tcx>) {
-        debug!("relate_regions(sub={:?}, sup={:?})", sub, sup);
-        if self.is_free_or_static(sub) && self.is_free(sup) {
-            self.relation.add(sub, sup)
-        }
-    }
-
-    /// Tests whether `r_a <= r_b`.
-    ///
-    /// Both regions must meet `is_free_or_static`.
-    ///
-    /// Subtle: one tricky case that this code gets correct is as
-    /// follows. If we know that `r_b: 'static`, then this function
-    /// will return true, even though we don't know anything that
-    /// directly relates `r_a` and `r_b`.
-    ///
-    /// Also available through the `FreeRegionRelations` trait below.
-    pub fn sub_free_regions(
-        &self,
-        tcx: TyCtxt<'tcx>,
-        r_a: Region<'tcx>,
-        r_b: Region<'tcx>,
-    ) -> bool {
-        assert!(self.is_free_or_static(r_a) && self.is_free_or_static(r_b));
-        let re_static = tcx.lifetimes.re_static;
-        if self.check_relation(re_static, r_b) {
-            // `'a <= 'static` is always true, and not stored in the
-            // relation explicitly, so check if `'b` is `'static` (or
-            // equivalent to it)
-            true
-        } else {
-            self.check_relation(r_a, r_b)
-        }
-    }
-
-    /// Check whether `r_a <= r_b` is found in the relation.
-    fn check_relation(&self, r_a: Region<'tcx>, r_b: Region<'tcx>) -> bool {
-        r_a == r_b || self.relation.contains(&r_a, &r_b)
-    }
-
-    /// True for free regions other than `'static`.
-    pub fn is_free(&self, r: Region<'_>) -> bool {
-        match *r {
-            ty::ReEarlyBound(_) | ty::ReFree(_) => true,
-            _ => false,
-        }
-    }
-
-    /// True if `r` is a free region or static of the sort that this
-    /// free region map can be used with.
-    pub fn is_free_or_static(&self, r: Region<'_>) -> bool {
-        match *r {
-            ty::ReStatic => true,
-            _ => self.is_free(r),
-        }
-    }
-
-    /// Computes the least-upper-bound of two free regions. In some
-    /// cases, this is more conservative than necessary, in order to
-    /// avoid making arbitrary choices. See
-    /// `TransitiveRelation::postdom_upper_bound` for more details.
-    pub fn lub_free_regions(
-        &self,
-        tcx: TyCtxt<'tcx>,
-        r_a: Region<'tcx>,
-        r_b: Region<'tcx>,
-    ) -> Region<'tcx> {
-        debug!("lub_free_regions(r_a={:?}, r_b={:?})", r_a, r_b);
-        assert!(self.is_free(r_a));
-        assert!(self.is_free(r_b));
-        let result = if r_a == r_b {
-            r_a
-        } else {
-            match self.relation.postdom_upper_bound(&r_a, &r_b) {
-                None => tcx.lifetimes.re_static,
-                Some(r) => *r,
-            }
-        };
-        debug!("lub_free_regions(r_a={:?}, r_b={:?}) = {:?}", r_a, r_b, result);
-        result
-    }
-}
-
-/// The NLL region handling code represents free region relations in a
-/// slightly different way; this trait allows functions to be abstract
-/// over which version is in use.
-pub trait FreeRegionRelations<'tcx> {
-    /// Tests whether `r_a <= r_b`. Both must be free regions or
-    /// `'static`.
-    fn sub_free_regions(
-        &self,
-        tcx: TyCtxt<'tcx>,
-        shorter: ty::Region<'tcx>,
-        longer: ty::Region<'tcx>,
-    ) -> bool;
-}
-
-impl<'tcx> FreeRegionRelations<'tcx> for FreeRegionMap<'tcx> {
-    fn sub_free_regions(&self, tcx: TyCtxt<'tcx>, r_a: Region<'tcx>, r_b: Region<'tcx>) -> bool {
-        // invoke the "inherent method"
-        self.sub_free_regions(tcx, r_a, r_b)
-    }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for FreeRegionMap<'a> {
-    type Lifted = FreeRegionMap<'tcx>;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<FreeRegionMap<'tcx>> {
-        self.relation.maybe_map(|&fr| tcx.lift(&fr)).map(|relation| FreeRegionMap { relation })
-    }
-}
diff --git a/src/librustc/ty/inhabitedness/def_id_forest.rs b/src/librustc/ty/inhabitedness/def_id_forest.rs
deleted file mode 100644
index 14ead77653c..00000000000
--- a/src/librustc/ty/inhabitedness/def_id_forest.rs
+++ /dev/null
@@ -1,113 +0,0 @@
-use crate::ty::context::TyCtxt;
-use crate::ty::{DefId, DefIdTree};
-use rustc_hir::CRATE_HIR_ID;
-use smallvec::SmallVec;
-use std::mem;
-
-/// Represents a forest of `DefId`s closed under the ancestor relation. That is,
-/// if a `DefId` representing a module is contained in the forest then all
-/// `DefId`s defined in that module or submodules are also implicitly contained
-/// in the forest.
-///
-/// This is used to represent a set of modules in which a type is visibly
-/// uninhabited.
-#[derive(Clone)]
-pub struct DefIdForest {
-    /// The minimal set of `DefId`s required to represent the whole set.
-    /// If A and B are DefIds in the `DefIdForest`, and A is a descendant
-    /// of B, then only B will be in `root_ids`.
-    /// We use a `SmallVec` here because (for its use for caching inhabitedness)
-    /// its rare that this will contain even two IDs.
-    root_ids: SmallVec<[DefId; 1]>,
-}
-
-impl<'tcx> DefIdForest {
-    /// Creates an empty forest.
-    pub fn empty() -> DefIdForest {
-        DefIdForest { root_ids: SmallVec::new() }
-    }
-
-    /// Creates a forest consisting of a single tree representing the entire
-    /// crate.
-    #[inline]
-    pub fn full(tcx: TyCtxt<'tcx>) -> DefIdForest {
-        let crate_id = tcx.hir().local_def_id(CRATE_HIR_ID);
-        DefIdForest::from_id(crate_id)
-    }
-
-    /// Creates a forest containing a `DefId` and all its descendants.
-    pub fn from_id(id: DefId) -> DefIdForest {
-        let mut root_ids = SmallVec::new();
-        root_ids.push(id);
-        DefIdForest { root_ids }
-    }
-
-    /// Tests whether the forest is empty.
-    pub fn is_empty(&self) -> bool {
-        self.root_ids.is_empty()
-    }
-
-    /// Tests whether the forest contains a given DefId.
-    pub fn contains(&self, tcx: TyCtxt<'tcx>, id: DefId) -> bool {
-        self.root_ids.iter().any(|root_id| tcx.is_descendant_of(id, *root_id))
-    }
-
-    /// Calculate the intersection of a collection of forests.
-    pub fn intersection<I>(tcx: TyCtxt<'tcx>, iter: I) -> DefIdForest
-    where
-        I: IntoIterator<Item = DefIdForest>,
-    {
-        let mut iter = iter.into_iter();
-        let mut ret = if let Some(first) = iter.next() {
-            first
-        } else {
-            return DefIdForest::full(tcx);
-        };
-
-        let mut next_ret = SmallVec::new();
-        let mut old_ret: SmallVec<[DefId; 1]> = SmallVec::new();
-        for next_forest in iter {
-            // No need to continue if the intersection is already empty.
-            if ret.is_empty() {
-                break;
-            }
-
-            for id in ret.root_ids.drain(..) {
-                if next_forest.contains(tcx, id) {
-                    next_ret.push(id);
-                } else {
-                    old_ret.push(id);
-                }
-            }
-            ret.root_ids.extend(old_ret.drain(..));
-
-            next_ret.extend(next_forest.root_ids.into_iter().filter(|&id| ret.contains(tcx, id)));
-
-            mem::swap(&mut next_ret, &mut ret.root_ids);
-            next_ret.drain(..);
-        }
-        ret
-    }
-
-    /// Calculate the union of a collection of forests.
-    pub fn union<I>(tcx: TyCtxt<'tcx>, iter: I) -> DefIdForest
-    where
-        I: IntoIterator<Item = DefIdForest>,
-    {
-        let mut ret = DefIdForest::empty();
-        let mut next_ret = SmallVec::new();
-        for next_forest in iter {
-            next_ret.extend(ret.root_ids.drain(..).filter(|&id| !next_forest.contains(tcx, id)));
-
-            for id in next_forest.root_ids {
-                if !next_ret.contains(&id) {
-                    next_ret.push(id);
-                }
-            }
-
-            mem::swap(&mut next_ret, &mut ret.root_ids);
-            next_ret.drain(..);
-        }
-        ret
-    }
-}
diff --git a/src/librustc/ty/inhabitedness/mod.rs b/src/librustc/ty/inhabitedness/mod.rs
deleted file mode 100644
index 144e3bc9c8b..00000000000
--- a/src/librustc/ty/inhabitedness/mod.rs
+++ /dev/null
@@ -1,206 +0,0 @@
-pub use self::def_id_forest::DefIdForest;
-
-use crate::ty;
-use crate::ty::context::TyCtxt;
-use crate::ty::TyKind::*;
-use crate::ty::{AdtDef, FieldDef, Ty, TyS, VariantDef};
-use crate::ty::{AdtKind, Visibility};
-use crate::ty::{DefId, SubstsRef};
-
-mod def_id_forest;
-
-// The methods in this module calculate `DefIdForest`s of modules in which a
-// `AdtDef`/`VariantDef`/`FieldDef` is visibly uninhabited.
-//
-// # Example
-// ```rust
-// enum Void {}
-// mod a {
-//     pub mod b {
-//         pub struct SecretlyUninhabited {
-//             _priv: !,
-//         }
-//     }
-// }
-//
-// mod c {
-//     pub struct AlsoSecretlyUninhabited {
-//         _priv: Void,
-//     }
-//     mod d {
-//     }
-// }
-//
-// struct Foo {
-//     x: a::b::SecretlyUninhabited,
-//     y: c::AlsoSecretlyUninhabited,
-// }
-// ```
-// In this code, the type `Foo` will only be visibly uninhabited inside the
-// modules `b`, `c` and `d`. Calling `uninhabited_from` on `Foo` or its `AdtDef` will
-// return the forest of modules {`b`, `c`->`d`} (represented in a `DefIdForest` by the
-// set {`b`, `c`}).
-//
-// We need this information for pattern-matching on `Foo` or types that contain
-// `Foo`.
-//
-// # Example
-// ```rust
-// let foo_result: Result<T, Foo> = ... ;
-// let Ok(t) = foo_result;
-// ```
-// This code should only compile in modules where the uninhabitedness of `Foo` is
-// visible.
-
-impl<'tcx> TyCtxt<'tcx> {
-    /// Checks whether a type is visibly uninhabited from a particular module.
-    ///
-    /// # Example
-    /// ```rust
-    /// enum Void {}
-    /// mod a {
-    ///     pub mod b {
-    ///         pub struct SecretlyUninhabited {
-    ///             _priv: !,
-    ///         }
-    ///     }
-    /// }
-    ///
-    /// mod c {
-    ///     pub struct AlsoSecretlyUninhabited {
-    ///         _priv: Void,
-    ///     }
-    ///     mod d {
-    ///     }
-    /// }
-    ///
-    /// struct Foo {
-    ///     x: a::b::SecretlyUninhabited,
-    ///     y: c::AlsoSecretlyUninhabited,
-    /// }
-    /// ```
-    /// In this code, the type `Foo` will only be visibly uninhabited inside the
-    /// modules b, c and d. This effects pattern-matching on `Foo` or types that
-    /// contain `Foo`.
-    ///
-    /// # Example
-    /// ```rust
-    /// let foo_result: Result<T, Foo> = ... ;
-    /// let Ok(t) = foo_result;
-    /// ```
-    /// This code should only compile in modules where the uninhabitedness of Foo is
-    /// visible.
-    pub fn is_ty_uninhabited_from(self, module: DefId, ty: Ty<'tcx>) -> bool {
-        // To check whether this type is uninhabited at all (not just from the
-        // given node), you could check whether the forest is empty.
-        // ```
-        // forest.is_empty()
-        // ```
-        ty.uninhabited_from(self).contains(self, module)
-    }
-
-    pub fn is_ty_uninhabited_from_any_module(self, ty: Ty<'tcx>) -> bool {
-        !ty.uninhabited_from(self).is_empty()
-    }
-}
-
-impl<'tcx> AdtDef {
-    /// Calculates the forest of `DefId`s from which this ADT is visibly uninhabited.
-    fn uninhabited_from(&self, tcx: TyCtxt<'tcx>, substs: SubstsRef<'tcx>) -> DefIdForest {
-        // Non-exhaustive ADTs from other crates are always considered inhabited.
-        if self.is_variant_list_non_exhaustive() && !self.did.is_local() {
-            DefIdForest::empty()
-        } else {
-            DefIdForest::intersection(
-                tcx,
-                self.variants.iter().map(|v| v.uninhabited_from(tcx, substs, self.adt_kind())),
-            )
-        }
-    }
-}
-
-impl<'tcx> VariantDef {
-    /// Calculates the forest of `DefId`s from which this variant is visibly uninhabited.
-    pub fn uninhabited_from(
-        &self,
-        tcx: TyCtxt<'tcx>,
-        substs: SubstsRef<'tcx>,
-        adt_kind: AdtKind,
-    ) -> DefIdForest {
-        let is_enum = match adt_kind {
-            // For now, `union`s are never considered uninhabited.
-            // The precise semantics of inhabitedness with respect to unions is currently undecided.
-            AdtKind::Union => return DefIdForest::empty(),
-            AdtKind::Enum => true,
-            AdtKind::Struct => false,
-        };
-        // Non-exhaustive variants from other crates are always considered inhabited.
-        if self.is_field_list_non_exhaustive() && !self.def_id.is_local() {
-            DefIdForest::empty()
-        } else {
-            DefIdForest::union(
-                tcx,
-                self.fields.iter().map(|f| f.uninhabited_from(tcx, substs, is_enum)),
-            )
-        }
-    }
-}
-
-impl<'tcx> FieldDef {
-    /// Calculates the forest of `DefId`s from which this field is visibly uninhabited.
-    fn uninhabited_from(
-        &self,
-        tcx: TyCtxt<'tcx>,
-        substs: SubstsRef<'tcx>,
-        is_enum: bool,
-    ) -> DefIdForest {
-        let data_uninhabitedness = move || self.ty(tcx, substs).uninhabited_from(tcx);
-        // FIXME(canndrew): Currently enum fields are (incorrectly) stored with
-        // `Visibility::Invisible` so we need to override `self.vis` if we're
-        // dealing with an enum.
-        if is_enum {
-            data_uninhabitedness()
-        } else {
-            match self.vis {
-                Visibility::Invisible => DefIdForest::empty(),
-                Visibility::Restricted(from) => {
-                    let forest = DefIdForest::from_id(from);
-                    let iter = Some(forest).into_iter().chain(Some(data_uninhabitedness()));
-                    DefIdForest::intersection(tcx, iter)
-                }
-                Visibility::Public => data_uninhabitedness(),
-            }
-        }
-    }
-}
-
-impl<'tcx> TyS<'tcx> {
-    /// Calculates the forest of `DefId`s from which this type is visibly uninhabited.
-    fn uninhabited_from(&self, tcx: TyCtxt<'tcx>) -> DefIdForest {
-        match self.kind {
-            Adt(def, substs) => def.uninhabited_from(tcx, substs),
-
-            Never => DefIdForest::full(tcx),
-
-            Tuple(ref tys) => {
-                DefIdForest::union(tcx, tys.iter().map(|ty| ty.expect_ty().uninhabited_from(tcx)))
-            }
-
-            Array(ty, len) => match len.try_eval_usize(tcx, ty::ParamEnv::empty()) {
-                // If the array is definitely non-empty, it's uninhabited if
-                // the type of its elements is uninhabited.
-                Some(n) if n != 0 => ty.uninhabited_from(tcx),
-                _ => DefIdForest::empty(),
-            },
-
-            // References to uninitialised memory is valid for any type, including
-            // uninhabited types, in unsafe code, so we treat all references as
-            // inhabited.
-            // The precise semantics of inhabitedness with respect to references is currently
-            // undecided.
-            Ref(..) => DefIdForest::empty(),
-
-            _ => DefIdForest::empty(),
-        }
-    }
-}
diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs
deleted file mode 100644
index 66888cdb552..00000000000
--- a/src/librustc/ty/instance.rs
+++ /dev/null
@@ -1,428 +0,0 @@
-use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
-use crate::middle::lang_items::DropInPlaceFnLangItem;
-use crate::ty::print::{FmtPrinter, Printer};
-use crate::ty::{self, SubstsRef, Ty, TyCtxt, TypeFoldable};
-use rustc_data_structures::AtomicRef;
-use rustc_hir::def::Namespace;
-use rustc_hir::def_id::{CrateNum, DefId};
-use rustc_macros::HashStable;
-
-use std::fmt;
-
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
-#[derive(HashStable, Lift)]
-pub struct Instance<'tcx> {
-    pub def: InstanceDef<'tcx>,
-    pub substs: SubstsRef<'tcx>,
-}
-
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable, HashStable)]
-pub enum InstanceDef<'tcx> {
-    Item(DefId),
-    Intrinsic(DefId),
-
-    /// `<T as Trait>::method` where `method` receives unsizeable `self: Self`.
-    VtableShim(DefId),
-
-    /// `fn()` pointer where the function itself cannot be turned into a pointer.
-    ///
-    /// One example is `<dyn Trait as Trait>::fn`, where the shim contains
-    /// a virtual call, which codegen supports only via a direct call to the
-    /// `<dyn Trait as Trait>::fn` instance (an `InstanceDef::Virtual`).
-    ///
-    /// Another example is functions annotated with `#[track_caller]`, which
-    /// must have their implicit caller location argument populated for a call.
-    /// Because this is a required part of the function's ABI but can't be tracked
-    /// as a property of the function pointer, we use a single "caller location"
-    /// (the definition of the function itself).
-    ReifyShim(DefId),
-
-    /// `<fn() as FnTrait>::call_*`
-    /// `DefId` is `FnTrait::call_*`.
-    FnPtrShim(DefId, Ty<'tcx>),
-
-    /// `<dyn Trait as Trait>::fn`, "direct calls" of which are implicitly
-    /// codegen'd as virtual calls.
-    ///
-    /// NB: if this is reified to a `fn` pointer, a `ReifyShim` is used
-    /// (see `ReifyShim` above for more details on that).
-    Virtual(DefId, usize),
-
-    /// `<[mut closure] as FnOnce>::call_once`
-    ClosureOnceShim {
-        call_once: DefId,
-    },
-
-    /// `core::ptr::drop_in_place::<T>`.
-    /// The `DefId` is for `core::ptr::drop_in_place`.
-    /// The `Option<Ty<'tcx>>` is either `Some(T)`, or `None` for empty drop
-    /// glue.
-    DropGlue(DefId, Option<Ty<'tcx>>),
-
-    ///`<T as Clone>::clone` shim.
-    CloneShim(DefId, Ty<'tcx>),
-}
-
-impl<'tcx> Instance<'tcx> {
-    /// Returns the `Ty` corresponding to this `Instance`,
-    /// with generic substitutions applied and lifetimes erased.
-    ///
-    /// This method can only be called when the 'substs' for this Instance
-    /// are fully monomorphic (no `ty::Param`'s are present).
-    /// This is usually the case (e.g. during codegen).
-    /// However, during constant evaluation, we may want
-    /// to try to resolve a `Instance` using generic parameters
-    /// (e.g. when we are attempting to to do const-propagation).
-    /// In this case, `Instance.ty_env` should be used to provide
-    /// the `ParamEnv` for our generic context.
-    pub fn monomorphic_ty(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
-        let ty = tcx.type_of(self.def.def_id());
-        // There shouldn't be any params - if there are, then
-        // Instance.ty_env should have been used to provide the proper
-        // ParamEnv
-        if self.substs.has_param_types() {
-            bug!("Instance.ty called for type {:?} with params in substs: {:?}", ty, self.substs);
-        }
-        tcx.subst_and_normalize_erasing_regions(self.substs, ty::ParamEnv::reveal_all(), &ty)
-    }
-
-    /// Like `Instance.ty`, but allows a `ParamEnv` to be specified for use during
-    /// normalization. This method is only really useful during constant evaluation,
-    /// where we are dealing with potentially generic types.
-    pub fn ty_env(&self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Ty<'tcx> {
-        let ty = tcx.type_of(self.def.def_id());
-        tcx.subst_and_normalize_erasing_regions(self.substs, param_env, &ty)
-    }
-
-    /// Finds a crate that contains a monomorphization of this instance that
-    /// can be linked to from the local crate. A return value of `None` means
-    /// no upstream crate provides such an exported monomorphization.
-    ///
-    /// This method already takes into account the global `-Zshare-generics`
-    /// setting, always returning `None` if `share-generics` is off.
-    pub fn upstream_monomorphization(&self, tcx: TyCtxt<'tcx>) -> Option<CrateNum> {
-        // If we are not in share generics mode, we don't link to upstream
-        // monomorphizations but always instantiate our own internal versions
-        // instead.
-        if !tcx.sess.opts.share_generics() {
-            return None;
-        }
-
-        // If this is an item that is defined in the local crate, no upstream
-        // crate can know about it/provide a monomorphization.
-        if self.def_id().is_local() {
-            return None;
-        }
-
-        // If this a non-generic instance, it cannot be a shared monomorphization.
-        if self.substs.non_erasable_generics().next().is_none() {
-            return None;
-        }
-
-        match self.def {
-            InstanceDef::Item(def_id) => tcx
-                .upstream_monomorphizations_for(def_id)
-                .and_then(|monos| monos.get(&self.substs).cloned()),
-            InstanceDef::DropGlue(_, Some(_)) => tcx.upstream_drop_glue_for(self.substs),
-            _ => None,
-        }
-    }
-}
-
-impl<'tcx> InstanceDef<'tcx> {
-    #[inline]
-    pub fn def_id(&self) -> DefId {
-        match *self {
-            InstanceDef::Item(def_id)
-            | InstanceDef::VtableShim(def_id)
-            | InstanceDef::ReifyShim(def_id)
-            | InstanceDef::FnPtrShim(def_id, _)
-            | InstanceDef::Virtual(def_id, _)
-            | InstanceDef::Intrinsic(def_id)
-            | InstanceDef::ClosureOnceShim { call_once: def_id }
-            | InstanceDef::DropGlue(def_id, _)
-            | InstanceDef::CloneShim(def_id, _) => def_id,
-        }
-    }
-
-    #[inline]
-    pub fn attrs(&self, tcx: TyCtxt<'tcx>) -> ty::Attributes<'tcx> {
-        tcx.get_attrs(self.def_id())
-    }
-
-    /// Returns `true` if the LLVM version of this instance is unconditionally
-    /// marked with `inline`. This implies that a copy of this instance is
-    /// generated in every codegen unit.
-    /// Note that this is only a hint. See the documentation for
-    /// `generates_cgu_internal_copy` for more information.
-    pub fn requires_inline(&self, tcx: TyCtxt<'tcx>) -> bool {
-        use crate::hir::map::DefPathData;
-        let def_id = match *self {
-            ty::InstanceDef::Item(def_id) => def_id,
-            ty::InstanceDef::DropGlue(_, Some(_)) => return false,
-            _ => return true,
-        };
-        match tcx.def_key(def_id).disambiguated_data.data {
-            DefPathData::Ctor | DefPathData::ClosureExpr => true,
-            _ => false,
-        }
-    }
-
-    /// Returns `true` if the machine code for this instance is instantiated in
-    /// each codegen unit that references it.
-    /// Note that this is only a hint! The compiler can globally decide to *not*
-    /// do this in order to speed up compilation. CGU-internal copies are
-    /// only exist to enable inlining. If inlining is not performed (e.g. at
-    /// `-Copt-level=0`) then the time for generating them is wasted and it's
-    /// better to create a single copy with external linkage.
-    pub fn generates_cgu_internal_copy(&self, tcx: TyCtxt<'tcx>) -> bool {
-        if self.requires_inline(tcx) {
-            return true;
-        }
-        if let ty::InstanceDef::DropGlue(.., Some(ty)) = *self {
-            // Drop glue generally wants to be instantiated at every codegen
-            // unit, but without an #[inline] hint. We should make this
-            // available to normal end-users.
-            if tcx.sess.opts.incremental.is_none() {
-                return true;
-            }
-            // When compiling with incremental, we can generate a *lot* of
-            // codegen units. Including drop glue into all of them has a
-            // considerable compile time cost.
-            //
-            // We include enums without destructors to allow, say, optimizing
-            // drops of `Option::None` before LTO. We also respect the intent of
-            // `#[inline]` on `Drop::drop` implementations.
-            return ty.ty_adt_def().map_or(true, |adt_def| {
-                adt_def.destructor(tcx).map_or(adt_def.is_enum(), |dtor| {
-                    tcx.codegen_fn_attrs(dtor.did).requests_inline()
-                })
-            });
-        }
-        tcx.codegen_fn_attrs(self.def_id()).requests_inline()
-    }
-
-    pub fn requires_caller_location(&self, tcx: TyCtxt<'_>) -> bool {
-        match *self {
-            InstanceDef::Item(def_id) => {
-                tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::TRACK_CALLER)
-            }
-            _ => false,
-        }
-    }
-}
-
-impl<'tcx> fmt::Display for Instance<'tcx> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        ty::tls::with(|tcx| {
-            let substs = tcx.lift(&self.substs).expect("could not lift for printing");
-            FmtPrinter::new(tcx, &mut *f, Namespace::ValueNS)
-                .print_def_path(self.def_id(), substs)?;
-            Ok(())
-        })?;
-
-        match self.def {
-            InstanceDef::Item(_) => Ok(()),
-            InstanceDef::VtableShim(_) => write!(f, " - shim(vtable)"),
-            InstanceDef::ReifyShim(_) => write!(f, " - shim(reify)"),
-            InstanceDef::Intrinsic(_) => write!(f, " - intrinsic"),
-            InstanceDef::Virtual(_, num) => write!(f, " - virtual#{}", num),
-            InstanceDef::FnPtrShim(_, ty) => write!(f, " - shim({:?})", ty),
-            InstanceDef::ClosureOnceShim { .. } => write!(f, " - shim"),
-            InstanceDef::DropGlue(_, ty) => write!(f, " - shim({:?})", ty),
-            InstanceDef::CloneShim(_, ty) => write!(f, " - shim({:?})", ty),
-        }
-    }
-}
-
-impl<'tcx> Instance<'tcx> {
-    pub fn new(def_id: DefId, substs: SubstsRef<'tcx>) -> Instance<'tcx> {
-        assert!(
-            !substs.has_escaping_bound_vars(),
-            "substs of instance {:?} not normalized for codegen: {:?}",
-            def_id,
-            substs
-        );
-        Instance { def: InstanceDef::Item(def_id), substs: substs }
-    }
-
-    pub fn mono(tcx: TyCtxt<'tcx>, def_id: DefId) -> Instance<'tcx> {
-        Instance::new(def_id, tcx.empty_substs_for_def_id(def_id))
-    }
-
-    #[inline]
-    pub fn def_id(&self) -> DefId {
-        self.def.def_id()
-    }
-
-    /// Resolves a `(def_id, substs)` pair to an (optional) instance -- most commonly,
-    /// this is used to find the precise code that will run for a trait method invocation,
-    /// if known.
-    ///
-    /// Returns `None` if we cannot resolve `Instance` to a specific instance.
-    /// For example, in a context like this,
-    ///
-    /// ```
-    /// fn foo<T: Debug>(t: T) { ... }
-    /// ```
-    ///
-    /// trying to resolve `Debug::fmt` applied to `T` will yield `None`, because we do not
-    /// know what code ought to run. (Note that this setting is also affected by the
-    /// `RevealMode` in the parameter environment.)
-    ///
-    /// Presuming that coherence and type-check have succeeded, if this method is invoked
-    /// in a monomorphic context (i.e., like during codegen), then it is guaranteed to return
-    /// `Some`.
-    pub fn resolve(
-        tcx: TyCtxt<'tcx>,
-        param_env: ty::ParamEnv<'tcx>,
-        def_id: DefId,
-        substs: SubstsRef<'tcx>,
-    ) -> Option<Instance<'tcx>> {
-        (*RESOLVE_INSTANCE)(tcx, param_env, def_id, substs)
-    }
-
-    pub fn resolve_for_fn_ptr(
-        tcx: TyCtxt<'tcx>,
-        param_env: ty::ParamEnv<'tcx>,
-        def_id: DefId,
-        substs: SubstsRef<'tcx>,
-    ) -> Option<Instance<'tcx>> {
-        debug!("resolve(def_id={:?}, substs={:?})", def_id, substs);
-        Instance::resolve(tcx, param_env, def_id, substs).map(|mut resolved| {
-            match resolved.def {
-                InstanceDef::Item(def_id) if resolved.def.requires_caller_location(tcx) => {
-                    debug!(" => fn pointer created for function with #[track_caller]");
-                    resolved.def = InstanceDef::ReifyShim(def_id);
-                }
-                InstanceDef::Virtual(def_id, _) => {
-                    debug!(" => fn pointer created for virtual call");
-                    resolved.def = InstanceDef::ReifyShim(def_id);
-                }
-                _ => {}
-            }
-
-            resolved
-        })
-    }
-
-    pub fn resolve_for_vtable(
-        tcx: TyCtxt<'tcx>,
-        param_env: ty::ParamEnv<'tcx>,
-        def_id: DefId,
-        substs: SubstsRef<'tcx>,
-    ) -> Option<Instance<'tcx>> {
-        debug!("resolve(def_id={:?}, substs={:?})", def_id, substs);
-        let fn_sig = tcx.fn_sig(def_id);
-        let is_vtable_shim = fn_sig.inputs().skip_binder().len() > 0
-            && fn_sig.input(0).skip_binder().is_param(0)
-            && tcx.generics_of(def_id).has_self;
-        if is_vtable_shim {
-            debug!(" => associated item with unsizeable self: Self");
-            Some(Instance { def: InstanceDef::VtableShim(def_id), substs })
-        } else {
-            Instance::resolve(tcx, param_env, def_id, substs)
-        }
-    }
-
-    pub fn resolve_closure(
-        tcx: TyCtxt<'tcx>,
-        def_id: DefId,
-        substs: ty::SubstsRef<'tcx>,
-        requested_kind: ty::ClosureKind,
-    ) -> Instance<'tcx> {
-        let actual_kind = substs.as_closure().kind(def_id, tcx);
-
-        match needs_fn_once_adapter_shim(actual_kind, requested_kind) {
-            Ok(true) => Instance::fn_once_adapter_instance(tcx, def_id, substs),
-            _ => Instance::new(def_id, substs),
-        }
-    }
-
-    pub fn resolve_drop_in_place(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ty::Instance<'tcx> {
-        let def_id = tcx.require_lang_item(DropInPlaceFnLangItem, None);
-        let substs = tcx.intern_substs(&[ty.into()]);
-        Instance::resolve(tcx, ty::ParamEnv::reveal_all(), def_id, substs).unwrap()
-    }
-
-    pub fn fn_once_adapter_instance(
-        tcx: TyCtxt<'tcx>,
-        closure_did: DefId,
-        substs: ty::SubstsRef<'tcx>,
-    ) -> Instance<'tcx> {
-        debug!("fn_once_adapter_shim({:?}, {:?})", closure_did, substs);
-        let fn_once = tcx.lang_items().fn_once_trait().unwrap();
-        let call_once = tcx
-            .associated_items(fn_once)
-            .in_definition_order()
-            .find(|it| it.kind == ty::AssocKind::Method)
-            .unwrap()
-            .def_id;
-        let def = ty::InstanceDef::ClosureOnceShim { call_once };
-
-        let self_ty = tcx.mk_closure(closure_did, substs);
-
-        let sig = substs.as_closure().sig(closure_did, tcx);
-        let sig = tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig);
-        assert_eq!(sig.inputs().len(), 1);
-        let substs = tcx.mk_substs_trait(self_ty, &[sig.inputs()[0].into()]);
-
-        debug!("fn_once_adapter_shim: self_ty={:?} sig={:?}", self_ty, sig);
-        Instance { def, substs }
-    }
-
-    pub fn is_vtable_shim(&self) -> bool {
-        if let InstanceDef::VtableShim(..) = self.def { true } else { false }
-    }
-}
-
-fn needs_fn_once_adapter_shim(
-    actual_closure_kind: ty::ClosureKind,
-    trait_closure_kind: ty::ClosureKind,
-) -> Result<bool, ()> {
-    match (actual_closure_kind, trait_closure_kind) {
-        (ty::ClosureKind::Fn, ty::ClosureKind::Fn)
-        | (ty::ClosureKind::FnMut, ty::ClosureKind::FnMut)
-        | (ty::ClosureKind::FnOnce, ty::ClosureKind::FnOnce) => {
-            // No adapter needed.
-            Ok(false)
-        }
-        (ty::ClosureKind::Fn, ty::ClosureKind::FnMut) => {
-            // The closure fn `llfn` is a `fn(&self, ...)`.  We want a
-            // `fn(&mut self, ...)`. In fact, at codegen time, these are
-            // basically the same thing, so we can just return llfn.
-            Ok(false)
-        }
-        (ty::ClosureKind::Fn, ty::ClosureKind::FnOnce)
-        | (ty::ClosureKind::FnMut, ty::ClosureKind::FnOnce) => {
-            // The closure fn `llfn` is a `fn(&self, ...)` or `fn(&mut
-            // self, ...)`.  We want a `fn(self, ...)`. We can produce
-            // this by doing something like:
-            //
-            //     fn call_once(self, ...) { call_mut(&self, ...) }
-            //     fn call_once(mut self, ...) { call_mut(&mut self, ...) }
-            //
-            // These are both the same at codegen time.
-            Ok(true)
-        }
-        (ty::ClosureKind::FnMut, _) | (ty::ClosureKind::FnOnce, _) => Err(()),
-    }
-}
-
-fn resolve_instance_default(
-    _tcx: TyCtxt<'tcx>,
-    _param_env: ty::ParamEnv<'tcx>,
-    _def_id: DefId,
-    _substs: SubstsRef<'tcx>,
-) -> Option<Instance<'tcx>> {
-    unimplemented!()
-}
-
-pub static RESOLVE_INSTANCE: AtomicRef<
-    for<'tcx> fn(
-        TyCtxt<'tcx>,
-        ty::ParamEnv<'tcx>,
-        DefId,
-        SubstsRef<'tcx>,
-    ) -> Option<Instance<'tcx>>,
-> = AtomicRef::new(&(resolve_instance_default as _));
diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs
deleted file mode 100644
index e8bf2eb9a12..00000000000
--- a/src/librustc/ty/layout.rs
+++ /dev/null
@@ -1,2744 +0,0 @@
-use crate::session::{self, DataTypeKind};
-use crate::ty::{self, subst::SubstsRef, ReprOptions, Ty, TyCtxt, TypeFoldable};
-
-use rustc_attr as attr;
-use rustc_span::DUMMY_SP;
-use syntax::ast::{self, Ident, IntTy, UintTy};
-
-use std::cmp;
-use std::fmt;
-use std::i128;
-use std::iter;
-use std::mem;
-use std::ops::Bound;
-
-use crate::ich::StableHashingContext;
-use crate::mir::{GeneratorLayout, GeneratorSavedLocal};
-use crate::ty::subst::Subst;
-use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
-use rustc_hir as hir;
-use rustc_index::bit_set::BitSet;
-use rustc_index::vec::{Idx, IndexVec};
-
-use rustc_target::abi::call::{
-    ArgAbi, ArgAttribute, ArgAttributes, Conv, FnAbi, PassMode, Reg, RegKind,
-};
-pub use rustc_target::abi::*;
-use rustc_target::spec::{abi::Abi as SpecAbi, HasTargetSpec};
-
-pub trait IntegerExt {
-    fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>, signed: bool) -> Ty<'tcx>;
-    fn from_attr<C: HasDataLayout>(cx: &C, ity: attr::IntType) -> Integer;
-    fn repr_discr<'tcx>(
-        tcx: TyCtxt<'tcx>,
-        ty: Ty<'tcx>,
-        repr: &ReprOptions,
-        min: i128,
-        max: i128,
-    ) -> (Integer, bool);
-}
-
-impl IntegerExt for Integer {
-    fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>, signed: bool) -> Ty<'tcx> {
-        match (*self, signed) {
-            (I8, false) => tcx.types.u8,
-            (I16, false) => tcx.types.u16,
-            (I32, false) => tcx.types.u32,
-            (I64, false) => tcx.types.u64,
-            (I128, false) => tcx.types.u128,
-            (I8, true) => tcx.types.i8,
-            (I16, true) => tcx.types.i16,
-            (I32, true) => tcx.types.i32,
-            (I64, true) => tcx.types.i64,
-            (I128, true) => tcx.types.i128,
-        }
-    }
-
-    /// Gets the Integer type from an attr::IntType.
-    fn from_attr<C: HasDataLayout>(cx: &C, ity: attr::IntType) -> Integer {
-        let dl = cx.data_layout();
-
-        match ity {
-            attr::SignedInt(IntTy::I8) | attr::UnsignedInt(UintTy::U8) => I8,
-            attr::SignedInt(IntTy::I16) | attr::UnsignedInt(UintTy::U16) => I16,
-            attr::SignedInt(IntTy::I32) | attr::UnsignedInt(UintTy::U32) => I32,
-            attr::SignedInt(IntTy::I64) | attr::UnsignedInt(UintTy::U64) => I64,
-            attr::SignedInt(IntTy::I128) | attr::UnsignedInt(UintTy::U128) => I128,
-            attr::SignedInt(IntTy::Isize) | attr::UnsignedInt(UintTy::Usize) => {
-                dl.ptr_sized_integer()
-            }
-        }
-    }
-
-    /// Finds the appropriate Integer type and signedness for the given
-    /// signed discriminant range and #[repr] attribute.
-    /// N.B.: u128 values above i128::MAX will be treated as signed, but
-    /// that shouldn't affect anything, other than maybe debuginfo.
-    fn repr_discr<'tcx>(
-        tcx: TyCtxt<'tcx>,
-        ty: Ty<'tcx>,
-        repr: &ReprOptions,
-        min: i128,
-        max: i128,
-    ) -> (Integer, bool) {
-        // Theoretically, negative values could be larger in unsigned representation
-        // than the unsigned representation of the signed minimum. However, if there
-        // are any negative values, the only valid unsigned representation is u128
-        // which can fit all i128 values, so the result remains unaffected.
-        let unsigned_fit = Integer::fit_unsigned(cmp::max(min as u128, max as u128));
-        let signed_fit = cmp::max(Integer::fit_signed(min), Integer::fit_signed(max));
-
-        let mut min_from_extern = None;
-        let min_default = I8;
-
-        if let Some(ity) = repr.int {
-            let discr = Integer::from_attr(&tcx, ity);
-            let fit = if ity.is_signed() { signed_fit } else { unsigned_fit };
-            if discr < fit {
-                bug!(
-                    "Integer::repr_discr: `#[repr]` hint too small for \
-                      discriminant range of enum `{}",
-                    ty
-                )
-            }
-            return (discr, ity.is_signed());
-        }
-
-        if repr.c() {
-            match &tcx.sess.target.target.arch[..] {
-                // WARNING: the ARM EABI has two variants; the one corresponding
-                // to `at_least == I32` appears to be used on Linux and NetBSD,
-                // but some systems may use the variant corresponding to no
-                // lower bound. However, we don't run on those yet...?
-                "arm" => min_from_extern = Some(I32),
-                _ => min_from_extern = Some(I32),
-            }
-        }
-
-        let at_least = min_from_extern.unwrap_or(min_default);
-
-        // If there are no negative values, we can use the unsigned fit.
-        if min >= 0 {
-            (cmp::max(unsigned_fit, at_least), false)
-        } else {
-            (cmp::max(signed_fit, at_least), true)
-        }
-    }
-}
-
-pub trait PrimitiveExt {
-    fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx>;
-    fn to_int_ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx>;
-}
-
-impl PrimitiveExt for Primitive {
-    fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
-        match *self {
-            Int(i, signed) => i.to_ty(tcx, signed),
-            F32 => tcx.types.f32,
-            F64 => tcx.types.f64,
-            Pointer => tcx.mk_mut_ptr(tcx.mk_unit()),
-        }
-    }
-
-    /// Return an *integer* type matching this primitive.
-    /// Useful in particular when dealing with enum discriminants.
-    fn to_int_ty(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
-        match *self {
-            Int(i, signed) => i.to_ty(tcx, signed),
-            Pointer => tcx.types.usize,
-            F32 | F64 => bug!("floats do not have an int type"),
-        }
-    }
-}
-
-/// The first half of a fat pointer.
-///
-/// - For a trait object, this is the address of the box.
-/// - For a slice, this is the base address.
-pub const FAT_PTR_ADDR: usize = 0;
-
-/// The second half of a fat pointer.
-///
-/// - For a trait object, this is the address of the vtable.
-/// - For a slice, this is the length.
-pub const FAT_PTR_EXTRA: usize = 1;
-
-#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
-pub enum LayoutError<'tcx> {
-    Unknown(Ty<'tcx>),
-    SizeOverflow(Ty<'tcx>),
-}
-
-impl<'tcx> fmt::Display for LayoutError<'tcx> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match *self {
-            LayoutError::Unknown(ty) => write!(f, "the type `{:?}` has an unknown layout", ty),
-            LayoutError::SizeOverflow(ty) => {
-                write!(f, "the type `{:?}` is too big for the current architecture", ty)
-            }
-        }
-    }
-}
-
-fn layout_raw<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>,
-) -> Result<&'tcx LayoutDetails, LayoutError<'tcx>> {
-    ty::tls::with_related_context(tcx, move |icx| {
-        let rec_limit = *tcx.sess.recursion_limit.get();
-        let (param_env, ty) = query.into_parts();
-
-        if icx.layout_depth > rec_limit {
-            tcx.sess.fatal(&format!("overflow representing the type `{}`", ty));
-        }
-
-        // Update the ImplicitCtxt to increase the layout_depth
-        let icx = ty::tls::ImplicitCtxt { layout_depth: icx.layout_depth + 1, ..icx.clone() };
-
-        ty::tls::enter_context(&icx, |_| {
-            let cx = LayoutCx { tcx, param_env };
-            let layout = cx.layout_raw_uncached(ty);
-            // Type-level uninhabitedness should always imply ABI uninhabitedness.
-            if let Ok(layout) = layout {
-                if ty.conservative_is_privately_uninhabited(tcx) {
-                    assert!(layout.abi.is_uninhabited());
-                }
-            }
-            layout
-        })
-    })
-}
-
-pub fn provide(providers: &mut ty::query::Providers<'_>) {
-    *providers = ty::query::Providers { layout_raw, ..*providers };
-}
-
-pub struct LayoutCx<'tcx, C> {
-    pub tcx: C,
-    pub param_env: ty::ParamEnv<'tcx>,
-}
-
-#[derive(Copy, Clone, Debug)]
-enum StructKind {
-    /// A tuple, closure, or univariant which cannot be coerced to unsized.
-    AlwaysSized,
-    /// A univariant, the last field of which may be coerced to unsized.
-    MaybeUnsized,
-    /// A univariant, but with a prefix of an arbitrary size & alignment (e.g., enum tag).
-    Prefixed(Size, Align),
-}
-
-// Invert a bijective mapping, i.e. `invert(map)[y] = x` if `map[x] = y`.
-// This is used to go between `memory_index` (source field order to memory order)
-// and `inverse_memory_index` (memory order to source field order).
-// See also `FieldPlacement::Arbitrary::memory_index` for more details.
-// FIXME(eddyb) build a better abstraction for permutations, if possible.
-fn invert_mapping(map: &[u32]) -> Vec<u32> {
-    let mut inverse = vec![0; map.len()];
-    for i in 0..map.len() {
-        inverse[map[i] as usize] = i as u32;
-    }
-    inverse
-}
-
-impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
-    fn scalar_pair(&self, a: Scalar, b: Scalar) -> LayoutDetails {
-        let dl = self.data_layout();
-        let b_align = b.value.align(dl);
-        let align = a.value.align(dl).max(b_align).max(dl.aggregate_align);
-        let b_offset = a.value.size(dl).align_to(b_align.abi);
-        let size = (b_offset + b.value.size(dl)).align_to(align.abi);
-
-        // HACK(nox): We iter on `b` and then `a` because `max_by_key`
-        // returns the last maximum.
-        let largest_niche = Niche::from_scalar(dl, b_offset, b.clone())
-            .into_iter()
-            .chain(Niche::from_scalar(dl, Size::ZERO, a.clone()))
-            .max_by_key(|niche| niche.available(dl));
-
-        LayoutDetails {
-            variants: Variants::Single { index: VariantIdx::new(0) },
-            fields: FieldPlacement::Arbitrary {
-                offsets: vec![Size::ZERO, b_offset],
-                memory_index: vec![0, 1],
-            },
-            abi: Abi::ScalarPair(a, b),
-            largest_niche,
-            align,
-            size,
-        }
-    }
-
-    fn univariant_uninterned(
-        &self,
-        ty: Ty<'tcx>,
-        fields: &[TyLayout<'_>],
-        repr: &ReprOptions,
-        kind: StructKind,
-    ) -> Result<LayoutDetails, LayoutError<'tcx>> {
-        let dl = self.data_layout();
-        let pack = repr.pack;
-        if pack.is_some() && repr.align.is_some() {
-            bug!("struct cannot be packed and aligned");
-        }
-
-        let mut align = if pack.is_some() { dl.i8_align } else { dl.aggregate_align };
-
-        let mut sized = true;
-        let mut offsets = vec![Size::ZERO; fields.len()];
-        let mut inverse_memory_index: Vec<u32> = (0..fields.len() as u32).collect();
-
-        let mut optimize = !repr.inhibit_struct_field_reordering_opt();
-        if let StructKind::Prefixed(_, align) = kind {
-            optimize &= align.bytes() == 1;
-        }
-
-        if optimize {
-            let end =
-                if let StructKind::MaybeUnsized = kind { fields.len() - 1 } else { fields.len() };
-            let optimizing = &mut inverse_memory_index[..end];
-            let field_align = |f: &TyLayout<'_>| {
-                if let Some(pack) = pack { f.align.abi.min(pack) } else { f.align.abi }
-            };
-            match kind {
-                StructKind::AlwaysSized | StructKind::MaybeUnsized => {
-                    optimizing.sort_by_key(|&x| {
-                        // Place ZSTs first to avoid "interesting offsets",
-                        // especially with only one or two non-ZST fields.
-                        let f = &fields[x as usize];
-                        (!f.is_zst(), cmp::Reverse(field_align(f)))
-                    });
-                }
-                StructKind::Prefixed(..) => {
-                    optimizing.sort_by_key(|&x| field_align(&fields[x as usize]));
-                }
-            }
-        }
-
-        // inverse_memory_index holds field indices by increasing memory offset.
-        // That is, if field 5 has offset 0, the first element of inverse_memory_index is 5.
-        // We now write field offsets to the corresponding offset slot;
-        // field 5 with offset 0 puts 0 in offsets[5].
-        // At the bottom of this function, we invert `inverse_memory_index` to
-        // produce `memory_index` (see `invert_mapping`).
-
-        let mut offset = Size::ZERO;
-        let mut largest_niche = None;
-        let mut largest_niche_available = 0;
-
-        if let StructKind::Prefixed(prefix_size, prefix_align) = kind {
-            let prefix_align =
-                if let Some(pack) = pack { prefix_align.min(pack) } else { prefix_align };
-            align = align.max(AbiAndPrefAlign::new(prefix_align));
-            offset = prefix_size.align_to(prefix_align);
-        }
-
-        for &i in &inverse_memory_index {
-            let field = fields[i as usize];
-            if !sized {
-                bug!("univariant: field #{} of `{}` comes after unsized field", offsets.len(), ty);
-            }
-
-            if field.is_unsized() {
-                sized = false;
-            }
-
-            // Invariant: offset < dl.obj_size_bound() <= 1<<61
-            let field_align = if let Some(pack) = pack {
-                field.align.min(AbiAndPrefAlign::new(pack))
-            } else {
-                field.align
-            };
-            offset = offset.align_to(field_align.abi);
-            align = align.max(field_align);
-
-            debug!("univariant offset: {:?} field: {:#?}", offset, field);
-            offsets[i as usize] = offset;
-
-            if !repr.hide_niche() {
-                if let Some(mut niche) = field.largest_niche.clone() {
-                    let available = niche.available(dl);
-                    if available > largest_niche_available {
-                        largest_niche_available = available;
-                        niche.offset += offset;
-                        largest_niche = Some(niche);
-                    }
-                }
-            }
-
-            offset = offset.checked_add(field.size, dl).ok_or(LayoutError::SizeOverflow(ty))?;
-        }
-
-        if let Some(repr_align) = repr.align {
-            align = align.max(AbiAndPrefAlign::new(repr_align));
-        }
-
-        debug!("univariant min_size: {:?}", offset);
-        let min_size = offset;
-
-        // As stated above, inverse_memory_index holds field indices by increasing offset.
-        // This makes it an already-sorted view of the offsets vec.
-        // To invert it, consider:
-        // If field 5 has offset 0, offsets[0] is 5, and memory_index[5] should be 0.
-        // Field 5 would be the first element, so memory_index is i:
-        // Note: if we didn't optimize, it's already right.
-
-        let memory_index;
-        if optimize {
-            memory_index = invert_mapping(&inverse_memory_index);
-        } else {
-            memory_index = inverse_memory_index;
-        }
-
-        let size = min_size.align_to(align.abi);
-        let mut abi = Abi::Aggregate { sized };
-
-        // Unpack newtype ABIs and find scalar pairs.
-        if sized && size.bytes() > 0 {
-            // All other fields must be ZSTs, and we need them to all start at 0.
-            let mut zst_offsets = offsets.iter().enumerate().filter(|&(i, _)| fields[i].is_zst());
-            if zst_offsets.all(|(_, o)| o.bytes() == 0) {
-                let mut non_zst_fields = fields.iter().enumerate().filter(|&(_, f)| !f.is_zst());
-
-                match (non_zst_fields.next(), non_zst_fields.next(), non_zst_fields.next()) {
-                    // We have exactly one non-ZST field.
-                    (Some((i, field)), None, None) => {
-                        // Field fills the struct and it has a scalar or scalar pair ABI.
-                        if offsets[i].bytes() == 0
-                            && align.abi == field.align.abi
-                            && size == field.size
-                        {
-                            match field.abi {
-                                // For plain scalars, or vectors of them, we can't unpack
-                                // newtypes for `#[repr(C)]`, as that affects C ABIs.
-                                Abi::Scalar(_) | Abi::Vector { .. } if optimize => {
-                                    abi = field.abi.clone();
-                                }
-                                // But scalar pairs are Rust-specific and get
-                                // treated as aggregates by C ABIs anyway.
-                                Abi::ScalarPair(..) => {
-                                    abi = field.abi.clone();
-                                }
-                                _ => {}
-                            }
-                        }
-                    }
-
-                    // Two non-ZST fields, and they're both scalars.
-                    (
-                        Some((
-                            i,
-                            &TyLayout {
-                                details: &LayoutDetails { abi: Abi::Scalar(ref a), .. },
-                                ..
-                            },
-                        )),
-                        Some((
-                            j,
-                            &TyLayout {
-                                details: &LayoutDetails { abi: Abi::Scalar(ref b), .. },
-                                ..
-                            },
-                        )),
-                        None,
-                    ) => {
-                        // Order by the memory placement, not source order.
-                        let ((i, a), (j, b)) = if offsets[i] < offsets[j] {
-                            ((i, a), (j, b))
-                        } else {
-                            ((j, b), (i, a))
-                        };
-                        let pair = self.scalar_pair(a.clone(), b.clone());
-                        let pair_offsets = match pair.fields {
-                            FieldPlacement::Arbitrary { ref offsets, ref memory_index } => {
-                                assert_eq!(memory_index, &[0, 1]);
-                                offsets
-                            }
-                            _ => bug!(),
-                        };
-                        if offsets[i] == pair_offsets[0]
-                            && offsets[j] == pair_offsets[1]
-                            && align == pair.align
-                            && size == pair.size
-                        {
-                            // We can use `ScalarPair` only when it matches our
-                            // already computed layout (including `#[repr(C)]`).
-                            abi = pair.abi;
-                        }
-                    }
-
-                    _ => {}
-                }
-            }
-        }
-
-        if sized && fields.iter().any(|f| f.abi.is_uninhabited()) {
-            abi = Abi::Uninhabited;
-        }
-
-        Ok(LayoutDetails {
-            variants: Variants::Single { index: VariantIdx::new(0) },
-            fields: FieldPlacement::Arbitrary { offsets, memory_index },
-            abi,
-            largest_niche,
-            align,
-            size,
-        })
-    }
-
-    fn layout_raw_uncached(&self, ty: Ty<'tcx>) -> Result<&'tcx LayoutDetails, LayoutError<'tcx>> {
-        let tcx = self.tcx;
-        let param_env = self.param_env;
-        let dl = self.data_layout();
-        let scalar_unit = |value: Primitive| {
-            let bits = value.size(dl).bits();
-            assert!(bits <= 128);
-            Scalar { value, valid_range: 0..=(!0 >> (128 - bits)) }
-        };
-        let scalar =
-            |value: Primitive| tcx.intern_layout(LayoutDetails::scalar(self, scalar_unit(value)));
-
-        let univariant = |fields: &[TyLayout<'_>], repr: &ReprOptions, kind| {
-            Ok(tcx.intern_layout(self.univariant_uninterned(ty, fields, repr, kind)?))
-        };
-        debug_assert!(!ty.has_infer_types());
-
-        Ok(match ty.kind {
-            // Basic scalars.
-            ty::Bool => tcx.intern_layout(LayoutDetails::scalar(
-                self,
-                Scalar { value: Int(I8, false), valid_range: 0..=1 },
-            )),
-            ty::Char => tcx.intern_layout(LayoutDetails::scalar(
-                self,
-                Scalar { value: Int(I32, false), valid_range: 0..=0x10FFFF },
-            )),
-            ty::Int(ity) => scalar(Int(Integer::from_attr(dl, attr::SignedInt(ity)), true)),
-            ty::Uint(ity) => scalar(Int(Integer::from_attr(dl, attr::UnsignedInt(ity)), false)),
-            ty::Float(fty) => scalar(match fty {
-                ast::FloatTy::F32 => F32,
-                ast::FloatTy::F64 => F64,
-            }),
-            ty::FnPtr(_) => {
-                let mut ptr = scalar_unit(Pointer);
-                ptr.valid_range = 1..=*ptr.valid_range.end();
-                tcx.intern_layout(LayoutDetails::scalar(self, ptr))
-            }
-
-            // The never type.
-            ty::Never => tcx.intern_layout(LayoutDetails {
-                variants: Variants::Single { index: VariantIdx::new(0) },
-                fields: FieldPlacement::Union(0),
-                abi: Abi::Uninhabited,
-                largest_niche: None,
-                align: dl.i8_align,
-                size: Size::ZERO,
-            }),
-
-            // Potentially-fat pointers.
-            ty::Ref(_, pointee, _) | ty::RawPtr(ty::TypeAndMut { ty: pointee, .. }) => {
-                let mut data_ptr = scalar_unit(Pointer);
-                if !ty.is_unsafe_ptr() {
-                    data_ptr.valid_range = 1..=*data_ptr.valid_range.end();
-                }
-
-                let pointee = tcx.normalize_erasing_regions(param_env, pointee);
-                if pointee.is_sized(tcx.at(DUMMY_SP), param_env) {
-                    return Ok(tcx.intern_layout(LayoutDetails::scalar(self, data_ptr)));
-                }
-
-                let unsized_part = tcx.struct_tail_erasing_lifetimes(pointee, param_env);
-                let metadata = match unsized_part.kind {
-                    ty::Foreign(..) => {
-                        return Ok(tcx.intern_layout(LayoutDetails::scalar(self, data_ptr)));
-                    }
-                    ty::Slice(_) | ty::Str => scalar_unit(Int(dl.ptr_sized_integer(), false)),
-                    ty::Dynamic(..) => {
-                        let mut vtable = scalar_unit(Pointer);
-                        vtable.valid_range = 1..=*vtable.valid_range.end();
-                        vtable
-                    }
-                    _ => return Err(LayoutError::Unknown(unsized_part)),
-                };
-
-                // Effectively a (ptr, meta) tuple.
-                tcx.intern_layout(self.scalar_pair(data_ptr, metadata))
-            }
-
-            // Arrays and slices.
-            ty::Array(element, mut count) => {
-                if count.has_projections() {
-                    count = tcx.normalize_erasing_regions(param_env, count);
-                    if count.has_projections() {
-                        return Err(LayoutError::Unknown(ty));
-                    }
-                }
-
-                let count = count.try_eval_usize(tcx, param_env).ok_or(LayoutError::Unknown(ty))?;
-                let element = self.layout_of(element)?;
-                let size =
-                    element.size.checked_mul(count, dl).ok_or(LayoutError::SizeOverflow(ty))?;
-
-                let abi = if count != 0 && ty.conservative_is_privately_uninhabited(tcx) {
-                    Abi::Uninhabited
-                } else {
-                    Abi::Aggregate { sized: true }
-                };
-
-                let largest_niche = if count != 0 { element.largest_niche.clone() } else { None };
-
-                tcx.intern_layout(LayoutDetails {
-                    variants: Variants::Single { index: VariantIdx::new(0) },
-                    fields: FieldPlacement::Array { stride: element.size, count },
-                    abi,
-                    largest_niche,
-                    align: element.align,
-                    size,
-                })
-            }
-            ty::Slice(element) => {
-                let element = self.layout_of(element)?;
-                tcx.intern_layout(LayoutDetails {
-                    variants: Variants::Single { index: VariantIdx::new(0) },
-                    fields: FieldPlacement::Array { stride: element.size, count: 0 },
-                    abi: Abi::Aggregate { sized: false },
-                    largest_niche: None,
-                    align: element.align,
-                    size: Size::ZERO,
-                })
-            }
-            ty::Str => tcx.intern_layout(LayoutDetails {
-                variants: Variants::Single { index: VariantIdx::new(0) },
-                fields: FieldPlacement::Array { stride: Size::from_bytes(1), count: 0 },
-                abi: Abi::Aggregate { sized: false },
-                largest_niche: None,
-                align: dl.i8_align,
-                size: Size::ZERO,
-            }),
-
-            // Odd unit types.
-            ty::FnDef(..) => univariant(&[], &ReprOptions::default(), StructKind::AlwaysSized)?,
-            ty::Dynamic(..) | ty::Foreign(..) => {
-                let mut unit = self.univariant_uninterned(
-                    ty,
-                    &[],
-                    &ReprOptions::default(),
-                    StructKind::AlwaysSized,
-                )?;
-                match unit.abi {
-                    Abi::Aggregate { ref mut sized } => *sized = false,
-                    _ => bug!(),
-                }
-                tcx.intern_layout(unit)
-            }
-
-            ty::Generator(def_id, substs, _) => self.generator_layout(ty, def_id, substs)?,
-
-            ty::Closure(def_id, ref substs) => {
-                let tys = substs.as_closure().upvar_tys(def_id, tcx);
-                univariant(
-                    &tys.map(|ty| self.layout_of(ty)).collect::<Result<Vec<_>, _>>()?,
-                    &ReprOptions::default(),
-                    StructKind::AlwaysSized,
-                )?
-            }
-
-            ty::Tuple(tys) => {
-                let kind =
-                    if tys.len() == 0 { StructKind::AlwaysSized } else { StructKind::MaybeUnsized };
-
-                univariant(
-                    &tys.iter()
-                        .map(|k| self.layout_of(k.expect_ty()))
-                        .collect::<Result<Vec<_>, _>>()?,
-                    &ReprOptions::default(),
-                    kind,
-                )?
-            }
-
-            // SIMD vector types.
-            ty::Adt(def, ..) if def.repr.simd() => {
-                let element = self.layout_of(ty.simd_type(tcx))?;
-                let count = ty.simd_size(tcx);
-                assert!(count > 0);
-                let scalar = match element.abi {
-                    Abi::Scalar(ref scalar) => scalar.clone(),
-                    _ => {
-                        tcx.sess.fatal(&format!(
-                            "monomorphising SIMD type `{}` with \
-                                                 a non-machine element type `{}`",
-                            ty, element.ty
-                        ));
-                    }
-                };
-                let size =
-                    element.size.checked_mul(count, dl).ok_or(LayoutError::SizeOverflow(ty))?;
-                let align = dl.vector_align(size);
-                let size = size.align_to(align.abi);
-
-                tcx.intern_layout(LayoutDetails {
-                    variants: Variants::Single { index: VariantIdx::new(0) },
-                    fields: FieldPlacement::Array { stride: element.size, count },
-                    abi: Abi::Vector { element: scalar, count },
-                    largest_niche: element.largest_niche.clone(),
-                    size,
-                    align,
-                })
-            }
-
-            // ADTs.
-            ty::Adt(def, substs) => {
-                // Cache the field layouts.
-                let variants = def
-                    .variants
-                    .iter()
-                    .map(|v| {
-                        v.fields
-                            .iter()
-                            .map(|field| self.layout_of(field.ty(tcx, substs)))
-                            .collect::<Result<Vec<_>, _>>()
-                    })
-                    .collect::<Result<IndexVec<VariantIdx, _>, _>>()?;
-
-                if def.is_union() {
-                    if def.repr.pack.is_some() && def.repr.align.is_some() {
-                        bug!("union cannot be packed and aligned");
-                    }
-
-                    let mut align =
-                        if def.repr.pack.is_some() { dl.i8_align } else { dl.aggregate_align };
-
-                    if let Some(repr_align) = def.repr.align {
-                        align = align.max(AbiAndPrefAlign::new(repr_align));
-                    }
-
-                    let optimize = !def.repr.inhibit_union_abi_opt();
-                    let mut size = Size::ZERO;
-                    let mut abi = Abi::Aggregate { sized: true };
-                    let index = VariantIdx::new(0);
-                    for field in &variants[index] {
-                        assert!(!field.is_unsized());
-                        align = align.max(field.align);
-
-                        // If all non-ZST fields have the same ABI, forward this ABI
-                        if optimize && !field.is_zst() {
-                            // Normalize scalar_unit to the maximal valid range
-                            let field_abi = match &field.abi {
-                                Abi::Scalar(x) => Abi::Scalar(scalar_unit(x.value)),
-                                Abi::ScalarPair(x, y) => {
-                                    Abi::ScalarPair(scalar_unit(x.value), scalar_unit(y.value))
-                                }
-                                Abi::Vector { element: x, count } => {
-                                    Abi::Vector { element: scalar_unit(x.value), count: *count }
-                                }
-                                Abi::Uninhabited | Abi::Aggregate { .. } => {
-                                    Abi::Aggregate { sized: true }
-                                }
-                            };
-
-                            if size == Size::ZERO {
-                                // first non ZST: initialize 'abi'
-                                abi = field_abi;
-                            } else if abi != field_abi {
-                                // different fields have different ABI: reset to Aggregate
-                                abi = Abi::Aggregate { sized: true };
-                            }
-                        }
-
-                        size = cmp::max(size, field.size);
-                    }
-
-                    if let Some(pack) = def.repr.pack {
-                        align = align.min(AbiAndPrefAlign::new(pack));
-                    }
-
-                    return Ok(tcx.intern_layout(LayoutDetails {
-                        variants: Variants::Single { index },
-                        fields: FieldPlacement::Union(variants[index].len()),
-                        abi,
-                        largest_niche: None,
-                        align,
-                        size: size.align_to(align.abi),
-                    }));
-                }
-
-                // A variant is absent if it's uninhabited and only has ZST fields.
-                // Present uninhabited variants only require space for their fields,
-                // but *not* an encoding of the discriminant (e.g., a tag value).
-                // See issue #49298 for more details on the need to leave space
-                // for non-ZST uninhabited data (mostly partial initialization).
-                let absent = |fields: &[TyLayout<'_>]| {
-                    let uninhabited = fields.iter().any(|f| f.abi.is_uninhabited());
-                    let is_zst = fields.iter().all(|f| f.is_zst());
-                    uninhabited && is_zst
-                };
-                let (present_first, present_second) = {
-                    let mut present_variants = variants
-                        .iter_enumerated()
-                        .filter_map(|(i, v)| if absent(v) { None } else { Some(i) });
-                    (present_variants.next(), present_variants.next())
-                };
-                let present_first = match present_first {
-                    present_first @ Some(_) => present_first,
-                    // Uninhabited because it has no variants, or only absent ones.
-                    None if def.is_enum() => return tcx.layout_raw(param_env.and(tcx.types.never)),
-                    // if it's a struct, still compute a layout so that we can still compute the
-                    // field offsets
-                    None => Some(VariantIdx::new(0)),
-                };
-
-                let is_struct = !def.is_enum() ||
-                    // Only one variant is present.
-                    (present_second.is_none() &&
-                    // Representation optimizations are allowed.
-                    !def.repr.inhibit_enum_layout_opt());
-                if is_struct {
-                    // Struct, or univariant enum equivalent to a struct.
-                    // (Typechecking will reject discriminant-sizing attrs.)
-
-                    let v = present_first.unwrap();
-                    let kind = if def.is_enum() || variants[v].len() == 0 {
-                        StructKind::AlwaysSized
-                    } else {
-                        let param_env = tcx.param_env(def.did);
-                        let last_field = def.variants[v].fields.last().unwrap();
-                        let always_sized =
-                            tcx.type_of(last_field.did).is_sized(tcx.at(DUMMY_SP), param_env);
-                        if !always_sized {
-                            StructKind::MaybeUnsized
-                        } else {
-                            StructKind::AlwaysSized
-                        }
-                    };
-
-                    let mut st = self.univariant_uninterned(ty, &variants[v], &def.repr, kind)?;
-                    st.variants = Variants::Single { index: v };
-                    let (start, end) = self.tcx.layout_scalar_valid_range(def.did);
-                    match st.abi {
-                        Abi::Scalar(ref mut scalar) | Abi::ScalarPair(ref mut scalar, _) => {
-                            // the asserts ensure that we are not using the
-                            // `#[rustc_layout_scalar_valid_range(n)]`
-                            // attribute to widen the range of anything as that would probably
-                            // result in UB somewhere
-                            // FIXME(eddyb) the asserts are probably not needed,
-                            // as larger validity ranges would result in missed
-                            // optimizations, *not* wrongly assuming the inner
-                            // value is valid. e.g. unions enlarge validity ranges,
-                            // because the values may be uninitialized.
-                            if let Bound::Included(start) = start {
-                                // FIXME(eddyb) this might be incorrect - it doesn't
-                                // account for wrap-around (end < start) ranges.
-                                assert!(*scalar.valid_range.start() <= start);
-                                scalar.valid_range = start..=*scalar.valid_range.end();
-                            }
-                            if let Bound::Included(end) = end {
-                                // FIXME(eddyb) this might be incorrect - it doesn't
-                                // account for wrap-around (end < start) ranges.
-                                assert!(*scalar.valid_range.end() >= end);
-                                scalar.valid_range = *scalar.valid_range.start()..=end;
-                            }
-
-                            // Update `largest_niche` if we have introduced a larger niche.
-                            let niche = if def.repr.hide_niche() {
-                                None
-                            } else {
-                                Niche::from_scalar(dl, Size::ZERO, scalar.clone())
-                            };
-                            if let Some(niche) = niche {
-                                match &st.largest_niche {
-                                    Some(largest_niche) => {
-                                        // Replace the existing niche even if they're equal,
-                                        // because this one is at a lower offset.
-                                        if largest_niche.available(dl) <= niche.available(dl) {
-                                            st.largest_niche = Some(niche);
-                                        }
-                                    }
-                                    None => st.largest_niche = Some(niche),
-                                }
-                            }
-                        }
-                        _ => assert!(
-                            start == Bound::Unbounded && end == Bound::Unbounded,
-                            "nonscalar layout for layout_scalar_valid_range type {:?}: {:#?}",
-                            def,
-                            st,
-                        ),
-                    }
-
-                    return Ok(tcx.intern_layout(st));
-                }
-
-                // At this point, we have handled all unions and
-                // structs. (We have also handled univariant enums
-                // that allow representation optimization.)
-                assert!(def.is_enum());
-
-                // The current code for niche-filling relies on variant indices
-                // instead of actual discriminants, so dataful enums with
-                // explicit discriminants (RFC #2363) would misbehave.
-                let no_explicit_discriminants = def
-                    .variants
-                    .iter_enumerated()
-                    .all(|(i, v)| v.discr == ty::VariantDiscr::Relative(i.as_u32()));
-
-                // Niche-filling enum optimization.
-                if !def.repr.inhibit_enum_layout_opt() && no_explicit_discriminants {
-                    let mut dataful_variant = None;
-                    let mut niche_variants = VariantIdx::MAX..=VariantIdx::new(0);
-
-                    // Find one non-ZST variant.
-                    'variants: for (v, fields) in variants.iter_enumerated() {
-                        if absent(fields) {
-                            continue 'variants;
-                        }
-                        for f in fields {
-                            if !f.is_zst() {
-                                if dataful_variant.is_none() {
-                                    dataful_variant = Some(v);
-                                    continue 'variants;
-                                } else {
-                                    dataful_variant = None;
-                                    break 'variants;
-                                }
-                            }
-                        }
-                        niche_variants = *niche_variants.start().min(&v)..=v;
-                    }
-
-                    if niche_variants.start() > niche_variants.end() {
-                        dataful_variant = None;
-                    }
-
-                    if let Some(i) = dataful_variant {
-                        let count = (niche_variants.end().as_u32()
-                            - niche_variants.start().as_u32()
-                            + 1) as u128;
-                        // FIXME(#62691) use the largest niche across all fields,
-                        // not just the first one.
-                        for (field_index, &field) in variants[i].iter().enumerate() {
-                            let niche = match &field.largest_niche {
-                                Some(niche) => niche,
-                                _ => continue,
-                            };
-                            let (niche_start, niche_scalar) = match niche.reserve(self, count) {
-                                Some(pair) => pair,
-                                None => continue,
-                            };
-
-                            let mut align = dl.aggregate_align;
-                            let st = variants
-                                .iter_enumerated()
-                                .map(|(j, v)| {
-                                    let mut st = self.univariant_uninterned(
-                                        ty,
-                                        v,
-                                        &def.repr,
-                                        StructKind::AlwaysSized,
-                                    )?;
-                                    st.variants = Variants::Single { index: j };
-
-                                    align = align.max(st.align);
-
-                                    Ok(st)
-                                })
-                                .collect::<Result<IndexVec<VariantIdx, _>, _>>()?;
-
-                            let offset = st[i].fields.offset(field_index) + niche.offset;
-                            let size = st[i].size;
-
-                            let mut abi = match st[i].abi {
-                                Abi::Scalar(_) => Abi::Scalar(niche_scalar.clone()),
-                                Abi::ScalarPair(ref first, ref second) => {
-                                    // We need to use scalar_unit to reset the
-                                    // valid range to the maximal one for that
-                                    // primitive, because only the niche is
-                                    // guaranteed to be initialised, not the
-                                    // other primitive.
-                                    if offset.bytes() == 0 {
-                                        Abi::ScalarPair(
-                                            niche_scalar.clone(),
-                                            scalar_unit(second.value),
-                                        )
-                                    } else {
-                                        Abi::ScalarPair(
-                                            scalar_unit(first.value),
-                                            niche_scalar.clone(),
-                                        )
-                                    }
-                                }
-                                _ => Abi::Aggregate { sized: true },
-                            };
-
-                            if st.iter().all(|v| v.abi.is_uninhabited()) {
-                                abi = Abi::Uninhabited;
-                            }
-
-                            let largest_niche =
-                                Niche::from_scalar(dl, offset, niche_scalar.clone());
-
-                            return Ok(tcx.intern_layout(LayoutDetails {
-                                variants: Variants::Multiple {
-                                    discr: niche_scalar,
-                                    discr_kind: DiscriminantKind::Niche {
-                                        dataful_variant: i,
-                                        niche_variants,
-                                        niche_start,
-                                    },
-                                    discr_index: 0,
-                                    variants: st,
-                                },
-                                fields: FieldPlacement::Arbitrary {
-                                    offsets: vec![offset],
-                                    memory_index: vec![0],
-                                },
-                                abi,
-                                largest_niche,
-                                size,
-                                align,
-                            }));
-                        }
-                    }
-                }
-
-                let (mut min, mut max) = (i128::max_value(), i128::min_value());
-                let discr_type = def.repr.discr_type();
-                let bits = Integer::from_attr(self, discr_type).size().bits();
-                for (i, discr) in def.discriminants(tcx) {
-                    if variants[i].iter().any(|f| f.abi.is_uninhabited()) {
-                        continue;
-                    }
-                    let mut x = discr.val as i128;
-                    if discr_type.is_signed() {
-                        // sign extend the raw representation to be an i128
-                        x = (x << (128 - bits)) >> (128 - bits);
-                    }
-                    if x < min {
-                        min = x;
-                    }
-                    if x > max {
-                        max = x;
-                    }
-                }
-                // We might have no inhabited variants, so pretend there's at least one.
-                if (min, max) == (i128::max_value(), i128::min_value()) {
-                    min = 0;
-                    max = 0;
-                }
-                assert!(min <= max, "discriminant range is {}...{}", min, max);
-                let (min_ity, signed) = Integer::repr_discr(tcx, ty, &def.repr, min, max);
-
-                let mut align = dl.aggregate_align;
-                let mut size = Size::ZERO;
-
-                // We're interested in the smallest alignment, so start large.
-                let mut start_align = Align::from_bytes(256).unwrap();
-                assert_eq!(Integer::for_align(dl, start_align), None);
-
-                // repr(C) on an enum tells us to make a (tag, union) layout,
-                // so we need to grow the prefix alignment to be at least
-                // the alignment of the union. (This value is used both for
-                // determining the alignment of the overall enum, and the
-                // determining the alignment of the payload after the tag.)
-                let mut prefix_align = min_ity.align(dl).abi;
-                if def.repr.c() {
-                    for fields in &variants {
-                        for field in fields {
-                            prefix_align = prefix_align.max(field.align.abi);
-                        }
-                    }
-                }
-
-                // Create the set of structs that represent each variant.
-                let mut layout_variants = variants
-                    .iter_enumerated()
-                    .map(|(i, field_layouts)| {
-                        let mut st = self.univariant_uninterned(
-                            ty,
-                            &field_layouts,
-                            &def.repr,
-                            StructKind::Prefixed(min_ity.size(), prefix_align),
-                        )?;
-                        st.variants = Variants::Single { index: i };
-                        // Find the first field we can't move later
-                        // to make room for a larger discriminant.
-                        for field in
-                            st.fields.index_by_increasing_offset().map(|j| field_layouts[j])
-                        {
-                            if !field.is_zst() || field.align.abi.bytes() != 1 {
-                                start_align = start_align.min(field.align.abi);
-                                break;
-                            }
-                        }
-                        size = cmp::max(size, st.size);
-                        align = align.max(st.align);
-                        Ok(st)
-                    })
-                    .collect::<Result<IndexVec<VariantIdx, _>, _>>()?;
-
-                // Align the maximum variant size to the largest alignment.
-                size = size.align_to(align.abi);
-
-                if size.bytes() >= dl.obj_size_bound() {
-                    return Err(LayoutError::SizeOverflow(ty));
-                }
-
-                let typeck_ity = Integer::from_attr(dl, def.repr.discr_type());
-                if typeck_ity < min_ity {
-                    // It is a bug if Layout decided on a greater discriminant size than typeck for
-                    // some reason at this point (based on values discriminant can take on). Mostly
-                    // because this discriminant will be loaded, and then stored into variable of
-                    // type calculated by typeck. Consider such case (a bug): typeck decided on
-                    // byte-sized discriminant, but layout thinks we need a 16-bit to store all
-                    // discriminant values. That would be a bug, because then, in codegen, in order
-                    // to store this 16-bit discriminant into 8-bit sized temporary some of the
-                    // space necessary to represent would have to be discarded (or layout is wrong
-                    // on thinking it needs 16 bits)
-                    bug!(
-                        "layout decided on a larger discriminant type ({:?}) than typeck ({:?})",
-                        min_ity,
-                        typeck_ity
-                    );
-                    // However, it is fine to make discr type however large (as an optimisation)
-                    // after this point – we’ll just truncate the value we load in codegen.
-                }
-
-                // Check to see if we should use a different type for the
-                // discriminant. We can safely use a type with the same size
-                // as the alignment of the first field of each variant.
-                // We increase the size of the discriminant to avoid LLVM copying
-                // padding when it doesn't need to. This normally causes unaligned
-                // load/stores and excessive memcpy/memset operations. By using a
-                // bigger integer size, LLVM can be sure about its contents and
-                // won't be so conservative.
-
-                // Use the initial field alignment
-                let mut ity = if def.repr.c() || def.repr.int.is_some() {
-                    min_ity
-                } else {
-                    Integer::for_align(dl, start_align).unwrap_or(min_ity)
-                };
-
-                // If the alignment is not larger than the chosen discriminant size,
-                // don't use the alignment as the final size.
-                if ity <= min_ity {
-                    ity = min_ity;
-                } else {
-                    // Patch up the variants' first few fields.
-                    let old_ity_size = min_ity.size();
-                    let new_ity_size = ity.size();
-                    for variant in &mut layout_variants {
-                        match variant.fields {
-                            FieldPlacement::Arbitrary { ref mut offsets, .. } => {
-                                for i in offsets {
-                                    if *i <= old_ity_size {
-                                        assert_eq!(*i, old_ity_size);
-                                        *i = new_ity_size;
-                                    }
-                                }
-                                // We might be making the struct larger.
-                                if variant.size <= old_ity_size {
-                                    variant.size = new_ity_size;
-                                }
-                            }
-                            _ => bug!(),
-                        }
-                    }
-                }
-
-                let tag_mask = !0u128 >> (128 - ity.size().bits());
-                let tag = Scalar {
-                    value: Int(ity, signed),
-                    valid_range: (min as u128 & tag_mask)..=(max as u128 & tag_mask),
-                };
-                let mut abi = Abi::Aggregate { sized: true };
-                if tag.value.size(dl) == size {
-                    abi = Abi::Scalar(tag.clone());
-                } else {
-                    // Try to use a ScalarPair for all tagged enums.
-                    let mut common_prim = None;
-                    for (field_layouts, layout_variant) in variants.iter().zip(&layout_variants) {
-                        let offsets = match layout_variant.fields {
-                            FieldPlacement::Arbitrary { ref offsets, .. } => offsets,
-                            _ => bug!(),
-                        };
-                        let mut fields =
-                            field_layouts.iter().zip(offsets).filter(|p| !p.0.is_zst());
-                        let (field, offset) = match (fields.next(), fields.next()) {
-                            (None, None) => continue,
-                            (Some(pair), None) => pair,
-                            _ => {
-                                common_prim = None;
-                                break;
-                            }
-                        };
-                        let prim = match field.details.abi {
-                            Abi::Scalar(ref scalar) => scalar.value,
-                            _ => {
-                                common_prim = None;
-                                break;
-                            }
-                        };
-                        if let Some(pair) = common_prim {
-                            // This is pretty conservative. We could go fancier
-                            // by conflating things like i32 and u32, or even
-                            // realising that (u8, u8) could just cohabit with
-                            // u16 or even u32.
-                            if pair != (prim, offset) {
-                                common_prim = None;
-                                break;
-                            }
-                        } else {
-                            common_prim = Some((prim, offset));
-                        }
-                    }
-                    if let Some((prim, offset)) = common_prim {
-                        let pair = self.scalar_pair(tag.clone(), scalar_unit(prim));
-                        let pair_offsets = match pair.fields {
-                            FieldPlacement::Arbitrary { ref offsets, ref memory_index } => {
-                                assert_eq!(memory_index, &[0, 1]);
-                                offsets
-                            }
-                            _ => bug!(),
-                        };
-                        if pair_offsets[0] == Size::ZERO
-                            && pair_offsets[1] == *offset
-                            && align == pair.align
-                            && size == pair.size
-                        {
-                            // We can use `ScalarPair` only when it matches our
-                            // already computed layout (including `#[repr(C)]`).
-                            abi = pair.abi;
-                        }
-                    }
-                }
-
-                if layout_variants.iter().all(|v| v.abi.is_uninhabited()) {
-                    abi = Abi::Uninhabited;
-                }
-
-                let largest_niche = Niche::from_scalar(dl, Size::ZERO, tag.clone());
-
-                tcx.intern_layout(LayoutDetails {
-                    variants: Variants::Multiple {
-                        discr: tag,
-                        discr_kind: DiscriminantKind::Tag,
-                        discr_index: 0,
-                        variants: layout_variants,
-                    },
-                    fields: FieldPlacement::Arbitrary {
-                        offsets: vec![Size::ZERO],
-                        memory_index: vec![0],
-                    },
-                    largest_niche,
-                    abi,
-                    align,
-                    size,
-                })
-            }
-
-            // Types with no meaningful known layout.
-            ty::Projection(_) | ty::Opaque(..) => {
-                let normalized = tcx.normalize_erasing_regions(param_env, ty);
-                if ty == normalized {
-                    return Err(LayoutError::Unknown(ty));
-                }
-                tcx.layout_raw(param_env.and(normalized))?
-            }
-
-            ty::Bound(..)
-            | ty::Placeholder(..)
-            | ty::UnnormalizedProjection(..)
-            | ty::GeneratorWitness(..)
-            | ty::Infer(_) => bug!("LayoutDetails::compute: unexpected type `{}`", ty),
-
-            ty::Param(_) | ty::Error => {
-                return Err(LayoutError::Unknown(ty));
-            }
-        })
-    }
-}
-
-/// Overlap eligibility and variant assignment for each GeneratorSavedLocal.
-#[derive(Clone, Debug, PartialEq)]
-enum SavedLocalEligibility {
-    Unassigned,
-    Assigned(VariantIdx),
-    // FIXME: Use newtype_index so we aren't wasting bytes
-    Ineligible(Option<u32>),
-}
-
-// When laying out generators, we divide our saved local fields into two
-// categories: overlap-eligible and overlap-ineligible.
-//
-// Those fields which are ineligible for overlap go in a "prefix" at the
-// beginning of the layout, and always have space reserved for them.
-//
-// Overlap-eligible fields are only assigned to one variant, so we lay
-// those fields out for each variant and put them right after the
-// prefix.
-//
-// Finally, in the layout details, we point to the fields from the
-// variants they are assigned to. It is possible for some fields to be
-// included in multiple variants. No field ever "moves around" in the
-// layout; its offset is always the same.
-//
-// Also included in the layout are the upvars and the discriminant.
-// These are included as fields on the "outer" layout; they are not part
-// of any variant.
-impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
-    /// Compute the eligibility and assignment of each local.
-    fn generator_saved_local_eligibility(
-        &self,
-        info: &GeneratorLayout<'tcx>,
-    ) -> (BitSet<GeneratorSavedLocal>, IndexVec<GeneratorSavedLocal, SavedLocalEligibility>) {
-        use SavedLocalEligibility::*;
-
-        let mut assignments: IndexVec<GeneratorSavedLocal, SavedLocalEligibility> =
-            IndexVec::from_elem_n(Unassigned, info.field_tys.len());
-
-        // The saved locals not eligible for overlap. These will get
-        // "promoted" to the prefix of our generator.
-        let mut ineligible_locals = BitSet::new_empty(info.field_tys.len());
-
-        // Figure out which of our saved locals are fields in only
-        // one variant. The rest are deemed ineligible for overlap.
-        for (variant_index, fields) in info.variant_fields.iter_enumerated() {
-            for local in fields {
-                match assignments[*local] {
-                    Unassigned => {
-                        assignments[*local] = Assigned(variant_index);
-                    }
-                    Assigned(idx) => {
-                        // We've already seen this local at another suspension
-                        // point, so it is no longer a candidate.
-                        trace!(
-                            "removing local {:?} in >1 variant ({:?}, {:?})",
-                            local,
-                            variant_index,
-                            idx
-                        );
-                        ineligible_locals.insert(*local);
-                        assignments[*local] = Ineligible(None);
-                    }
-                    Ineligible(_) => {}
-                }
-            }
-        }
-
-        // Next, check every pair of eligible locals to see if they
-        // conflict.
-        for local_a in info.storage_conflicts.rows() {
-            let conflicts_a = info.storage_conflicts.count(local_a);
-            if ineligible_locals.contains(local_a) {
-                continue;
-            }
-
-            for local_b in info.storage_conflicts.iter(local_a) {
-                // local_a and local_b are storage live at the same time, therefore they
-                // cannot overlap in the generator layout. The only way to guarantee
-                // this is if they are in the same variant, or one is ineligible
-                // (which means it is stored in every variant).
-                if ineligible_locals.contains(local_b)
-                    || assignments[local_a] == assignments[local_b]
-                {
-                    continue;
-                }
-
-                // If they conflict, we will choose one to make ineligible.
-                // This is not always optimal; it's just a greedy heuristic that
-                // seems to produce good results most of the time.
-                let conflicts_b = info.storage_conflicts.count(local_b);
-                let (remove, other) =
-                    if conflicts_a > conflicts_b { (local_a, local_b) } else { (local_b, local_a) };
-                ineligible_locals.insert(remove);
-                assignments[remove] = Ineligible(None);
-                trace!("removing local {:?} due to conflict with {:?}", remove, other);
-            }
-        }
-
-        // Count the number of variants in use. If only one of them, then it is
-        // impossible to overlap any locals in our layout. In this case it's
-        // always better to make the remaining locals ineligible, so we can
-        // lay them out with the other locals in the prefix and eliminate
-        // unnecessary padding bytes.
-        {
-            let mut used_variants = BitSet::new_empty(info.variant_fields.len());
-            for assignment in &assignments {
-                match assignment {
-                    Assigned(idx) => {
-                        used_variants.insert(*idx);
-                    }
-                    _ => {}
-                }
-            }
-            if used_variants.count() < 2 {
-                for assignment in assignments.iter_mut() {
-                    *assignment = Ineligible(None);
-                }
-                ineligible_locals.insert_all();
-            }
-        }
-
-        // Write down the order of our locals that will be promoted to the prefix.
-        {
-            let mut idx = 0u32;
-            for local in ineligible_locals.iter() {
-                assignments[local] = Ineligible(Some(idx));
-                idx += 1;
-            }
-        }
-        debug!("generator saved local assignments: {:?}", assignments);
-
-        (ineligible_locals, assignments)
-    }
-
-    /// Compute the full generator layout.
-    fn generator_layout(
-        &self,
-        ty: Ty<'tcx>,
-        def_id: hir::def_id::DefId,
-        substs: SubstsRef<'tcx>,
-    ) -> Result<&'tcx LayoutDetails, LayoutError<'tcx>> {
-        use SavedLocalEligibility::*;
-        let tcx = self.tcx;
-
-        let subst_field = |ty: Ty<'tcx>| ty.subst(tcx, substs);
-
-        let info = tcx.generator_layout(def_id);
-        let (ineligible_locals, assignments) = self.generator_saved_local_eligibility(&info);
-
-        // Build a prefix layout, including "promoting" all ineligible
-        // locals as part of the prefix. We compute the layout of all of
-        // these fields at once to get optimal packing.
-        let discr_index = substs.as_generator().prefix_tys(def_id, tcx).count();
-        // FIXME(eddyb) set the correct vaidity range for the discriminant.
-        let discr_layout = self.layout_of(substs.as_generator().discr_ty(tcx))?;
-        let discr = match &discr_layout.abi {
-            Abi::Scalar(s) => s.clone(),
-            _ => bug!(),
-        };
-        let promoted_layouts = ineligible_locals
-            .iter()
-            .map(|local| subst_field(info.field_tys[local]))
-            .map(|ty| tcx.mk_maybe_uninit(ty))
-            .map(|ty| self.layout_of(ty));
-        let prefix_layouts = substs
-            .as_generator()
-            .prefix_tys(def_id, tcx)
-            .map(|ty| self.layout_of(ty))
-            .chain(iter::once(Ok(discr_layout)))
-            .chain(promoted_layouts)
-            .collect::<Result<Vec<_>, _>>()?;
-        let prefix = self.univariant_uninterned(
-            ty,
-            &prefix_layouts,
-            &ReprOptions::default(),
-            StructKind::AlwaysSized,
-        )?;
-
-        let (prefix_size, prefix_align) = (prefix.size, prefix.align);
-
-        // Split the prefix layout into the "outer" fields (upvars and
-        // discriminant) and the "promoted" fields. Promoted fields will
-        // get included in each variant that requested them in
-        // GeneratorLayout.
-        debug!("prefix = {:#?}", prefix);
-        let (outer_fields, promoted_offsets, promoted_memory_index) = match prefix.fields {
-            FieldPlacement::Arbitrary { mut offsets, memory_index } => {
-                let mut inverse_memory_index = invert_mapping(&memory_index);
-
-                // "a" (`0..b_start`) and "b" (`b_start..`) correspond to
-                // "outer" and "promoted" fields respectively.
-                let b_start = (discr_index + 1) as u32;
-                let offsets_b = offsets.split_off(b_start as usize);
-                let offsets_a = offsets;
-
-                // Disentangle the "a" and "b" components of `inverse_memory_index`
-                // by preserving the order but keeping only one disjoint "half" each.
-                // FIXME(eddyb) build a better abstraction for permutations, if possible.
-                let inverse_memory_index_b: Vec<_> =
-                    inverse_memory_index.iter().filter_map(|&i| i.checked_sub(b_start)).collect();
-                inverse_memory_index.retain(|&i| i < b_start);
-                let inverse_memory_index_a = inverse_memory_index;
-
-                // Since `inverse_memory_index_{a,b}` each only refer to their
-                // respective fields, they can be safely inverted
-                let memory_index_a = invert_mapping(&inverse_memory_index_a);
-                let memory_index_b = invert_mapping(&inverse_memory_index_b);
-
-                let outer_fields =
-                    FieldPlacement::Arbitrary { offsets: offsets_a, memory_index: memory_index_a };
-                (outer_fields, offsets_b, memory_index_b)
-            }
-            _ => bug!(),
-        };
-
-        let mut size = prefix.size;
-        let mut align = prefix.align;
-        let variants = info
-            .variant_fields
-            .iter_enumerated()
-            .map(|(index, variant_fields)| {
-                // Only include overlap-eligible fields when we compute our variant layout.
-                let variant_only_tys = variant_fields
-                    .iter()
-                    .filter(|local| match assignments[**local] {
-                        Unassigned => bug!(),
-                        Assigned(v) if v == index => true,
-                        Assigned(_) => bug!("assignment does not match variant"),
-                        Ineligible(_) => false,
-                    })
-                    .map(|local| subst_field(info.field_tys[*local]));
-
-                let mut variant = self.univariant_uninterned(
-                    ty,
-                    &variant_only_tys
-                        .map(|ty| self.layout_of(ty))
-                        .collect::<Result<Vec<_>, _>>()?,
-                    &ReprOptions::default(),
-                    StructKind::Prefixed(prefix_size, prefix_align.abi),
-                )?;
-                variant.variants = Variants::Single { index };
-
-                let (offsets, memory_index) = match variant.fields {
-                    FieldPlacement::Arbitrary { offsets, memory_index } => (offsets, memory_index),
-                    _ => bug!(),
-                };
-
-                // Now, stitch the promoted and variant-only fields back together in
-                // the order they are mentioned by our GeneratorLayout.
-                // Because we only use some subset (that can differ between variants)
-                // of the promoted fields, we can't just pick those elements of the
-                // `promoted_memory_index` (as we'd end up with gaps).
-                // So instead, we build an "inverse memory_index", as if all of the
-                // promoted fields were being used, but leave the elements not in the
-                // subset as `INVALID_FIELD_IDX`, which we can filter out later to
-                // obtain a valid (bijective) mapping.
-                const INVALID_FIELD_IDX: u32 = !0;
-                let mut combined_inverse_memory_index =
-                    vec![INVALID_FIELD_IDX; promoted_memory_index.len() + memory_index.len()];
-                let mut offsets_and_memory_index = offsets.into_iter().zip(memory_index);
-                let combined_offsets = variant_fields
-                    .iter()
-                    .enumerate()
-                    .map(|(i, local)| {
-                        let (offset, memory_index) = match assignments[*local] {
-                            Unassigned => bug!(),
-                            Assigned(_) => {
-                                let (offset, memory_index) =
-                                    offsets_and_memory_index.next().unwrap();
-                                (offset, promoted_memory_index.len() as u32 + memory_index)
-                            }
-                            Ineligible(field_idx) => {
-                                let field_idx = field_idx.unwrap() as usize;
-                                (promoted_offsets[field_idx], promoted_memory_index[field_idx])
-                            }
-                        };
-                        combined_inverse_memory_index[memory_index as usize] = i as u32;
-                        offset
-                    })
-                    .collect();
-
-                // Remove the unused slots and invert the mapping to obtain the
-                // combined `memory_index` (also see previous comment).
-                combined_inverse_memory_index.retain(|&i| i != INVALID_FIELD_IDX);
-                let combined_memory_index = invert_mapping(&combined_inverse_memory_index);
-
-                variant.fields = FieldPlacement::Arbitrary {
-                    offsets: combined_offsets,
-                    memory_index: combined_memory_index,
-                };
-
-                size = size.max(variant.size);
-                align = align.max(variant.align);
-                Ok(variant)
-            })
-            .collect::<Result<IndexVec<VariantIdx, _>, _>>()?;
-
-        size = size.align_to(align.abi);
-
-        let abi = if prefix.abi.is_uninhabited() || variants.iter().all(|v| v.abi.is_uninhabited())
-        {
-            Abi::Uninhabited
-        } else {
-            Abi::Aggregate { sized: true }
-        };
-
-        let layout = tcx.intern_layout(LayoutDetails {
-            variants: Variants::Multiple {
-                discr,
-                discr_kind: DiscriminantKind::Tag,
-                discr_index,
-                variants,
-            },
-            fields: outer_fields,
-            abi,
-            largest_niche: prefix.largest_niche,
-            size,
-            align,
-        });
-        debug!("generator layout ({:?}): {:#?}", ty, layout);
-        Ok(layout)
-    }
-
-    /// This is invoked by the `layout_raw` query to record the final
-    /// layout of each type.
-    #[inline(always)]
-    fn record_layout_for_printing(&self, layout: TyLayout<'tcx>) {
-        // If we are running with `-Zprint-type-sizes`, maybe record layouts
-        // for dumping later.
-        if self.tcx.sess.opts.debugging_opts.print_type_sizes {
-            self.record_layout_for_printing_outlined(layout)
-        }
-    }
-
-    fn record_layout_for_printing_outlined(&self, layout: TyLayout<'tcx>) {
-        // Ignore layouts that are done with non-empty environments or
-        // non-monomorphic layouts, as the user only wants to see the stuff
-        // resulting from the final codegen session.
-        if layout.ty.has_param_types() || !self.param_env.caller_bounds.is_empty() {
-            return;
-        }
-
-        // (delay format until we actually need it)
-        let record = |kind, packed, opt_discr_size, variants| {
-            let type_desc = format!("{:?}", layout.ty);
-            self.tcx.sess.code_stats.record_type_size(
-                kind,
-                type_desc,
-                layout.align.abi,
-                layout.size,
-                packed,
-                opt_discr_size,
-                variants,
-            );
-        };
-
-        let adt_def = match layout.ty.kind {
-            ty::Adt(ref adt_def, _) => {
-                debug!("print-type-size t: `{:?}` process adt", layout.ty);
-                adt_def
-            }
-
-            ty::Closure(..) => {
-                debug!("print-type-size t: `{:?}` record closure", layout.ty);
-                record(DataTypeKind::Closure, false, None, vec![]);
-                return;
-            }
-
-            _ => {
-                debug!("print-type-size t: `{:?}` skip non-nominal", layout.ty);
-                return;
-            }
-        };
-
-        let adt_kind = adt_def.adt_kind();
-        let adt_packed = adt_def.repr.pack.is_some();
-
-        let build_variant_info = |n: Option<Ident>, flds: &[ast::Name], layout: TyLayout<'tcx>| {
-            let mut min_size = Size::ZERO;
-            let field_info: Vec<_> = flds
-                .iter()
-                .enumerate()
-                .map(|(i, &name)| match layout.field(self, i) {
-                    Err(err) => {
-                        bug!("no layout found for field {}: `{:?}`", name, err);
-                    }
-                    Ok(field_layout) => {
-                        let offset = layout.fields.offset(i);
-                        let field_end = offset + field_layout.size;
-                        if min_size < field_end {
-                            min_size = field_end;
-                        }
-                        session::FieldInfo {
-                            name: name.to_string(),
-                            offset: offset.bytes(),
-                            size: field_layout.size.bytes(),
-                            align: field_layout.align.abi.bytes(),
-                        }
-                    }
-                })
-                .collect();
-
-            session::VariantInfo {
-                name: n.map(|n| n.to_string()),
-                kind: if layout.is_unsized() {
-                    session::SizeKind::Min
-                } else {
-                    session::SizeKind::Exact
-                },
-                align: layout.align.abi.bytes(),
-                size: if min_size.bytes() == 0 { layout.size.bytes() } else { min_size.bytes() },
-                fields: field_info,
-            }
-        };
-
-        match layout.variants {
-            Variants::Single { index } => {
-                debug!("print-type-size `{:#?}` variant {}", layout, adt_def.variants[index].ident);
-                if !adt_def.variants.is_empty() {
-                    let variant_def = &adt_def.variants[index];
-                    let fields: Vec<_> = variant_def.fields.iter().map(|f| f.ident.name).collect();
-                    record(
-                        adt_kind.into(),
-                        adt_packed,
-                        None,
-                        vec![build_variant_info(Some(variant_def.ident), &fields, layout)],
-                    );
-                } else {
-                    // (This case arises for *empty* enums; so give it
-                    // zero variants.)
-                    record(adt_kind.into(), adt_packed, None, vec![]);
-                }
-            }
-
-            Variants::Multiple { ref discr, ref discr_kind, .. } => {
-                debug!(
-                    "print-type-size `{:#?}` adt general variants def {}",
-                    layout.ty,
-                    adt_def.variants.len()
-                );
-                let variant_infos: Vec<_> = adt_def
-                    .variants
-                    .iter_enumerated()
-                    .map(|(i, variant_def)| {
-                        let fields: Vec<_> =
-                            variant_def.fields.iter().map(|f| f.ident.name).collect();
-                        build_variant_info(
-                            Some(variant_def.ident),
-                            &fields,
-                            layout.for_variant(self, i),
-                        )
-                    })
-                    .collect();
-                record(
-                    adt_kind.into(),
-                    adt_packed,
-                    match discr_kind {
-                        DiscriminantKind::Tag => Some(discr.value.size(self)),
-                        _ => None,
-                    },
-                    variant_infos,
-                );
-            }
-        }
-    }
-}
-
-/// Type size "skeleton", i.e., the only information determining a type's size.
-/// While this is conservative, (aside from constant sizes, only pointers,
-/// newtypes thereof and null pointer optimized enums are allowed), it is
-/// enough to statically check common use cases of transmute.
-#[derive(Copy, Clone, Debug)]
-pub enum SizeSkeleton<'tcx> {
-    /// Any statically computable Layout.
-    Known(Size),
-
-    /// A potentially-fat pointer.
-    Pointer {
-        /// If true, this pointer is never null.
-        non_zero: bool,
-        /// The type which determines the unsized metadata, if any,
-        /// of this pointer. Either a type parameter or a projection
-        /// depending on one, with regions erased.
-        tail: Ty<'tcx>,
-    },
-}
-
-impl<'tcx> SizeSkeleton<'tcx> {
-    pub fn compute(
-        ty: Ty<'tcx>,
-        tcx: TyCtxt<'tcx>,
-        param_env: ty::ParamEnv<'tcx>,
-    ) -> Result<SizeSkeleton<'tcx>, LayoutError<'tcx>> {
-        debug_assert!(!ty.has_infer_types());
-
-        // First try computing a static layout.
-        let err = match tcx.layout_of(param_env.and(ty)) {
-            Ok(layout) => {
-                return Ok(SizeSkeleton::Known(layout.size));
-            }
-            Err(err) => err,
-        };
-
-        match ty.kind {
-            ty::Ref(_, pointee, _) | ty::RawPtr(ty::TypeAndMut { ty: pointee, .. }) => {
-                let non_zero = !ty.is_unsafe_ptr();
-                let tail = tcx.struct_tail_erasing_lifetimes(pointee, param_env);
-                match tail.kind {
-                    ty::Param(_) | ty::Projection(_) => {
-                        debug_assert!(tail.has_param_types());
-                        Ok(SizeSkeleton::Pointer { non_zero, tail: tcx.erase_regions(&tail) })
-                    }
-                    _ => bug!(
-                        "SizeSkeleton::compute({}): layout errored ({}), yet \
-                              tail `{}` is not a type parameter or a projection",
-                        ty,
-                        err,
-                        tail
-                    ),
-                }
-            }
-
-            ty::Adt(def, substs) => {
-                // Only newtypes and enums w/ nullable pointer optimization.
-                if def.is_union() || def.variants.is_empty() || def.variants.len() > 2 {
-                    return Err(err);
-                }
-
-                // Get a zero-sized variant or a pointer newtype.
-                let zero_or_ptr_variant = |i| {
-                    let i = VariantIdx::new(i);
-                    let fields = def.variants[i]
-                        .fields
-                        .iter()
-                        .map(|field| SizeSkeleton::compute(field.ty(tcx, substs), tcx, param_env));
-                    let mut ptr = None;
-                    for field in fields {
-                        let field = field?;
-                        match field {
-                            SizeSkeleton::Known(size) => {
-                                if size.bytes() > 0 {
-                                    return Err(err);
-                                }
-                            }
-                            SizeSkeleton::Pointer { .. } => {
-                                if ptr.is_some() {
-                                    return Err(err);
-                                }
-                                ptr = Some(field);
-                            }
-                        }
-                    }
-                    Ok(ptr)
-                };
-
-                let v0 = zero_or_ptr_variant(0)?;
-                // Newtype.
-                if def.variants.len() == 1 {
-                    if let Some(SizeSkeleton::Pointer { non_zero, tail }) = v0 {
-                        return Ok(SizeSkeleton::Pointer {
-                            non_zero: non_zero
-                                || match tcx.layout_scalar_valid_range(def.did) {
-                                    (Bound::Included(start), Bound::Unbounded) => start > 0,
-                                    (Bound::Included(start), Bound::Included(end)) => {
-                                        0 < start && start < end
-                                    }
-                                    _ => false,
-                                },
-                            tail,
-                        });
-                    } else {
-                        return Err(err);
-                    }
-                }
-
-                let v1 = zero_or_ptr_variant(1)?;
-                // Nullable pointer enum optimization.
-                match (v0, v1) {
-                    (Some(SizeSkeleton::Pointer { non_zero: true, tail }), None)
-                    | (None, Some(SizeSkeleton::Pointer { non_zero: true, tail })) => {
-                        Ok(SizeSkeleton::Pointer { non_zero: false, tail })
-                    }
-                    _ => Err(err),
-                }
-            }
-
-            ty::Projection(_) | ty::Opaque(..) => {
-                let normalized = tcx.normalize_erasing_regions(param_env, ty);
-                if ty == normalized {
-                    Err(err)
-                } else {
-                    SizeSkeleton::compute(normalized, tcx, param_env)
-                }
-            }
-
-            _ => Err(err),
-        }
-    }
-
-    pub fn same_size(self, other: SizeSkeleton<'_>) -> bool {
-        match (self, other) {
-            (SizeSkeleton::Known(a), SizeSkeleton::Known(b)) => a == b,
-            (SizeSkeleton::Pointer { tail: a, .. }, SizeSkeleton::Pointer { tail: b, .. }) => {
-                a == b
-            }
-            _ => false,
-        }
-    }
-}
-
-pub trait HasTyCtxt<'tcx>: HasDataLayout {
-    fn tcx(&self) -> TyCtxt<'tcx>;
-}
-
-pub trait HasParamEnv<'tcx> {
-    fn param_env(&self) -> ty::ParamEnv<'tcx>;
-}
-
-impl<'tcx> HasDataLayout for TyCtxt<'tcx> {
-    fn data_layout(&self) -> &TargetDataLayout {
-        &self.data_layout
-    }
-}
-
-impl<'tcx> HasTyCtxt<'tcx> for TyCtxt<'tcx> {
-    fn tcx(&self) -> TyCtxt<'tcx> {
-        *self
-    }
-}
-
-impl<'tcx, C> HasParamEnv<'tcx> for LayoutCx<'tcx, C> {
-    fn param_env(&self) -> ty::ParamEnv<'tcx> {
-        self.param_env
-    }
-}
-
-impl<'tcx, T: HasDataLayout> HasDataLayout for LayoutCx<'tcx, T> {
-    fn data_layout(&self) -> &TargetDataLayout {
-        self.tcx.data_layout()
-    }
-}
-
-impl<'tcx, T: HasTyCtxt<'tcx>> HasTyCtxt<'tcx> for LayoutCx<'tcx, T> {
-    fn tcx(&self) -> TyCtxt<'tcx> {
-        self.tcx.tcx()
-    }
-}
-
-pub trait MaybeResult<T> {
-    type Error;
-
-    fn from(x: Result<T, Self::Error>) -> Self;
-    fn to_result(self) -> Result<T, Self::Error>;
-}
-
-impl<T> MaybeResult<T> for T {
-    type Error = !;
-
-    fn from(x: Result<T, Self::Error>) -> Self {
-        let Ok(x) = x;
-        x
-    }
-    fn to_result(self) -> Result<T, Self::Error> {
-        Ok(self)
-    }
-}
-
-impl<T, E> MaybeResult<T> for Result<T, E> {
-    type Error = E;
-
-    fn from(x: Result<T, Self::Error>) -> Self {
-        x
-    }
-    fn to_result(self) -> Result<T, Self::Error> {
-        self
-    }
-}
-
-pub type TyLayout<'tcx> = ::rustc_target::abi::TyLayout<'tcx, Ty<'tcx>>;
-
-impl<'tcx> LayoutOf for LayoutCx<'tcx, TyCtxt<'tcx>> {
-    type Ty = Ty<'tcx>;
-    type TyLayout = Result<TyLayout<'tcx>, LayoutError<'tcx>>;
-
-    /// Computes the layout of a type. Note that this implicitly
-    /// executes in "reveal all" mode.
-    fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyLayout {
-        let param_env = self.param_env.with_reveal_all();
-        let ty = self.tcx.normalize_erasing_regions(param_env, ty);
-        let details = self.tcx.layout_raw(param_env.and(ty))?;
-        let layout = TyLayout { ty, details };
-
-        // N.B., this recording is normally disabled; when enabled, it
-        // can however trigger recursive invocations of `layout_of`.
-        // Therefore, we execute it *after* the main query has
-        // completed, to avoid problems around recursive structures
-        // and the like. (Admittedly, I wasn't able to reproduce a problem
-        // here, but it seems like the right thing to do. -nmatsakis)
-        self.record_layout_for_printing(layout);
-
-        Ok(layout)
-    }
-}
-
-impl LayoutOf for LayoutCx<'tcx, ty::query::TyCtxtAt<'tcx>> {
-    type Ty = Ty<'tcx>;
-    type TyLayout = Result<TyLayout<'tcx>, LayoutError<'tcx>>;
-
-    /// Computes the layout of a type. Note that this implicitly
-    /// executes in "reveal all" mode.
-    fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyLayout {
-        let param_env = self.param_env.with_reveal_all();
-        let ty = self.tcx.normalize_erasing_regions(param_env, ty);
-        let details = self.tcx.layout_raw(param_env.and(ty))?;
-        let layout = TyLayout { ty, details };
-
-        // N.B., this recording is normally disabled; when enabled, it
-        // can however trigger recursive invocations of `layout_of`.
-        // Therefore, we execute it *after* the main query has
-        // completed, to avoid problems around recursive structures
-        // and the like. (Admittedly, I wasn't able to reproduce a problem
-        // here, but it seems like the right thing to do. -nmatsakis)
-        let cx = LayoutCx { tcx: *self.tcx, param_env: self.param_env };
-        cx.record_layout_for_printing(layout);
-
-        Ok(layout)
-    }
-}
-
-// Helper (inherent) `layout_of` methods to avoid pushing `LayoutCx` to users.
-impl TyCtxt<'tcx> {
-    /// Computes the layout of a type. Note that this implicitly
-    /// executes in "reveal all" mode.
-    #[inline]
-    pub fn layout_of(
-        self,
-        param_env_and_ty: ty::ParamEnvAnd<'tcx, Ty<'tcx>>,
-    ) -> Result<TyLayout<'tcx>, LayoutError<'tcx>> {
-        let cx = LayoutCx { tcx: self, param_env: param_env_and_ty.param_env };
-        cx.layout_of(param_env_and_ty.value)
-    }
-}
-
-impl ty::query::TyCtxtAt<'tcx> {
-    /// Computes the layout of a type. Note that this implicitly
-    /// executes in "reveal all" mode.
-    #[inline]
-    pub fn layout_of(
-        self,
-        param_env_and_ty: ty::ParamEnvAnd<'tcx, Ty<'tcx>>,
-    ) -> Result<TyLayout<'tcx>, LayoutError<'tcx>> {
-        let cx = LayoutCx { tcx: self.at(self.span), param_env: param_env_and_ty.param_env };
-        cx.layout_of(param_env_and_ty.value)
-    }
-}
-
-impl<'tcx, C> TyLayoutMethods<'tcx, C> for Ty<'tcx>
-where
-    C: LayoutOf<Ty = Ty<'tcx>, TyLayout: MaybeResult<TyLayout<'tcx>>>
-        + HasTyCtxt<'tcx>
-        + HasParamEnv<'tcx>,
-{
-    fn for_variant(this: TyLayout<'tcx>, cx: &C, variant_index: VariantIdx) -> TyLayout<'tcx> {
-        let details = match this.variants {
-            Variants::Single { index } if index == variant_index => this.details,
-
-            Variants::Single { index } => {
-                // Deny calling for_variant more than once for non-Single enums.
-                if let Ok(layout) = cx.layout_of(this.ty).to_result() {
-                    assert_eq!(layout.variants, Variants::Single { index });
-                }
-
-                let fields = match this.ty.kind {
-                    ty::Adt(def, _) => def.variants[variant_index].fields.len(),
-                    _ => bug!(),
-                };
-                let tcx = cx.tcx();
-                tcx.intern_layout(LayoutDetails {
-                    variants: Variants::Single { index: variant_index },
-                    fields: FieldPlacement::Union(fields),
-                    abi: Abi::Uninhabited,
-                    largest_niche: None,
-                    align: tcx.data_layout.i8_align,
-                    size: Size::ZERO,
-                })
-            }
-
-            Variants::Multiple { ref variants, .. } => &variants[variant_index],
-        };
-
-        assert_eq!(details.variants, Variants::Single { index: variant_index });
-
-        TyLayout { ty: this.ty, details }
-    }
-
-    fn field(this: TyLayout<'tcx>, cx: &C, i: usize) -> C::TyLayout {
-        let tcx = cx.tcx();
-        let discr_layout = |discr: &Scalar| -> C::TyLayout {
-            let layout = LayoutDetails::scalar(cx, discr.clone());
-            MaybeResult::from(Ok(TyLayout {
-                details: tcx.intern_layout(layout),
-                ty: discr.value.to_ty(tcx),
-            }))
-        };
-
-        cx.layout_of(match this.ty.kind {
-            ty::Bool
-            | ty::Char
-            | ty::Int(_)
-            | ty::Uint(_)
-            | ty::Float(_)
-            | ty::FnPtr(_)
-            | ty::Never
-            | ty::FnDef(..)
-            | ty::GeneratorWitness(..)
-            | ty::Foreign(..)
-            | ty::Dynamic(..) => bug!("TyLayout::field_type({:?}): not applicable", this),
-
-            // Potentially-fat pointers.
-            ty::Ref(_, pointee, _) | ty::RawPtr(ty::TypeAndMut { ty: pointee, .. }) => {
-                assert!(i < this.fields.count());
-
-                // Reuse the fat `*T` type as its own thin pointer data field.
-                // This provides information about, e.g., DST struct pointees
-                // (which may have no non-DST form), and will work as long
-                // as the `Abi` or `FieldPlacement` is checked by users.
-                if i == 0 {
-                    let nil = tcx.mk_unit();
-                    let ptr_ty = if this.ty.is_unsafe_ptr() {
-                        tcx.mk_mut_ptr(nil)
-                    } else {
-                        tcx.mk_mut_ref(tcx.lifetimes.re_static, nil)
-                    };
-                    return MaybeResult::from(cx.layout_of(ptr_ty).to_result().map(
-                        |mut ptr_layout| {
-                            ptr_layout.ty = this.ty;
-                            ptr_layout
-                        },
-                    ));
-                }
-
-                match tcx.struct_tail_erasing_lifetimes(pointee, cx.param_env()).kind {
-                    ty::Slice(_) | ty::Str => tcx.types.usize,
-                    ty::Dynamic(_, _) => {
-                        tcx.mk_imm_ref(tcx.lifetimes.re_static, tcx.mk_array(tcx.types.usize, 3))
-                        /* FIXME: use actual fn pointers
-                        Warning: naively computing the number of entries in the
-                        vtable by counting the methods on the trait + methods on
-                        all parent traits does not work, because some methods can
-                        be not object safe and thus excluded from the vtable.
-                        Increase this counter if you tried to implement this but
-                        failed to do it without duplicating a lot of code from
-                        other places in the compiler: 2
-                        tcx.mk_tup(&[
-                            tcx.mk_array(tcx.types.usize, 3),
-                            tcx.mk_array(Option<fn()>),
-                        ])
-                        */
-                    }
-                    _ => bug!("TyLayout::field_type({:?}): not applicable", this),
-                }
-            }
-
-            // Arrays and slices.
-            ty::Array(element, _) | ty::Slice(element) => element,
-            ty::Str => tcx.types.u8,
-
-            // Tuples, generators and closures.
-            ty::Closure(def_id, ref substs) => {
-                substs.as_closure().upvar_tys(def_id, tcx).nth(i).unwrap()
-            }
-
-            ty::Generator(def_id, ref substs, _) => match this.variants {
-                Variants::Single { index } => substs
-                    .as_generator()
-                    .state_tys(def_id, tcx)
-                    .nth(index.as_usize())
-                    .unwrap()
-                    .nth(i)
-                    .unwrap(),
-                Variants::Multiple { ref discr, discr_index, .. } => {
-                    if i == discr_index {
-                        return discr_layout(discr);
-                    }
-                    substs.as_generator().prefix_tys(def_id, tcx).nth(i).unwrap()
-                }
-            },
-
-            ty::Tuple(tys) => tys[i].expect_ty(),
-
-            // SIMD vector types.
-            ty::Adt(def, ..) if def.repr.simd() => this.ty.simd_type(tcx),
-
-            // ADTs.
-            ty::Adt(def, substs) => {
-                match this.variants {
-                    Variants::Single { index } => def.variants[index].fields[i].ty(tcx, substs),
-
-                    // Discriminant field for enums (where applicable).
-                    Variants::Multiple { ref discr, .. } => {
-                        assert_eq!(i, 0);
-                        return discr_layout(discr);
-                    }
-                }
-            }
-
-            ty::Projection(_)
-            | ty::UnnormalizedProjection(..)
-            | ty::Bound(..)
-            | ty::Placeholder(..)
-            | ty::Opaque(..)
-            | ty::Param(_)
-            | ty::Infer(_)
-            | ty::Error => bug!("TyLayout::field_type: unexpected type `{}`", this.ty),
-        })
-    }
-
-    fn pointee_info_at(this: TyLayout<'tcx>, cx: &C, offset: Size) -> Option<PointeeInfo> {
-        match this.ty.kind {
-            ty::RawPtr(mt) if offset.bytes() == 0 => {
-                cx.layout_of(mt.ty).to_result().ok().map(|layout| PointeeInfo {
-                    size: layout.size,
-                    align: layout.align.abi,
-                    safe: None,
-                })
-            }
-
-            ty::Ref(_, ty, mt) if offset.bytes() == 0 => {
-                let tcx = cx.tcx();
-                let is_freeze = ty.is_freeze(tcx, cx.param_env(), DUMMY_SP);
-                let kind = match mt {
-                    hir::Mutability::Not => {
-                        if is_freeze {
-                            PointerKind::Frozen
-                        } else {
-                            PointerKind::Shared
-                        }
-                    }
-                    hir::Mutability::Mut => {
-                        // Previously we would only emit noalias annotations for LLVM >= 6 or in
-                        // panic=abort mode. That was deemed right, as prior versions had many bugs
-                        // in conjunction with unwinding, but later versions didn’t seem to have
-                        // said issues. See issue #31681.
-                        //
-                        // Alas, later on we encountered a case where noalias would generate wrong
-                        // code altogether even with recent versions of LLVM in *safe* code with no
-                        // unwinding involved. See #54462.
-                        //
-                        // For now, do not enable mutable_noalias by default at all, while the
-                        // issue is being figured out.
-                        let mutable_noalias =
-                            tcx.sess.opts.debugging_opts.mutable_noalias.unwrap_or(false);
-                        if mutable_noalias {
-                            PointerKind::UniqueBorrowed
-                        } else {
-                            PointerKind::Shared
-                        }
-                    }
-                };
-
-                cx.layout_of(ty).to_result().ok().map(|layout| PointeeInfo {
-                    size: layout.size,
-                    align: layout.align.abi,
-                    safe: Some(kind),
-                })
-            }
-
-            _ => {
-                let mut data_variant = match this.variants {
-                    // Within the discriminant field, only the niche itself is
-                    // always initialized, so we only check for a pointer at its
-                    // offset.
-                    //
-                    // If the niche is a pointer, it's either valid (according
-                    // to its type), or null (which the niche field's scalar
-                    // validity range encodes).  This allows using
-                    // `dereferenceable_or_null` for e.g., `Option<&T>`, and
-                    // this will continue to work as long as we don't start
-                    // using more niches than just null (e.g., the first page of
-                    // the address space, or unaligned pointers).
-                    Variants::Multiple {
-                        discr_kind: DiscriminantKind::Niche { dataful_variant, .. },
-                        discr_index,
-                        ..
-                    } if this.fields.offset(discr_index) == offset => {
-                        Some(this.for_variant(cx, dataful_variant))
-                    }
-                    _ => Some(this),
-                };
-
-                if let Some(variant) = data_variant {
-                    // We're not interested in any unions.
-                    if let FieldPlacement::Union(_) = variant.fields {
-                        data_variant = None;
-                    }
-                }
-
-                let mut result = None;
-
-                if let Some(variant) = data_variant {
-                    let ptr_end = offset + Pointer.size(cx);
-                    for i in 0..variant.fields.count() {
-                        let field_start = variant.fields.offset(i);
-                        if field_start <= offset {
-                            let field = variant.field(cx, i);
-                            result = field.to_result().ok().and_then(|field| {
-                                if ptr_end <= field_start + field.size {
-                                    // We found the right field, look inside it.
-                                    field.pointee_info_at(cx, offset - field_start)
-                                } else {
-                                    None
-                                }
-                            });
-                            if result.is_some() {
-                                break;
-                            }
-                        }
-                    }
-                }
-
-                // FIXME(eddyb) This should be for `ptr::Unique<T>`, not `Box<T>`.
-                if let Some(ref mut pointee) = result {
-                    if let ty::Adt(def, _) = this.ty.kind {
-                        if def.is_box() && offset.bytes() == 0 {
-                            pointee.safe = Some(PointerKind::UniqueOwned);
-                        }
-                    }
-                }
-
-                result
-            }
-        }
-    }
-}
-
-impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for LayoutError<'tcx> {
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        use crate::ty::layout::LayoutError::*;
-        mem::discriminant(self).hash_stable(hcx, hasher);
-
-        match *self {
-            Unknown(t) | SizeOverflow(t) => t.hash_stable(hcx, hasher),
-        }
-    }
-}
-
-impl<'tcx> ty::Instance<'tcx> {
-    // NOTE(eddyb) this is private to avoid using it from outside of
-    // `FnAbi::of_instance` - any other uses are either too high-level
-    // for `Instance` (e.g. typeck would use `Ty::fn_sig` instead),
-    // or should go through `FnAbi` instead, to avoid losing any
-    // adjustments `FnAbi::of_instance` might be performing.
-    fn fn_sig_for_fn_abi(&self, tcx: TyCtxt<'tcx>) -> ty::PolyFnSig<'tcx> {
-        let ty = self.monomorphic_ty(tcx);
-        match ty.kind {
-            ty::FnDef(..) |
-            // Shims currently have type FnPtr. Not sure this should remain.
-            ty::FnPtr(_) => {
-                let mut sig = ty.fn_sig(tcx);
-                if let ty::InstanceDef::VtableShim(..) = self.def {
-                    // Modify `fn(self, ...)` to `fn(self: *mut Self, ...)`.
-                    sig = sig.map_bound(|mut sig| {
-                        let mut inputs_and_output = sig.inputs_and_output.to_vec();
-                        inputs_and_output[0] = tcx.mk_mut_ptr(inputs_and_output[0]);
-                        sig.inputs_and_output = tcx.intern_type_list(&inputs_and_output);
-                        sig
-                    });
-                }
-                sig
-            }
-            ty::Closure(def_id, substs) => {
-                let sig = substs.as_closure().sig(def_id, tcx);
-
-                let env_ty = tcx.closure_env_ty(def_id, substs).unwrap();
-                sig.map_bound(|sig| tcx.mk_fn_sig(
-                    iter::once(*env_ty.skip_binder()).chain(sig.inputs().iter().cloned()),
-                    sig.output(),
-                    sig.c_variadic,
-                    sig.unsafety,
-                    sig.abi
-                ))
-            }
-            ty::Generator(def_id, substs, _) => {
-                let sig = substs.as_generator().poly_sig(def_id, tcx);
-
-                let env_region = ty::ReLateBound(ty::INNERMOST, ty::BrEnv);
-                let env_ty = tcx.mk_mut_ref(tcx.mk_region(env_region), ty);
-
-                let pin_did = tcx.lang_items().pin_type().unwrap();
-                let pin_adt_ref = tcx.adt_def(pin_did);
-                let pin_substs = tcx.intern_substs(&[env_ty.into()]);
-                let env_ty = tcx.mk_adt(pin_adt_ref, pin_substs);
-
-                sig.map_bound(|sig| {
-                    let state_did = tcx.lang_items().gen_state().unwrap();
-                    let state_adt_ref = tcx.adt_def(state_did);
-                    let state_substs = tcx.intern_substs(&[
-                        sig.yield_ty.into(),
-                        sig.return_ty.into(),
-                    ]);
-                    let ret_ty = tcx.mk_adt(state_adt_ref, state_substs);
-
-                    tcx.mk_fn_sig(
-                        [env_ty, sig.resume_ty].iter(),
-                        &ret_ty,
-                        false,
-                        hir::Unsafety::Normal,
-                        rustc_target::spec::abi::Abi::Rust
-                    )
-                })
-            }
-            _ => bug!("unexpected type {:?} in Instance::fn_sig", ty)
-        }
-    }
-}
-
-pub trait FnAbiExt<'tcx, C>
-where
-    C: LayoutOf<Ty = Ty<'tcx>, TyLayout = TyLayout<'tcx>>
-        + HasDataLayout
-        + HasTargetSpec
-        + HasTyCtxt<'tcx>
-        + HasParamEnv<'tcx>,
-{
-    /// Compute a `FnAbi` suitable for indirect calls, i.e. to `fn` pointers.
-    ///
-    /// NB: this doesn't handle virtual calls - those should use `FnAbi::of_instance`
-    /// instead, where the instance is a `InstanceDef::Virtual`.
-    fn of_fn_ptr(cx: &C, sig: ty::PolyFnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> Self;
-
-    /// Compute a `FnAbi` suitable for declaring/defining an `fn` instance, and for
-    /// direct calls to an `fn`.
-    ///
-    /// NB: that includes virtual calls, which are represented by "direct calls"
-    /// to a `InstanceDef::Virtual` instance (of `<dyn Trait as Trait>::fn`).
-    fn of_instance(cx: &C, instance: ty::Instance<'tcx>, extra_args: &[Ty<'tcx>]) -> Self;
-
-    fn new_internal(
-        cx: &C,
-        sig: ty::PolyFnSig<'tcx>,
-        extra_args: &[Ty<'tcx>],
-        caller_location: Option<Ty<'tcx>>,
-        mk_arg_type: impl Fn(Ty<'tcx>, Option<usize>) -> ArgAbi<'tcx, Ty<'tcx>>,
-    ) -> Self;
-    fn adjust_for_abi(&mut self, cx: &C, abi: SpecAbi);
-}
-
-impl<'tcx, C> FnAbiExt<'tcx, C> for call::FnAbi<'tcx, Ty<'tcx>>
-where
-    C: LayoutOf<Ty = Ty<'tcx>, TyLayout = TyLayout<'tcx>>
-        + HasDataLayout
-        + HasTargetSpec
-        + HasTyCtxt<'tcx>
-        + HasParamEnv<'tcx>,
-{
-    fn of_fn_ptr(cx: &C, sig: ty::PolyFnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> Self {
-        call::FnAbi::new_internal(cx, sig, extra_args, None, |ty, _| ArgAbi::new(cx.layout_of(ty)))
-    }
-
-    fn of_instance(cx: &C, instance: ty::Instance<'tcx>, extra_args: &[Ty<'tcx>]) -> Self {
-        let sig = instance.fn_sig_for_fn_abi(cx.tcx());
-
-        let caller_location = if instance.def.requires_caller_location(cx.tcx()) {
-            Some(cx.tcx().caller_location_ty())
-        } else {
-            None
-        };
-
-        call::FnAbi::new_internal(cx, sig, extra_args, caller_location, |ty, arg_idx| {
-            let mut layout = cx.layout_of(ty);
-            // Don't pass the vtable, it's not an argument of the virtual fn.
-            // Instead, pass just the data pointer, but give it the type `*const/mut dyn Trait`
-            // or `&/&mut dyn Trait` because this is special-cased elsewhere in codegen
-            if let (ty::InstanceDef::Virtual(..), Some(0)) = (&instance.def, arg_idx) {
-                let fat_pointer_ty = if layout.is_unsized() {
-                    // unsized `self` is passed as a pointer to `self`
-                    // FIXME (mikeyhew) change this to use &own if it is ever added to the language
-                    cx.tcx().mk_mut_ptr(layout.ty)
-                } else {
-                    match layout.abi {
-                        Abi::ScalarPair(..) => (),
-                        _ => bug!("receiver type has unsupported layout: {:?}", layout),
-                    }
-
-                    // In the case of Rc<Self>, we need to explicitly pass a *mut RcBox<Self>
-                    // with a Scalar (not ScalarPair) ABI. This is a hack that is understood
-                    // elsewhere in the compiler as a method on a `dyn Trait`.
-                    // To get the type `*mut RcBox<Self>`, we just keep unwrapping newtypes until we
-                    // get a built-in pointer type
-                    let mut fat_pointer_layout = layout;
-                    'descend_newtypes: while !fat_pointer_layout.ty.is_unsafe_ptr()
-                        && !fat_pointer_layout.ty.is_region_ptr()
-                    {
-                        for i in 0..fat_pointer_layout.fields.count() {
-                            let field_layout = fat_pointer_layout.field(cx, i);
-
-                            if !field_layout.is_zst() {
-                                fat_pointer_layout = field_layout;
-                                continue 'descend_newtypes;
-                            }
-                        }
-
-                        bug!("receiver has no non-zero-sized fields {:?}", fat_pointer_layout);
-                    }
-
-                    fat_pointer_layout.ty
-                };
-
-                // we now have a type like `*mut RcBox<dyn Trait>`
-                // change its layout to that of `*mut ()`, a thin pointer, but keep the same type
-                // this is understood as a special case elsewhere in the compiler
-                let unit_pointer_ty = cx.tcx().mk_mut_ptr(cx.tcx().mk_unit());
-                layout = cx.layout_of(unit_pointer_ty);
-                layout.ty = fat_pointer_ty;
-            }
-            ArgAbi::new(layout)
-        })
-    }
-
-    fn new_internal(
-        cx: &C,
-        sig: ty::PolyFnSig<'tcx>,
-        extra_args: &[Ty<'tcx>],
-        caller_location: Option<Ty<'tcx>>,
-        mk_arg_type: impl Fn(Ty<'tcx>, Option<usize>) -> ArgAbi<'tcx, Ty<'tcx>>,
-    ) -> Self {
-        debug!("FnAbi::new_internal({:?}, {:?})", sig, extra_args);
-
-        let sig = cx.tcx().normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig);
-
-        use rustc_target::spec::abi::Abi::*;
-        let conv = match cx.tcx().sess.target.target.adjust_abi(sig.abi) {
-            RustIntrinsic | PlatformIntrinsic | Rust | RustCall => Conv::Rust,
-
-            // It's the ABI's job to select this, not ours.
-            System => bug!("system abi should be selected elsewhere"),
-            EfiApi => bug!("eficall abi should be selected elsewhere"),
-
-            Stdcall => Conv::X86Stdcall,
-            Fastcall => Conv::X86Fastcall,
-            Vectorcall => Conv::X86VectorCall,
-            Thiscall => Conv::X86ThisCall,
-            C => Conv::C,
-            Unadjusted => Conv::C,
-            Win64 => Conv::X86_64Win64,
-            SysV64 => Conv::X86_64SysV,
-            Aapcs => Conv::ArmAapcs,
-            PtxKernel => Conv::PtxKernel,
-            Msp430Interrupt => Conv::Msp430Intr,
-            X86Interrupt => Conv::X86Intr,
-            AmdGpuKernel => Conv::AmdGpuKernel,
-
-            // These API constants ought to be more specific...
-            Cdecl => Conv::C,
-        };
-
-        let mut inputs = sig.inputs();
-        let extra_args = if sig.abi == RustCall {
-            assert!(!sig.c_variadic && extra_args.is_empty());
-
-            if let Some(input) = sig.inputs().last() {
-                if let ty::Tuple(tupled_arguments) = input.kind {
-                    inputs = &sig.inputs()[0..sig.inputs().len() - 1];
-                    tupled_arguments.iter().map(|k| k.expect_ty()).collect()
-                } else {
-                    bug!(
-                        "argument to function with \"rust-call\" ABI \
-                            is not a tuple"
-                    );
-                }
-            } else {
-                bug!(
-                    "argument to function with \"rust-call\" ABI \
-                        is not a tuple"
-                );
-            }
-        } else {
-            assert!(sig.c_variadic || extra_args.is_empty());
-            extra_args.to_vec()
-        };
-
-        let target = &cx.tcx().sess.target.target;
-        let win_x64_gnu =
-            target.target_os == "windows" && target.arch == "x86_64" && target.target_env == "gnu";
-        let linux_s390x =
-            target.target_os == "linux" && target.arch == "s390x" && target.target_env == "gnu";
-        let linux_sparc64 =
-            target.target_os == "linux" && target.arch == "sparc64" && target.target_env == "gnu";
-        let rust_abi = match sig.abi {
-            RustIntrinsic | PlatformIntrinsic | Rust | RustCall => true,
-            _ => false,
-        };
-
-        // Handle safe Rust thin and fat pointers.
-        let adjust_for_rust_scalar = |attrs: &mut ArgAttributes,
-                                      scalar: &Scalar,
-                                      layout: TyLayout<'tcx>,
-                                      offset: Size,
-                                      is_return: bool| {
-            // Booleans are always an i1 that needs to be zero-extended.
-            if scalar.is_bool() {
-                attrs.set(ArgAttribute::ZExt);
-                return;
-            }
-
-            // Only pointer types handled below.
-            if scalar.value != Pointer {
-                return;
-            }
-
-            if scalar.valid_range.start() < scalar.valid_range.end() {
-                if *scalar.valid_range.start() > 0 {
-                    attrs.set(ArgAttribute::NonNull);
-                }
-            }
-
-            if let Some(pointee) = layout.pointee_info_at(cx, offset) {
-                if let Some(kind) = pointee.safe {
-                    attrs.pointee_align = Some(pointee.align);
-
-                    // `Box` (`UniqueBorrowed`) are not necessarily dereferencable
-                    // for the entire duration of the function as they can be deallocated
-                    // any time. Set their valid size to 0.
-                    attrs.pointee_size = match kind {
-                        PointerKind::UniqueOwned => Size::ZERO,
-                        _ => pointee.size,
-                    };
-
-                    // `Box` pointer parameters never alias because ownership is transferred
-                    // `&mut` pointer parameters never alias other parameters,
-                    // or mutable global data
-                    //
-                    // `&T` where `T` contains no `UnsafeCell<U>` is immutable,
-                    // and can be marked as both `readonly` and `noalias`, as
-                    // LLVM's definition of `noalias` is based solely on memory
-                    // dependencies rather than pointer equality
-                    let no_alias = match kind {
-                        PointerKind::Shared => false,
-                        PointerKind::UniqueOwned => true,
-                        PointerKind::Frozen | PointerKind::UniqueBorrowed => !is_return,
-                    };
-                    if no_alias {
-                        attrs.set(ArgAttribute::NoAlias);
-                    }
-
-                    if kind == PointerKind::Frozen && !is_return {
-                        attrs.set(ArgAttribute::ReadOnly);
-                    }
-                }
-            }
-        };
-
-        let arg_of = |ty: Ty<'tcx>, arg_idx: Option<usize>| {
-            let is_return = arg_idx.is_none();
-            let mut arg = mk_arg_type(ty, arg_idx);
-            if arg.layout.is_zst() {
-                // For some forsaken reason, x86_64-pc-windows-gnu
-                // doesn't ignore zero-sized struct arguments.
-                // The same is true for s390x-unknown-linux-gnu
-                // and sparc64-unknown-linux-gnu.
-                if is_return || rust_abi || (!win_x64_gnu && !linux_s390x && !linux_sparc64) {
-                    arg.mode = PassMode::Ignore;
-                }
-            }
-
-            // FIXME(eddyb) other ABIs don't have logic for scalar pairs.
-            if !is_return && rust_abi {
-                if let Abi::ScalarPair(ref a, ref b) = arg.layout.abi {
-                    let mut a_attrs = ArgAttributes::new();
-                    let mut b_attrs = ArgAttributes::new();
-                    adjust_for_rust_scalar(&mut a_attrs, a, arg.layout, Size::ZERO, false);
-                    adjust_for_rust_scalar(
-                        &mut b_attrs,
-                        b,
-                        arg.layout,
-                        a.value.size(cx).align_to(b.value.align(cx).abi),
-                        false,
-                    );
-                    arg.mode = PassMode::Pair(a_attrs, b_attrs);
-                    return arg;
-                }
-            }
-
-            if let Abi::Scalar(ref scalar) = arg.layout.abi {
-                if let PassMode::Direct(ref mut attrs) = arg.mode {
-                    adjust_for_rust_scalar(attrs, scalar, arg.layout, Size::ZERO, is_return);
-                }
-            }
-
-            arg
-        };
-
-        let mut fn_abi = FnAbi {
-            ret: arg_of(sig.output(), None),
-            args: inputs
-                .iter()
-                .cloned()
-                .chain(extra_args)
-                .chain(caller_location)
-                .enumerate()
-                .map(|(i, ty)| arg_of(ty, Some(i)))
-                .collect(),
-            c_variadic: sig.c_variadic,
-            fixed_count: inputs.len(),
-            conv,
-        };
-        fn_abi.adjust_for_abi(cx, sig.abi);
-        fn_abi
-    }
-
-    fn adjust_for_abi(&mut self, cx: &C, abi: SpecAbi) {
-        if abi == SpecAbi::Unadjusted {
-            return;
-        }
-
-        if abi == SpecAbi::Rust
-            || abi == SpecAbi::RustCall
-            || abi == SpecAbi::RustIntrinsic
-            || abi == SpecAbi::PlatformIntrinsic
-        {
-            let fixup = |arg: &mut ArgAbi<'tcx, Ty<'tcx>>| {
-                if arg.is_ignore() {
-                    return;
-                }
-
-                match arg.layout.abi {
-                    Abi::Aggregate { .. } => {}
-
-                    // This is a fun case! The gist of what this is doing is
-                    // that we want callers and callees to always agree on the
-                    // ABI of how they pass SIMD arguments. If we were to *not*
-                    // make these arguments indirect then they'd be immediates
-                    // in LLVM, which means that they'd used whatever the
-                    // appropriate ABI is for the callee and the caller. That
-                    // means, for example, if the caller doesn't have AVX
-                    // enabled but the callee does, then passing an AVX argument
-                    // across this boundary would cause corrupt data to show up.
-                    //
-                    // This problem is fixed by unconditionally passing SIMD
-                    // arguments through memory between callers and callees
-                    // which should get them all to agree on ABI regardless of
-                    // target feature sets. Some more information about this
-                    // issue can be found in #44367.
-                    //
-                    // Note that the platform intrinsic ABI is exempt here as
-                    // that's how we connect up to LLVM and it's unstable
-                    // anyway, we control all calls to it in libstd.
-                    Abi::Vector { .. }
-                        if abi != SpecAbi::PlatformIntrinsic
-                            && cx.tcx().sess.target.target.options.simd_types_indirect =>
-                    {
-                        arg.make_indirect();
-                        return;
-                    }
-
-                    _ => return,
-                }
-
-                let size = arg.layout.size;
-                if arg.layout.is_unsized() || size > Pointer.size(cx) {
-                    arg.make_indirect();
-                } else {
-                    // We want to pass small aggregates as immediates, but using
-                    // a LLVM aggregate type for this leads to bad optimizations,
-                    // so we pick an appropriately sized integer type instead.
-                    arg.cast_to(Reg { kind: RegKind::Integer, size });
-                }
-            };
-            fixup(&mut self.ret);
-            for arg in &mut self.args {
-                fixup(arg);
-            }
-            if let PassMode::Indirect(ref mut attrs, _) = self.ret.mode {
-                attrs.set(ArgAttribute::StructRet);
-            }
-            return;
-        }
-
-        if let Err(msg) = self.adjust_for_cabi(cx, abi) {
-            cx.tcx().sess.fatal(&msg);
-        }
-    }
-}
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
deleted file mode 100644
index dae9f945ce0..00000000000
--- a/src/librustc/ty/mod.rs
+++ /dev/null
@@ -1,3169 +0,0 @@
-// ignore-tidy-filelength
-
-pub use self::fold::{TypeFoldable, TypeVisitor};
-pub use self::AssocItemContainer::*;
-pub use self::BorrowKind::*;
-pub use self::IntVarValue::*;
-pub use self::Variance::*;
-
-use crate::arena::Arena;
-use crate::hir::exports::ExportMap;
-use crate::hir::map as hir_map;
-
-use crate::ich::Fingerprint;
-use crate::ich::StableHashingContext;
-use crate::infer::canonical::Canonical;
-use crate::middle::cstore::CrateStoreDyn;
-use crate::middle::lang_items::{FnMutTraitLangItem, FnOnceTraitLangItem, FnTraitLangItem};
-use crate::middle::resolve_lifetime::ObjectLifetimeDefault;
-use crate::mir::interpret::ErrorHandled;
-use crate::mir::GeneratorLayout;
-use crate::mir::ReadOnlyBodyAndCache;
-use crate::session::DataTypeKind;
-use crate::traits::{self, Reveal};
-use crate::ty;
-use crate::ty::layout::VariantIdx;
-use crate::ty::subst::{InternalSubsts, Subst, SubstsRef};
-use crate::ty::util::{Discr, IntTypeExt};
-use crate::ty::walk::TypeWalker;
-use rustc_attr as attr;
-use rustc_data_structures::captures::Captures;
-use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::fx::FxIndexMap;
-use rustc_data_structures::sorted_map::SortedIndexMultiMap;
-use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
-use rustc_data_structures::sync::{self, par_iter, Lrc, ParallelIterator};
-use rustc_hir as hir;
-use rustc_hir::def::{CtorKind, CtorOf, DefKind, Namespace, Res};
-use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
-use rustc_hir::{Constness, GlobMap, Node, TraitMap};
-use rustc_index::vec::{Idx, IndexVec};
-use rustc_macros::HashStable;
-use rustc_serialize::{self, Encodable, Encoder};
-use rustc_span::hygiene::ExpnId;
-use rustc_span::symbol::{kw, sym, Symbol};
-use rustc_span::Span;
-use rustc_target::abi::Align;
-use syntax::ast::{self, Ident, Name};
-use syntax::node_id::{NodeId, NodeMap, NodeSet};
-
-use std::cell::RefCell;
-use std::cmp::{self, Ordering};
-use std::fmt;
-use std::hash::{Hash, Hasher};
-use std::ops::Deref;
-use std::ops::Range;
-use std::slice;
-use std::{mem, ptr};
-
-pub use self::sty::BoundRegion::*;
-pub use self::sty::InferTy::*;
-pub use self::sty::RegionKind;
-pub use self::sty::RegionKind::*;
-pub use self::sty::TyKind::*;
-pub use self::sty::{Binder, BoundTy, BoundTyKind, BoundVar, DebruijnIndex, INNERMOST};
-pub use self::sty::{BoundRegion, EarlyBoundRegion, FreeRegion, Region};
-pub use self::sty::{CanonicalPolyFnSig, FnSig, GenSig, PolyFnSig, PolyGenSig};
-pub use self::sty::{ClosureSubsts, GeneratorSubsts, TypeAndMut, UpvarSubsts};
-pub use self::sty::{Const, ConstKind, ExistentialProjection, PolyExistentialProjection};
-pub use self::sty::{ConstVid, FloatVid, IntVid, RegionVid, TyVid};
-pub use self::sty::{ExistentialPredicate, InferConst, InferTy, ParamConst, ParamTy, ProjectionTy};
-pub use self::sty::{ExistentialTraitRef, PolyExistentialTraitRef};
-pub use self::sty::{PolyTraitRef, TraitRef, TyKind};
-pub use crate::ty::diagnostics::*;
-
-pub use self::binding::BindingMode;
-pub use self::binding::BindingMode::*;
-
-pub use self::context::{keep_local, tls, FreeRegionInfo, TyCtxt};
-pub use self::context::{
-    CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, ResolvedOpaqueTy,
-    UserType, UserTypeAnnotationIndex,
-};
-pub use self::context::{
-    CtxtInterners, GeneratorInteriorTypeCause, GlobalCtxt, Lift, TypeckTables,
-};
-
-pub use self::instance::RESOLVE_INSTANCE;
-pub use self::instance::{Instance, InstanceDef};
-
-pub use self::trait_def::TraitDef;
-
-pub use self::query::queries;
-
-pub mod adjustment;
-pub mod binding;
-pub mod cast;
-#[macro_use]
-pub mod codec;
-pub mod _match;
-mod erase_regions;
-pub mod error;
-pub mod fast_reject;
-pub mod flags;
-pub mod fold;
-pub mod free_region_map;
-pub mod inhabitedness;
-pub mod layout;
-pub mod normalize_erasing_regions;
-pub mod outlives;
-pub mod print;
-pub mod query;
-pub mod relate;
-pub mod steal;
-pub mod subst;
-pub mod trait_def;
-pub mod util;
-pub mod walk;
-
-mod context;
-mod diagnostics;
-mod instance;
-mod structural_impls;
-mod sty;
-
-// Data types
-
-pub struct ResolverOutputs {
-    pub definitions: hir_map::Definitions,
-    pub cstore: Box<CrateStoreDyn>,
-    pub extern_crate_map: NodeMap<CrateNum>,
-    pub trait_map: TraitMap<NodeId>,
-    pub maybe_unused_trait_imports: NodeSet,
-    pub maybe_unused_extern_crates: Vec<(NodeId, Span)>,
-    pub export_map: ExportMap<NodeId>,
-    pub glob_map: GlobMap,
-    /// Extern prelude entries. The value is `true` if the entry was introduced
-    /// via `extern crate` item and not `--extern` option or compiler built-in.
-    pub extern_prelude: FxHashMap<Name, bool>,
-}
-
-#[derive(Clone, Copy, PartialEq, Eq, Debug, HashStable)]
-pub enum AssocItemContainer {
-    TraitContainer(DefId),
-    ImplContainer(DefId),
-}
-
-impl AssocItemContainer {
-    /// Asserts that this is the `DefId` of an associated item declared
-    /// in a trait, and returns the trait `DefId`.
-    pub fn assert_trait(&self) -> DefId {
-        match *self {
-            TraitContainer(id) => id,
-            _ => bug!("associated item has wrong container type: {:?}", self),
-        }
-    }
-
-    pub fn id(&self) -> DefId {
-        match *self {
-            TraitContainer(id) => id,
-            ImplContainer(id) => id,
-        }
-    }
-}
-
-/// The "header" of an impl is everything outside the body: a Self type, a trait
-/// ref (in the case of a trait impl), and a set of predicates (from the
-/// bounds / where-clauses).
-#[derive(Clone, Debug, TypeFoldable)]
-pub struct ImplHeader<'tcx> {
-    pub impl_def_id: DefId,
-    pub self_ty: Ty<'tcx>,
-    pub trait_ref: Option<TraitRef<'tcx>>,
-    pub predicates: Vec<Predicate<'tcx>>,
-}
-
-#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, HashStable)]
-pub enum ImplPolarity {
-    /// `impl Trait for Type`
-    Positive,
-    /// `impl !Trait for Type`
-    Negative,
-    /// `#[rustc_reservation_impl] impl Trait for Type`
-    ///
-    /// This is a "stability hack", not a real Rust feature.
-    /// See #64631 for details.
-    Reservation,
-}
-
-#[derive(Copy, Clone, Debug, PartialEq, HashStable)]
-pub struct AssocItem {
-    pub def_id: DefId,
-    #[stable_hasher(project(name))]
-    pub ident: Ident,
-    pub kind: AssocKind,
-    pub vis: Visibility,
-    pub defaultness: hir::Defaultness,
-    pub container: AssocItemContainer,
-
-    /// Whether this is a method with an explicit self
-    /// as its first argument, allowing method calls.
-    pub method_has_self_argument: bool,
-}
-
-#[derive(Copy, Clone, PartialEq, Debug, HashStable)]
-pub enum AssocKind {
-    Const,
-    Method,
-    OpaqueTy,
-    Type,
-}
-
-impl AssocKind {
-    pub fn suggestion_descr(&self) -> &'static str {
-        match self {
-            ty::AssocKind::Method => "method call",
-            ty::AssocKind::Type | ty::AssocKind::OpaqueTy => "associated type",
-            ty::AssocKind::Const => "associated constant",
-        }
-    }
-
-    pub fn namespace(&self) -> Namespace {
-        match *self {
-            ty::AssocKind::OpaqueTy | ty::AssocKind::Type => Namespace::TypeNS,
-            ty::AssocKind::Const | ty::AssocKind::Method => Namespace::ValueNS,
-        }
-    }
-}
-
-impl AssocItem {
-    pub fn def_kind(&self) -> DefKind {
-        match self.kind {
-            AssocKind::Const => DefKind::AssocConst,
-            AssocKind::Method => DefKind::Method,
-            AssocKind::Type => DefKind::AssocTy,
-            AssocKind::OpaqueTy => DefKind::AssocOpaqueTy,
-        }
-    }
-
-    /// Tests whether the associated item admits a non-trivial implementation
-    /// for !
-    pub fn relevant_for_never(&self) -> bool {
-        match self.kind {
-            AssocKind::OpaqueTy | AssocKind::Const | AssocKind::Type => true,
-            // FIXME(canndrew): Be more thorough here, check if any argument is uninhabited.
-            AssocKind::Method => !self.method_has_self_argument,
-        }
-    }
-
-    pub fn signature(&self, tcx: TyCtxt<'_>) -> String {
-        match self.kind {
-            ty::AssocKind::Method => {
-                // We skip the binder here because the binder would deanonymize all
-                // late-bound regions, and we don't want method signatures to show up
-                // `as for<'r> fn(&'r MyType)`.  Pretty-printing handles late-bound
-                // regions just fine, showing `fn(&MyType)`.
-                tcx.fn_sig(self.def_id).skip_binder().to_string()
-            }
-            ty::AssocKind::Type => format!("type {};", self.ident),
-            // FIXME(type_alias_impl_trait): we should print bounds here too.
-            ty::AssocKind::OpaqueTy => format!("type {};", self.ident),
-            ty::AssocKind::Const => {
-                format!("const {}: {:?};", self.ident, tcx.type_of(self.def_id))
-            }
-        }
-    }
-}
-
-/// A list of `ty::AssocItem`s in definition order that allows for efficient lookup by name.
-///
-/// When doing lookup by name, we try to postpone hygienic comparison for as long as possible since
-/// it is relatively expensive. Instead, items are indexed by `Symbol` and hygienic comparison is
-/// done only on items with the same name.
-#[derive(Debug, Clone, PartialEq, HashStable)]
-pub struct AssociatedItems {
-    items: SortedIndexMultiMap<u32, Symbol, ty::AssocItem>,
-}
-
-impl AssociatedItems {
-    /// Constructs an `AssociatedItems` map from a series of `ty::AssocItem`s in definition order.
-    pub fn new(items_in_def_order: impl IntoIterator<Item = ty::AssocItem>) -> Self {
-        let items = items_in_def_order.into_iter().map(|item| (item.ident.name, item)).collect();
-        AssociatedItems { items }
-    }
-
-    /// Returns a slice of associated items in the order they were defined.
-    ///
-    /// New code should avoid relying on definition order. If you need a particular associated item
-    /// for a known trait, make that trait a lang item instead of indexing this array.
-    pub fn in_definition_order(&self) -> impl '_ + Iterator<Item = &ty::AssocItem> {
-        self.items.iter().map(|(_, v)| v)
-    }
-
-    /// Returns an iterator over all associated items with the given name, ignoring hygiene.
-    pub fn filter_by_name_unhygienic(
-        &self,
-        name: Symbol,
-    ) -> impl '_ + Iterator<Item = &ty::AssocItem> {
-        self.items.get_by_key(&name)
-    }
-
-    /// Returns an iterator over all associated items with the given name.
-    ///
-    /// Multiple items may have the same name if they are in different `Namespace`s. For example,
-    /// an associated type can have the same name as a method. Use one of the `find_by_name_and_*`
-    /// methods below if you know which item you are looking for.
-    pub fn filter_by_name(
-        &'a self,
-        tcx: TyCtxt<'a>,
-        ident: Ident,
-        parent_def_id: DefId,
-    ) -> impl 'a + Iterator<Item = &'a ty::AssocItem> {
-        self.filter_by_name_unhygienic(ident.name)
-            .filter(move |item| tcx.hygienic_eq(ident, item.ident, parent_def_id))
-    }
-
-    /// Returns the associated item with the given name and `AssocKind`, if one exists.
-    pub fn find_by_name_and_kind(
-        &self,
-        tcx: TyCtxt<'_>,
-        ident: Ident,
-        kind: AssocKind,
-        parent_def_id: DefId,
-    ) -> Option<&ty::AssocItem> {
-        self.filter_by_name_unhygienic(ident.name)
-            .filter(|item| item.kind == kind)
-            .find(|item| tcx.hygienic_eq(ident, item.ident, parent_def_id))
-    }
-
-    /// Returns the associated item with the given name in the given `Namespace`, if one exists.
-    pub fn find_by_name_and_namespace(
-        &self,
-        tcx: TyCtxt<'_>,
-        ident: Ident,
-        ns: Namespace,
-        parent_def_id: DefId,
-    ) -> Option<&ty::AssocItem> {
-        self.filter_by_name_unhygienic(ident.name)
-            .filter(|item| item.kind.namespace() == ns)
-            .find(|item| tcx.hygienic_eq(ident, item.ident, parent_def_id))
-    }
-}
-
-#[derive(Clone, Debug, PartialEq, Eq, Copy, RustcEncodable, RustcDecodable, HashStable)]
-pub enum Visibility {
-    /// Visible everywhere (including in other crates).
-    Public,
-    /// Visible only in the given crate-local module.
-    Restricted(DefId),
-    /// Not visible anywhere in the local crate. This is the visibility of private external items.
-    Invisible,
-}
-
-pub trait DefIdTree: Copy {
-    fn parent(self, id: DefId) -> Option<DefId>;
-
-    fn is_descendant_of(self, mut descendant: DefId, ancestor: DefId) -> bool {
-        if descendant.krate != ancestor.krate {
-            return false;
-        }
-
-        while descendant != ancestor {
-            match self.parent(descendant) {
-                Some(parent) => descendant = parent,
-                None => return false,
-            }
-        }
-        true
-    }
-}
-
-impl<'tcx> DefIdTree for TyCtxt<'tcx> {
-    fn parent(self, id: DefId) -> Option<DefId> {
-        self.def_key(id).parent.map(|index| DefId { index: index, ..id })
-    }
-}
-
-impl Visibility {
-    pub fn from_hir(visibility: &hir::Visibility<'_>, id: hir::HirId, tcx: TyCtxt<'_>) -> Self {
-        match visibility.node {
-            hir::VisibilityKind::Public => Visibility::Public,
-            hir::VisibilityKind::Crate(_) => Visibility::Restricted(DefId::local(CRATE_DEF_INDEX)),
-            hir::VisibilityKind::Restricted { ref path, .. } => match path.res {
-                // If there is no resolution, `resolve` will have already reported an error, so
-                // assume that the visibility is public to avoid reporting more privacy errors.
-                Res::Err => Visibility::Public,
-                def => Visibility::Restricted(def.def_id()),
-            },
-            hir::VisibilityKind::Inherited => {
-                Visibility::Restricted(tcx.hir().get_module_parent(id))
-            }
-        }
-    }
-
-    /// Returns `true` if an item with this visibility is accessible from the given block.
-    pub fn is_accessible_from<T: DefIdTree>(self, module: DefId, tree: T) -> bool {
-        let restriction = match self {
-            // Public items are visible everywhere.
-            Visibility::Public => return true,
-            // Private items from other crates are visible nowhere.
-            Visibility::Invisible => return false,
-            // Restricted items are visible in an arbitrary local module.
-            Visibility::Restricted(other) if other.krate != module.krate => return false,
-            Visibility::Restricted(module) => module,
-        };
-
-        tree.is_descendant_of(module, restriction)
-    }
-
-    /// Returns `true` if this visibility is at least as accessible as the given visibility
-    pub fn is_at_least<T: DefIdTree>(self, vis: Visibility, tree: T) -> bool {
-        let vis_restriction = match vis {
-            Visibility::Public => return self == Visibility::Public,
-            Visibility::Invisible => return true,
-            Visibility::Restricted(module) => module,
-        };
-
-        self.is_accessible_from(vis_restriction, tree)
-    }
-
-    // Returns `true` if this item is visible anywhere in the local crate.
-    pub fn is_visible_locally(self) -> bool {
-        match self {
-            Visibility::Public => true,
-            Visibility::Restricted(def_id) => def_id.is_local(),
-            Visibility::Invisible => false,
-        }
-    }
-}
-
-#[derive(Copy, Clone, PartialEq, RustcDecodable, RustcEncodable, HashStable)]
-pub enum Variance {
-    Covariant,     // T<A> <: T<B> iff A <: B -- e.g., function return type
-    Invariant,     // T<A> <: T<B> iff B == A -- e.g., type of mutable cell
-    Contravariant, // T<A> <: T<B> iff B <: A -- e.g., function param type
-    Bivariant,     // T<A> <: T<B>            -- e.g., unused type parameter
-}
-
-/// The crate variances map is computed during typeck and contains the
-/// variance of every item in the local crate. You should not use it
-/// directly, because to do so will make your pass dependent on the
-/// HIR of every item in the local crate. Instead, use
-/// `tcx.variances_of()` to get the variance for a *particular*
-/// item.
-#[derive(HashStable)]
-pub struct CrateVariancesMap<'tcx> {
-    /// For each item with generics, maps to a vector of the variance
-    /// of its generics. If an item has no generics, it will have no
-    /// entry.
-    pub variances: FxHashMap<DefId, &'tcx [ty::Variance]>,
-}
-
-impl Variance {
-    /// `a.xform(b)` combines the variance of a context with the
-    /// variance of a type with the following meaning. If we are in a
-    /// context with variance `a`, and we encounter a type argument in
-    /// a position with variance `b`, then `a.xform(b)` is the new
-    /// variance with which the argument appears.
-    ///
-    /// Example 1:
-    ///
-    ///     *mut Vec<i32>
-    ///
-    /// Here, the "ambient" variance starts as covariant. `*mut T` is
-    /// invariant with respect to `T`, so the variance in which the
-    /// `Vec<i32>` appears is `Covariant.xform(Invariant)`, which
-    /// yields `Invariant`. Now, the type `Vec<T>` is covariant with
-    /// respect to its type argument `T`, and hence the variance of
-    /// the `i32` here is `Invariant.xform(Covariant)`, which results
-    /// (again) in `Invariant`.
-    ///
-    /// Example 2:
-    ///
-    ///     fn(*const Vec<i32>, *mut Vec<i32)
-    ///
-    /// The ambient variance is covariant. A `fn` type is
-    /// contravariant with respect to its parameters, so the variance
-    /// within which both pointer types appear is
-    /// `Covariant.xform(Contravariant)`, or `Contravariant`. `*const
-    /// T` is covariant with respect to `T`, so the variance within
-    /// which the first `Vec<i32>` appears is
-    /// `Contravariant.xform(Covariant)` or `Contravariant`. The same
-    /// is true for its `i32` argument. In the `*mut T` case, the
-    /// variance of `Vec<i32>` is `Contravariant.xform(Invariant)`,
-    /// and hence the outermost type is `Invariant` with respect to
-    /// `Vec<i32>` (and its `i32` argument).
-    ///
-    /// Source: Figure 1 of "Taming the Wildcards:
-    /// Combining Definition- and Use-Site Variance" published in PLDI'11.
-    pub fn xform(self, v: ty::Variance) -> ty::Variance {
-        match (self, v) {
-            // Figure 1, column 1.
-            (ty::Covariant, ty::Covariant) => ty::Covariant,
-            (ty::Covariant, ty::Contravariant) => ty::Contravariant,
-            (ty::Covariant, ty::Invariant) => ty::Invariant,
-            (ty::Covariant, ty::Bivariant) => ty::Bivariant,
-
-            // Figure 1, column 2.
-            (ty::Contravariant, ty::Covariant) => ty::Contravariant,
-            (ty::Contravariant, ty::Contravariant) => ty::Covariant,
-            (ty::Contravariant, ty::Invariant) => ty::Invariant,
-            (ty::Contravariant, ty::Bivariant) => ty::Bivariant,
-
-            // Figure 1, column 3.
-            (ty::Invariant, _) => ty::Invariant,
-
-            // Figure 1, column 4.
-            (ty::Bivariant, _) => ty::Bivariant,
-        }
-    }
-}
-
-// Contains information needed to resolve types and (in the future) look up
-// the types of AST nodes.
-#[derive(Copy, Clone, PartialEq, Eq, Hash)]
-pub struct CReaderCacheKey {
-    pub cnum: CrateNum,
-    pub pos: usize,
-}
-
-// Flags that we track on types. These flags are propagated upwards
-// through the type during type construction, so that we can quickly
-// check whether the type has various kinds of types in it without
-// recursing over the type itself.
-bitflags! {
-    pub struct TypeFlags: u32 {
-        const HAS_PARAMS         = 1 << 0;
-        const HAS_TY_INFER       = 1 << 1;
-        const HAS_RE_INFER       = 1 << 2;
-        const HAS_RE_PLACEHOLDER = 1 << 3;
-
-        /// Does this have any `ReEarlyBound` regions? Used to
-        /// determine whether substitition is required, since those
-        /// represent regions that are bound in a `ty::Generics` and
-        /// hence may be substituted.
-        const HAS_RE_EARLY_BOUND = 1 << 4;
-
-        /// Does this have any region that "appears free" in the type?
-        /// Basically anything but `ReLateBound` and `ReErased`.
-        const HAS_FREE_REGIONS   = 1 << 5;
-
-        /// Is an error type reachable?
-        const HAS_TY_ERR         = 1 << 6;
-        const HAS_PROJECTION     = 1 << 7;
-
-        // FIXME: Rename this to the actual property since it's used for generators too
-        const HAS_TY_CLOSURE     = 1 << 8;
-
-        /// `true` if there are "names" of types and regions and so forth
-        /// that are local to a particular fn
-        const HAS_FREE_LOCAL_NAMES = 1 << 9;
-
-        /// Present if the type belongs in a local type context.
-        /// Only set for Infer other than Fresh.
-        const KEEP_IN_LOCAL_TCX  = 1 << 10;
-
-        /// Does this have any `ReLateBound` regions? Used to check
-        /// if a global bound is safe to evaluate.
-        const HAS_RE_LATE_BOUND  = 1 << 11;
-
-        /// Does this have any `ReErased` regions?
-        const HAS_RE_ERASED  = 1 << 12;
-
-        const HAS_TY_PLACEHOLDER = 1 << 13;
-
-        const HAS_CT_INFER       = 1 << 14;
-        const HAS_CT_PLACEHOLDER = 1 << 15;
-        /// Does this have any [Opaque] types.
-        const HAS_TY_OPAQUE      = 1 << 16;
-
-        const NEEDS_SUBST        = TypeFlags::HAS_PARAMS.bits |
-                                   TypeFlags::HAS_RE_EARLY_BOUND.bits;
-
-        /// Flags representing the nominal content of a type,
-        /// computed by FlagsComputation. If you add a new nominal
-        /// flag, it should be added here too.
-        const NOMINAL_FLAGS     = TypeFlags::HAS_PARAMS.bits |
-                                  TypeFlags::HAS_TY_INFER.bits |
-                                  TypeFlags::HAS_RE_INFER.bits |
-                                  TypeFlags::HAS_RE_PLACEHOLDER.bits |
-                                  TypeFlags::HAS_RE_EARLY_BOUND.bits |
-                                  TypeFlags::HAS_FREE_REGIONS.bits |
-                                  TypeFlags::HAS_TY_ERR.bits |
-                                  TypeFlags::HAS_PROJECTION.bits |
-                                  TypeFlags::HAS_TY_CLOSURE.bits |
-                                  TypeFlags::HAS_FREE_LOCAL_NAMES.bits |
-                                  TypeFlags::KEEP_IN_LOCAL_TCX.bits |
-                                  TypeFlags::HAS_RE_LATE_BOUND.bits |
-                                  TypeFlags::HAS_RE_ERASED.bits |
-                                  TypeFlags::HAS_TY_PLACEHOLDER.bits |
-                                  TypeFlags::HAS_CT_INFER.bits |
-                                  TypeFlags::HAS_CT_PLACEHOLDER.bits |
-                                  TypeFlags::HAS_TY_OPAQUE.bits;
-    }
-}
-
-#[allow(rustc::usage_of_ty_tykind)]
-pub struct TyS<'tcx> {
-    pub kind: TyKind<'tcx>,
-    pub flags: TypeFlags,
-
-    /// This is a kind of confusing thing: it stores the smallest
-    /// binder such that
-    ///
-    /// (a) the binder itself captures nothing but
-    /// (b) all the late-bound things within the type are captured
-    ///     by some sub-binder.
-    ///
-    /// So, for a type without any late-bound things, like `u32`, this
-    /// will be *innermost*, because that is the innermost binder that
-    /// captures nothing. But for a type `&'D u32`, where `'D` is a
-    /// late-bound region with De Bruijn index `D`, this would be `D + 1`
-    /// -- the binder itself does not capture `D`, but `D` is captured
-    /// by an inner binder.
-    ///
-    /// We call this concept an "exclusive" binder `D` because all
-    /// De Bruijn indices within the type are contained within `0..D`
-    /// (exclusive).
-    outer_exclusive_binder: ty::DebruijnIndex,
-}
-
-// `TyS` is used a lot. Make sure it doesn't unintentionally get bigger.
-#[cfg(target_arch = "x86_64")]
-static_assert_size!(TyS<'_>, 32);
-
-impl<'tcx> Ord for TyS<'tcx> {
-    fn cmp(&self, other: &TyS<'tcx>) -> Ordering {
-        self.kind.cmp(&other.kind)
-    }
-}
-
-impl<'tcx> PartialOrd for TyS<'tcx> {
-    fn partial_cmp(&self, other: &TyS<'tcx>) -> Option<Ordering> {
-        Some(self.kind.cmp(&other.kind))
-    }
-}
-
-impl<'tcx> PartialEq for TyS<'tcx> {
-    #[inline]
-    fn eq(&self, other: &TyS<'tcx>) -> bool {
-        ptr::eq(self, other)
-    }
-}
-impl<'tcx> Eq for TyS<'tcx> {}
-
-impl<'tcx> Hash for TyS<'tcx> {
-    fn hash<H: Hasher>(&self, s: &mut H) {
-        (self as *const TyS<'_>).hash(s)
-    }
-}
-
-impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ty::TyS<'tcx> {
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        let ty::TyS {
-            ref kind,
-
-            // The other fields just provide fast access to information that is
-            // also contained in `kind`, so no need to hash them.
-            flags: _,
-
-            outer_exclusive_binder: _,
-        } = *self;
-
-        kind.hash_stable(hcx, hasher);
-    }
-}
-
-#[rustc_diagnostic_item = "Ty"]
-pub type Ty<'tcx> = &'tcx TyS<'tcx>;
-
-impl<'tcx> rustc_serialize::UseSpecializedEncodable for Ty<'tcx> {}
-impl<'tcx> rustc_serialize::UseSpecializedDecodable for Ty<'tcx> {}
-
-pub type CanonicalTy<'tcx> = Canonical<'tcx, Ty<'tcx>>;
-
-extern "C" {
-    /// A dummy type used to force `List` to be unsized while not requiring references to it be wide
-    /// pointers.
-    type OpaqueListContents;
-}
-
-/// A wrapper for slices with the additional invariant
-/// that the slice is interned and no other slice with
-/// the same contents can exist in the same context.
-/// This means we can use pointer for both
-/// equality comparisons and hashing.
-/// Note: `Slice` was already taken by the `Ty`.
-#[repr(C)]
-pub struct List<T> {
-    len: usize,
-    data: [T; 0],
-    opaque: OpaqueListContents,
-}
-
-unsafe impl<T: Sync> Sync for List<T> {}
-
-impl<T: Copy> List<T> {
-    #[inline]
-    fn from_arena<'tcx>(arena: &'tcx Arena<'tcx>, slice: &[T]) -> &'tcx List<T> {
-        assert!(!mem::needs_drop::<T>());
-        assert!(mem::size_of::<T>() != 0);
-        assert!(slice.len() != 0);
-
-        // Align up the size of the len (usize) field
-        let align = mem::align_of::<T>();
-        let align_mask = align - 1;
-        let offset = mem::size_of::<usize>();
-        let offset = (offset + align_mask) & !align_mask;
-
-        let size = offset + slice.len() * mem::size_of::<T>();
-
-        let mem = arena
-            .dropless
-            .alloc_raw(size, cmp::max(mem::align_of::<T>(), mem::align_of::<usize>()));
-        unsafe {
-            let result = &mut *(mem.as_mut_ptr() as *mut List<T>);
-            // Write the length
-            result.len = slice.len();
-
-            // Write the elements
-            let arena_slice = slice::from_raw_parts_mut(result.data.as_mut_ptr(), result.len);
-            arena_slice.copy_from_slice(slice);
-
-            result
-        }
-    }
-}
-
-impl<T: fmt::Debug> fmt::Debug for List<T> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        (**self).fmt(f)
-    }
-}
-
-impl<T: Encodable> Encodable for List<T> {
-    #[inline]
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
-        (**self).encode(s)
-    }
-}
-
-impl<T> Ord for List<T>
-where
-    T: Ord,
-{
-    fn cmp(&self, other: &List<T>) -> Ordering {
-        if self == other { Ordering::Equal } else { <[T] as Ord>::cmp(&**self, &**other) }
-    }
-}
-
-impl<T> PartialOrd for List<T>
-where
-    T: PartialOrd,
-{
-    fn partial_cmp(&self, other: &List<T>) -> Option<Ordering> {
-        if self == other {
-            Some(Ordering::Equal)
-        } else {
-            <[T] as PartialOrd>::partial_cmp(&**self, &**other)
-        }
-    }
-}
-
-impl<T: PartialEq> PartialEq for List<T> {
-    #[inline]
-    fn eq(&self, other: &List<T>) -> bool {
-        ptr::eq(self, other)
-    }
-}
-impl<T: Eq> Eq for List<T> {}
-
-impl<T> Hash for List<T> {
-    #[inline]
-    fn hash<H: Hasher>(&self, s: &mut H) {
-        (self as *const List<T>).hash(s)
-    }
-}
-
-impl<T> Deref for List<T> {
-    type Target = [T];
-    #[inline(always)]
-    fn deref(&self) -> &[T] {
-        self.as_ref()
-    }
-}
-
-impl<T> AsRef<[T]> for List<T> {
-    #[inline(always)]
-    fn as_ref(&self) -> &[T] {
-        unsafe { slice::from_raw_parts(self.data.as_ptr(), self.len) }
-    }
-}
-
-impl<'a, T> IntoIterator for &'a List<T> {
-    type Item = &'a T;
-    type IntoIter = <&'a [T] as IntoIterator>::IntoIter;
-    #[inline(always)]
-    fn into_iter(self) -> Self::IntoIter {
-        self[..].iter()
-    }
-}
-
-impl<'tcx> rustc_serialize::UseSpecializedDecodable for &'tcx List<Ty<'tcx>> {}
-
-impl<T> List<T> {
-    #[inline(always)]
-    pub fn empty<'a>() -> &'a List<T> {
-        #[repr(align(64), C)]
-        struct EmptySlice([u8; 64]);
-        static EMPTY_SLICE: EmptySlice = EmptySlice([0; 64]);
-        assert!(mem::align_of::<T>() <= 64);
-        unsafe { &*(&EMPTY_SLICE as *const _ as *const List<T>) }
-    }
-}
-
-#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
-pub struct UpvarPath {
-    pub hir_id: hir::HirId,
-}
-
-/// Upvars do not get their own `NodeId`. Instead, we use the pair of
-/// the original var ID (that is, the root variable that is referenced
-/// by the upvar) and the ID of the closure expression.
-#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
-pub struct UpvarId {
-    pub var_path: UpvarPath,
-    pub closure_expr_id: LocalDefId,
-}
-
-#[derive(Clone, PartialEq, Debug, RustcEncodable, RustcDecodable, Copy, HashStable)]
-pub enum BorrowKind {
-    /// Data must be immutable and is aliasable.
-    ImmBorrow,
-
-    /// Data must be immutable but not aliasable. This kind of borrow
-    /// cannot currently be expressed by the user and is used only in
-    /// implicit closure bindings. It is needed when the closure
-    /// is borrowing or mutating a mutable referent, e.g.:
-    ///
-    ///    let x: &mut isize = ...;
-    ///    let y = || *x += 5;
-    ///
-    /// If we were to try to translate this closure into a more explicit
-    /// form, we'd encounter an error with the code as written:
-    ///
-    ///    struct Env { x: & &mut isize }
-    ///    let x: &mut isize = ...;
-    ///    let y = (&mut Env { &x }, fn_ptr);  // Closure is pair of env and fn
-    ///    fn fn_ptr(env: &mut Env) { **env.x += 5; }
-    ///
-    /// This is then illegal because you cannot mutate a `&mut` found
-    /// in an aliasable location. To solve, you'd have to translate with
-    /// an `&mut` borrow:
-    ///
-    ///    struct Env { x: & &mut isize }
-    ///    let x: &mut isize = ...;
-    ///    let y = (&mut Env { &mut x }, fn_ptr); // changed from &x to &mut x
-    ///    fn fn_ptr(env: &mut Env) { **env.x += 5; }
-    ///
-    /// Now the assignment to `**env.x` is legal, but creating a
-    /// mutable pointer to `x` is not because `x` is not mutable. We
-    /// could fix this by declaring `x` as `let mut x`. This is ok in
-    /// user code, if awkward, but extra weird for closures, since the
-    /// borrow is hidden.
-    ///
-    /// So we introduce a "unique imm" borrow -- the referent is
-    /// immutable, but not aliasable. This solves the problem. For
-    /// simplicity, we don't give users the way to express this
-    /// borrow, it's just used when translating closures.
-    UniqueImmBorrow,
-
-    /// Data is mutable and not aliasable.
-    MutBorrow,
-}
-
-/// Information describing the capture of an upvar. This is computed
-/// during `typeck`, specifically by `regionck`.
-#[derive(PartialEq, Clone, Debug, Copy, RustcEncodable, RustcDecodable, HashStable)]
-pub enum UpvarCapture<'tcx> {
-    /// Upvar is captured by value. This is always true when the
-    /// closure is labeled `move`, but can also be true in other cases
-    /// depending on inference.
-    ByValue,
-
-    /// Upvar is captured by reference.
-    ByRef(UpvarBorrow<'tcx>),
-}
-
-#[derive(PartialEq, Clone, Copy, RustcEncodable, RustcDecodable, HashStable)]
-pub struct UpvarBorrow<'tcx> {
-    /// The kind of borrow: by-ref upvars have access to shared
-    /// immutable borrows, which are not part of the normal language
-    /// syntax.
-    pub kind: BorrowKind,
-
-    /// Region of the resulting reference.
-    pub region: ty::Region<'tcx>,
-}
-
-pub type UpvarListMap = FxHashMap<DefId, FxIndexMap<hir::HirId, UpvarId>>;
-pub type UpvarCaptureMap<'tcx> = FxHashMap<UpvarId, UpvarCapture<'tcx>>;
-
-#[derive(Clone, Copy, PartialEq, Eq)]
-pub enum IntVarValue {
-    IntType(ast::IntTy),
-    UintType(ast::UintTy),
-}
-
-#[derive(Clone, Copy, PartialEq, Eq)]
-pub struct FloatVarValue(pub ast::FloatTy);
-
-impl ty::EarlyBoundRegion {
-    pub fn to_bound_region(&self) -> ty::BoundRegion {
-        ty::BoundRegion::BrNamed(self.def_id, self.name)
-    }
-
-    /// Does this early bound region have a name? Early bound regions normally
-    /// always have names except when using anonymous lifetimes (`'_`).
-    pub fn has_name(&self) -> bool {
-        self.name != kw::UnderscoreLifetime
-    }
-}
-
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
-pub enum GenericParamDefKind {
-    Lifetime,
-    Type {
-        has_default: bool,
-        object_lifetime_default: ObjectLifetimeDefault,
-        synthetic: Option<hir::SyntheticTyParamKind>,
-    },
-    Const,
-}
-
-impl GenericParamDefKind {
-    pub fn descr(&self) -> &'static str {
-        match self {
-            GenericParamDefKind::Lifetime => "lifetime",
-            GenericParamDefKind::Type { .. } => "type",
-            GenericParamDefKind::Const => "constant",
-        }
-    }
-}
-
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
-pub struct GenericParamDef {
-    pub name: Symbol,
-    pub def_id: DefId,
-    pub index: u32,
-
-    /// `pure_wrt_drop`, set by the (unsafe) `#[may_dangle]` attribute
-    /// on generic parameter `'a`/`T`, asserts data behind the parameter
-    /// `'a`/`T` won't be accessed during the parent type's `Drop` impl.
-    pub pure_wrt_drop: bool,
-
-    pub kind: GenericParamDefKind,
-}
-
-impl GenericParamDef {
-    pub fn to_early_bound_region_data(&self) -> ty::EarlyBoundRegion {
-        if let GenericParamDefKind::Lifetime = self.kind {
-            ty::EarlyBoundRegion { def_id: self.def_id, index: self.index, name: self.name }
-        } else {
-            bug!("cannot convert a non-lifetime parameter def to an early bound region")
-        }
-    }
-
-    pub fn to_bound_region(&self) -> ty::BoundRegion {
-        if let GenericParamDefKind::Lifetime = self.kind {
-            self.to_early_bound_region_data().to_bound_region()
-        } else {
-            bug!("cannot convert a non-lifetime parameter def to an early bound region")
-        }
-    }
-}
-
-#[derive(Default)]
-pub struct GenericParamCount {
-    pub lifetimes: usize,
-    pub types: usize,
-    pub consts: usize,
-}
-
-/// Information about the formal type/lifetime parameters associated
-/// with an item or method. Analogous to `hir::Generics`.
-///
-/// The ordering of parameters is the same as in `Subst` (excluding child generics):
-/// `Self` (optionally), `Lifetime` params..., `Type` params...
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
-pub struct Generics {
-    pub parent: Option<DefId>,
-    pub parent_count: usize,
-    pub params: Vec<GenericParamDef>,
-
-    /// Reverse map to the `index` field of each `GenericParamDef`.
-    #[stable_hasher(ignore)]
-    pub param_def_id_to_index: FxHashMap<DefId, u32>,
-
-    pub has_self: bool,
-    pub has_late_bound_regions: Option<Span>,
-}
-
-impl<'tcx> Generics {
-    pub fn count(&self) -> usize {
-        self.parent_count + self.params.len()
-    }
-
-    pub fn own_counts(&self) -> GenericParamCount {
-        // We could cache this as a property of `GenericParamCount`, but
-        // the aim is to refactor this away entirely eventually and the
-        // presence of this method will be a constant reminder.
-        let mut own_counts: GenericParamCount = Default::default();
-
-        for param in &self.params {
-            match param.kind {
-                GenericParamDefKind::Lifetime => own_counts.lifetimes += 1,
-                GenericParamDefKind::Type { .. } => own_counts.types += 1,
-                GenericParamDefKind::Const => own_counts.consts += 1,
-            };
-        }
-
-        own_counts
-    }
-
-    pub fn requires_monomorphization(&self, tcx: TyCtxt<'tcx>) -> bool {
-        if self.own_requires_monomorphization() {
-            return true;
-        }
-
-        if let Some(parent_def_id) = self.parent {
-            let parent = tcx.generics_of(parent_def_id);
-            parent.requires_monomorphization(tcx)
-        } else {
-            false
-        }
-    }
-
-    pub fn own_requires_monomorphization(&self) -> bool {
-        for param in &self.params {
-            match param.kind {
-                GenericParamDefKind::Type { .. } | GenericParamDefKind::Const => return true,
-                GenericParamDefKind::Lifetime => {}
-            }
-        }
-        false
-    }
-
-    pub fn region_param(
-        &'tcx self,
-        param: &EarlyBoundRegion,
-        tcx: TyCtxt<'tcx>,
-    ) -> &'tcx GenericParamDef {
-        if let Some(index) = param.index.checked_sub(self.parent_count as u32) {
-            let param = &self.params[index as usize];
-            match param.kind {
-                GenericParamDefKind::Lifetime => param,
-                _ => bug!("expected lifetime parameter, but found another generic parameter"),
-            }
-        } else {
-            tcx.generics_of(self.parent.expect("parent_count > 0 but no parent?"))
-                .region_param(param, tcx)
-        }
-    }
-
-    /// Returns the `GenericParamDef` associated with this `ParamTy`.
-    pub fn type_param(&'tcx self, param: &ParamTy, tcx: TyCtxt<'tcx>) -> &'tcx GenericParamDef {
-        if let Some(index) = param.index.checked_sub(self.parent_count as u32) {
-            let param = &self.params[index as usize];
-            match param.kind {
-                GenericParamDefKind::Type { .. } => param,
-                _ => bug!("expected type parameter, but found another generic parameter"),
-            }
-        } else {
-            tcx.generics_of(self.parent.expect("parent_count > 0 but no parent?"))
-                .type_param(param, tcx)
-        }
-    }
-
-    /// Returns the `ConstParameterDef` associated with this `ParamConst`.
-    pub fn const_param(&'tcx self, param: &ParamConst, tcx: TyCtxt<'tcx>) -> &GenericParamDef {
-        if let Some(index) = param.index.checked_sub(self.parent_count as u32) {
-            let param = &self.params[index as usize];
-            match param.kind {
-                GenericParamDefKind::Const => param,
-                _ => bug!("expected const parameter, but found another generic parameter"),
-            }
-        } else {
-            tcx.generics_of(self.parent.expect("parent_count>0 but no parent?"))
-                .const_param(param, tcx)
-        }
-    }
-}
-
-/// Bounds on generics.
-#[derive(Copy, Clone, Default, Debug, RustcEncodable, RustcDecodable, HashStable)]
-pub struct GenericPredicates<'tcx> {
-    pub parent: Option<DefId>,
-    pub predicates: &'tcx [(Predicate<'tcx>, Span)],
-}
-
-impl<'tcx> GenericPredicates<'tcx> {
-    pub fn instantiate(
-        &self,
-        tcx: TyCtxt<'tcx>,
-        substs: SubstsRef<'tcx>,
-    ) -> InstantiatedPredicates<'tcx> {
-        let mut instantiated = InstantiatedPredicates::empty();
-        self.instantiate_into(tcx, &mut instantiated, substs);
-        instantiated
-    }
-
-    pub fn instantiate_own(
-        &self,
-        tcx: TyCtxt<'tcx>,
-        substs: SubstsRef<'tcx>,
-    ) -> InstantiatedPredicates<'tcx> {
-        InstantiatedPredicates {
-            predicates: self.predicates.iter().map(|(p, _)| p.subst(tcx, substs)).collect(),
-            spans: self.predicates.iter().map(|(_, sp)| *sp).collect(),
-        }
-    }
-
-    fn instantiate_into(
-        &self,
-        tcx: TyCtxt<'tcx>,
-        instantiated: &mut InstantiatedPredicates<'tcx>,
-        substs: SubstsRef<'tcx>,
-    ) {
-        if let Some(def_id) = self.parent {
-            tcx.predicates_of(def_id).instantiate_into(tcx, instantiated, substs);
-        }
-        instantiated.predicates.extend(self.predicates.iter().map(|(p, _)| p.subst(tcx, substs)));
-        instantiated.spans.extend(self.predicates.iter().map(|(_, sp)| *sp));
-    }
-
-    pub fn instantiate_identity(&self, tcx: TyCtxt<'tcx>) -> InstantiatedPredicates<'tcx> {
-        let mut instantiated = InstantiatedPredicates::empty();
-        self.instantiate_identity_into(tcx, &mut instantiated);
-        instantiated
-    }
-
-    fn instantiate_identity_into(
-        &self,
-        tcx: TyCtxt<'tcx>,
-        instantiated: &mut InstantiatedPredicates<'tcx>,
-    ) {
-        if let Some(def_id) = self.parent {
-            tcx.predicates_of(def_id).instantiate_identity_into(tcx, instantiated);
-        }
-        instantiated.predicates.extend(self.predicates.iter().map(|(p, _)| p));
-        instantiated.spans.extend(self.predicates.iter().map(|(_, s)| s));
-    }
-
-    pub fn instantiate_supertrait(
-        &self,
-        tcx: TyCtxt<'tcx>,
-        poly_trait_ref: &ty::PolyTraitRef<'tcx>,
-    ) -> InstantiatedPredicates<'tcx> {
-        assert_eq!(self.parent, None);
-        InstantiatedPredicates {
-            predicates: self
-                .predicates
-                .iter()
-                .map(|(pred, _)| pred.subst_supertrait(tcx, poly_trait_ref))
-                .collect(),
-            spans: self.predicates.iter().map(|(_, sp)| *sp).collect(),
-        }
-    }
-}
-
-#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
-#[derive(HashStable, TypeFoldable)]
-pub enum Predicate<'tcx> {
-    /// Corresponds to `where Foo: Bar<A, B, C>`. `Foo` here would be
-    /// the `Self` type of the trait reference and `A`, `B`, and `C`
-    /// would be the type parameters.
-    ///
-    /// A trait predicate will have `Constness::Const` if it originates
-    /// from a bound on a `const fn` without the `?const` opt-out (e.g.,
-    /// `const fn foobar<Foo: Bar>() {}`).
-    Trait(PolyTraitPredicate<'tcx>, Constness),
-
-    /// `where 'a: 'b`
-    RegionOutlives(PolyRegionOutlivesPredicate<'tcx>),
-
-    /// `where T: 'a`
-    TypeOutlives(PolyTypeOutlivesPredicate<'tcx>),
-
-    /// `where <T as TraitRef>::Name == X`, approximately.
-    /// See the `ProjectionPredicate` struct for details.
-    Projection(PolyProjectionPredicate<'tcx>),
-
-    /// No syntax: `T` well-formed.
-    WellFormed(Ty<'tcx>),
-
-    /// Trait must be object-safe.
-    ObjectSafe(DefId),
-
-    /// No direct syntax. May be thought of as `where T: FnFoo<...>`
-    /// for some substitutions `...` and `T` being a closure type.
-    /// Satisfied (or refuted) once we know the closure's kind.
-    ClosureKind(DefId, SubstsRef<'tcx>, ClosureKind),
-
-    /// `T1 <: T2`
-    Subtype(PolySubtypePredicate<'tcx>),
-
-    /// Constant initializer must evaluate successfully.
-    ConstEvaluatable(DefId, SubstsRef<'tcx>),
-}
-
-/// The crate outlives map is computed during typeck and contains the
-/// outlives of every item in the local crate. You should not use it
-/// directly, because to do so will make your pass dependent on the
-/// HIR of every item in the local crate. Instead, use
-/// `tcx.inferred_outlives_of()` to get the outlives for a *particular*
-/// item.
-#[derive(HashStable)]
-pub struct CratePredicatesMap<'tcx> {
-    /// For each struct with outlive bounds, maps to a vector of the
-    /// predicate of its outlive bounds. If an item has no outlives
-    /// bounds, it will have no entry.
-    pub predicates: FxHashMap<DefId, &'tcx [(ty::Predicate<'tcx>, Span)]>,
-}
-
-impl<'tcx> AsRef<Predicate<'tcx>> for Predicate<'tcx> {
-    fn as_ref(&self) -> &Predicate<'tcx> {
-        self
-    }
-}
-
-impl<'tcx> Predicate<'tcx> {
-    /// Performs a substitution suitable for going from a
-    /// poly-trait-ref to supertraits that must hold if that
-    /// poly-trait-ref holds. This is slightly different from a normal
-    /// substitution in terms of what happens with bound regions. See
-    /// lengthy comment below for details.
-    pub fn subst_supertrait(
-        &self,
-        tcx: TyCtxt<'tcx>,
-        trait_ref: &ty::PolyTraitRef<'tcx>,
-    ) -> ty::Predicate<'tcx> {
-        // The interaction between HRTB and supertraits is not entirely
-        // obvious. Let me walk you (and myself) through an example.
-        //
-        // Let's start with an easy case. Consider two traits:
-        //
-        //     trait Foo<'a>: Bar<'a,'a> { }
-        //     trait Bar<'b,'c> { }
-        //
-        // Now, if we have a trait reference `for<'x> T: Foo<'x>`, then
-        // we can deduce that `for<'x> T: Bar<'x,'x>`. Basically, if we
-        // knew that `Foo<'x>` (for any 'x) then we also know that
-        // `Bar<'x,'x>` (for any 'x). This more-or-less falls out from
-        // normal substitution.
-        //
-        // In terms of why this is sound, the idea is that whenever there
-        // is an impl of `T:Foo<'a>`, it must show that `T:Bar<'a,'a>`
-        // holds.  So if there is an impl of `T:Foo<'a>` that applies to
-        // all `'a`, then we must know that `T:Bar<'a,'a>` holds for all
-        // `'a`.
-        //
-        // Another example to be careful of is this:
-        //
-        //     trait Foo1<'a>: for<'b> Bar1<'a,'b> { }
-        //     trait Bar1<'b,'c> { }
-        //
-        // Here, if we have `for<'x> T: Foo1<'x>`, then what do we know?
-        // The answer is that we know `for<'x,'b> T: Bar1<'x,'b>`. The
-        // reason is similar to the previous example: any impl of
-        // `T:Foo1<'x>` must show that `for<'b> T: Bar1<'x, 'b>`.  So
-        // basically we would want to collapse the bound lifetimes from
-        // the input (`trait_ref`) and the supertraits.
-        //
-        // To achieve this in practice is fairly straightforward. Let's
-        // consider the more complicated scenario:
-        //
-        // - We start out with `for<'x> T: Foo1<'x>`. In this case, `'x`
-        //   has a De Bruijn index of 1. We want to produce `for<'x,'b> T: Bar1<'x,'b>`,
-        //   where both `'x` and `'b` would have a DB index of 1.
-        //   The substitution from the input trait-ref is therefore going to be
-        //   `'a => 'x` (where `'x` has a DB index of 1).
-        // - The super-trait-ref is `for<'b> Bar1<'a,'b>`, where `'a` is an
-        //   early-bound parameter and `'b' is a late-bound parameter with a
-        //   DB index of 1.
-        // - If we replace `'a` with `'x` from the input, it too will have
-        //   a DB index of 1, and thus we'll have `for<'x,'b> Bar1<'x,'b>`
-        //   just as we wanted.
-        //
-        // There is only one catch. If we just apply the substitution `'a
-        // => 'x` to `for<'b> Bar1<'a,'b>`, the substitution code will
-        // adjust the DB index because we substituting into a binder (it
-        // tries to be so smart...) resulting in `for<'x> for<'b>
-        // Bar1<'x,'b>` (we have no syntax for this, so use your
-        // imagination). Basically the 'x will have DB index of 2 and 'b
-        // will have DB index of 1. Not quite what we want. So we apply
-        // the substitution to the *contents* of the trait reference,
-        // rather than the trait reference itself (put another way, the
-        // substitution code expects equal binding levels in the values
-        // from the substitution and the value being substituted into, and
-        // this trick achieves that).
-
-        let substs = &trait_ref.skip_binder().substs;
-        match *self {
-            Predicate::Trait(ref binder, constness) => {
-                Predicate::Trait(binder.map_bound(|data| data.subst(tcx, substs)), constness)
-            }
-            Predicate::Subtype(ref binder) => {
-                Predicate::Subtype(binder.map_bound(|data| data.subst(tcx, substs)))
-            }
-            Predicate::RegionOutlives(ref binder) => {
-                Predicate::RegionOutlives(binder.map_bound(|data| data.subst(tcx, substs)))
-            }
-            Predicate::TypeOutlives(ref binder) => {
-                Predicate::TypeOutlives(binder.map_bound(|data| data.subst(tcx, substs)))
-            }
-            Predicate::Projection(ref binder) => {
-                Predicate::Projection(binder.map_bound(|data| data.subst(tcx, substs)))
-            }
-            Predicate::WellFormed(data) => Predicate::WellFormed(data.subst(tcx, substs)),
-            Predicate::ObjectSafe(trait_def_id) => Predicate::ObjectSafe(trait_def_id),
-            Predicate::ClosureKind(closure_def_id, closure_substs, kind) => {
-                Predicate::ClosureKind(closure_def_id, closure_substs.subst(tcx, substs), kind)
-            }
-            Predicate::ConstEvaluatable(def_id, const_substs) => {
-                Predicate::ConstEvaluatable(def_id, const_substs.subst(tcx, substs))
-            }
-        }
-    }
-}
-
-#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
-#[derive(HashStable, TypeFoldable)]
-pub struct TraitPredicate<'tcx> {
-    pub trait_ref: TraitRef<'tcx>,
-}
-
-pub type PolyTraitPredicate<'tcx> = ty::Binder<TraitPredicate<'tcx>>;
-
-impl<'tcx> TraitPredicate<'tcx> {
-    pub fn def_id(&self) -> DefId {
-        self.trait_ref.def_id
-    }
-
-    pub fn input_types<'a>(&'a self) -> impl DoubleEndedIterator<Item = Ty<'tcx>> + 'a {
-        self.trait_ref.input_types()
-    }
-
-    pub fn self_ty(&self) -> Ty<'tcx> {
-        self.trait_ref.self_ty()
-    }
-}
-
-impl<'tcx> PolyTraitPredicate<'tcx> {
-    pub fn def_id(&self) -> DefId {
-        // Ok to skip binder since trait `DefId` does not care about regions.
-        self.skip_binder().def_id()
-    }
-}
-
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
-#[derive(HashStable, TypeFoldable)]
-pub struct OutlivesPredicate<A, B>(pub A, pub B); // `A: B`
-pub type PolyOutlivesPredicate<A, B> = ty::Binder<OutlivesPredicate<A, B>>;
-pub type RegionOutlivesPredicate<'tcx> = OutlivesPredicate<ty::Region<'tcx>, ty::Region<'tcx>>;
-pub type TypeOutlivesPredicate<'tcx> = OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>;
-pub type PolyRegionOutlivesPredicate<'tcx> = ty::Binder<RegionOutlivesPredicate<'tcx>>;
-pub type PolyTypeOutlivesPredicate<'tcx> = ty::Binder<TypeOutlivesPredicate<'tcx>>;
-
-#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
-#[derive(HashStable, TypeFoldable)]
-pub struct SubtypePredicate<'tcx> {
-    pub a_is_expected: bool,
-    pub a: Ty<'tcx>,
-    pub b: Ty<'tcx>,
-}
-pub type PolySubtypePredicate<'tcx> = ty::Binder<SubtypePredicate<'tcx>>;
-
-/// This kind of predicate has no *direct* correspondent in the
-/// syntax, but it roughly corresponds to the syntactic forms:
-///
-/// 1. `T: TraitRef<..., Item = Type>`
-/// 2. `<T as TraitRef<...>>::Item == Type` (NYI)
-///
-/// In particular, form #1 is "desugared" to the combination of a
-/// normal trait predicate (`T: TraitRef<...>`) and one of these
-/// predicates. Form #2 is a broader form in that it also permits
-/// equality between arbitrary types. Processing an instance of
-/// Form #2 eventually yields one of these `ProjectionPredicate`
-/// instances to normalize the LHS.
-#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
-#[derive(HashStable, TypeFoldable)]
-pub struct ProjectionPredicate<'tcx> {
-    pub projection_ty: ProjectionTy<'tcx>,
-    pub ty: Ty<'tcx>,
-}
-
-pub type PolyProjectionPredicate<'tcx> = Binder<ProjectionPredicate<'tcx>>;
-
-impl<'tcx> PolyProjectionPredicate<'tcx> {
-    /// Returns the `DefId` of the associated item being projected.
-    pub fn item_def_id(&self) -> DefId {
-        self.skip_binder().projection_ty.item_def_id
-    }
-
-    #[inline]
-    pub fn to_poly_trait_ref(&self, tcx: TyCtxt<'tcx>) -> PolyTraitRef<'tcx> {
-        // Note: unlike with `TraitRef::to_poly_trait_ref()`,
-        // `self.0.trait_ref` is permitted to have escaping regions.
-        // This is because here `self` has a `Binder` and so does our
-        // return value, so we are preserving the number of binding
-        // levels.
-        self.map_bound(|predicate| predicate.projection_ty.trait_ref(tcx))
-    }
-
-    pub fn ty(&self) -> Binder<Ty<'tcx>> {
-        self.map_bound(|predicate| predicate.ty)
-    }
-
-    /// The `DefId` of the `TraitItem` for the associated type.
-    ///
-    /// Note that this is not the `DefId` of the `TraitRef` containing this
-    /// associated type, which is in `tcx.associated_item(projection_def_id()).container`.
-    pub fn projection_def_id(&self) -> DefId {
-        // Ok to skip binder since trait `DefId` does not care about regions.
-        self.skip_binder().projection_ty.item_def_id
-    }
-}
-
-pub trait ToPolyTraitRef<'tcx> {
-    fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx>;
-}
-
-impl<'tcx> ToPolyTraitRef<'tcx> for TraitRef<'tcx> {
-    fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> {
-        ty::Binder::dummy(*self)
-    }
-}
-
-impl<'tcx> ToPolyTraitRef<'tcx> for PolyTraitPredicate<'tcx> {
-    fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> {
-        self.map_bound_ref(|trait_pred| trait_pred.trait_ref)
-    }
-}
-
-pub trait ToPredicate<'tcx> {
-    fn to_predicate(&self) -> Predicate<'tcx>;
-}
-
-impl<'tcx> ToPredicate<'tcx> for ConstnessAnd<TraitRef<'tcx>> {
-    fn to_predicate(&self) -> Predicate<'tcx> {
-        ty::Predicate::Trait(
-            ty::Binder::dummy(ty::TraitPredicate { trait_ref: self.value }),
-            self.constness,
-        )
-    }
-}
-
-impl<'tcx> ToPredicate<'tcx> for ConstnessAnd<&TraitRef<'tcx>> {
-    fn to_predicate(&self) -> Predicate<'tcx> {
-        ty::Predicate::Trait(
-            ty::Binder::dummy(ty::TraitPredicate { trait_ref: *self.value }),
-            self.constness,
-        )
-    }
-}
-
-impl<'tcx> ToPredicate<'tcx> for ConstnessAnd<PolyTraitRef<'tcx>> {
-    fn to_predicate(&self) -> Predicate<'tcx> {
-        ty::Predicate::Trait(self.value.to_poly_trait_predicate(), self.constness)
-    }
-}
-
-impl<'tcx> ToPredicate<'tcx> for ConstnessAnd<&PolyTraitRef<'tcx>> {
-    fn to_predicate(&self) -> Predicate<'tcx> {
-        ty::Predicate::Trait(self.value.to_poly_trait_predicate(), self.constness)
-    }
-}
-
-impl<'tcx> ToPredicate<'tcx> for PolyRegionOutlivesPredicate<'tcx> {
-    fn to_predicate(&self) -> Predicate<'tcx> {
-        Predicate::RegionOutlives(*self)
-    }
-}
-
-impl<'tcx> ToPredicate<'tcx> for PolyTypeOutlivesPredicate<'tcx> {
-    fn to_predicate(&self) -> Predicate<'tcx> {
-        Predicate::TypeOutlives(*self)
-    }
-}
-
-impl<'tcx> ToPredicate<'tcx> for PolyProjectionPredicate<'tcx> {
-    fn to_predicate(&self) -> Predicate<'tcx> {
-        Predicate::Projection(*self)
-    }
-}
-
-// A custom iterator used by `Predicate::walk_tys`.
-enum WalkTysIter<'tcx, I, J, K>
-where
-    I: Iterator<Item = Ty<'tcx>>,
-    J: Iterator<Item = Ty<'tcx>>,
-    K: Iterator<Item = Ty<'tcx>>,
-{
-    None,
-    One(Ty<'tcx>),
-    Two(Ty<'tcx>, Ty<'tcx>),
-    Types(I),
-    InputTypes(J),
-    ProjectionTypes(K),
-}
-
-impl<'tcx, I, J, K> Iterator for WalkTysIter<'tcx, I, J, K>
-where
-    I: Iterator<Item = Ty<'tcx>>,
-    J: Iterator<Item = Ty<'tcx>>,
-    K: Iterator<Item = Ty<'tcx>>,
-{
-    type Item = Ty<'tcx>;
-
-    fn next(&mut self) -> Option<Ty<'tcx>> {
-        match *self {
-            WalkTysIter::None => None,
-            WalkTysIter::One(item) => {
-                *self = WalkTysIter::None;
-                Some(item)
-            }
-            WalkTysIter::Two(item1, item2) => {
-                *self = WalkTysIter::One(item2);
-                Some(item1)
-            }
-            WalkTysIter::Types(ref mut iter) => iter.next(),
-            WalkTysIter::InputTypes(ref mut iter) => iter.next(),
-            WalkTysIter::ProjectionTypes(ref mut iter) => iter.next(),
-        }
-    }
-}
-
-impl<'tcx> Predicate<'tcx> {
-    /// Iterates over the types in this predicate. Note that in all
-    /// cases this is skipping over a binder, so late-bound regions
-    /// with depth 0 are bound by the predicate.
-    pub fn walk_tys(&'a self) -> impl Iterator<Item = Ty<'tcx>> + 'a {
-        match *self {
-            ty::Predicate::Trait(ref data, _) => {
-                WalkTysIter::InputTypes(data.skip_binder().input_types())
-            }
-            ty::Predicate::Subtype(binder) => {
-                let SubtypePredicate { a, b, a_is_expected: _ } = binder.skip_binder();
-                WalkTysIter::Two(a, b)
-            }
-            ty::Predicate::TypeOutlives(binder) => WalkTysIter::One(binder.skip_binder().0),
-            ty::Predicate::RegionOutlives(..) => WalkTysIter::None,
-            ty::Predicate::Projection(ref data) => {
-                let inner = data.skip_binder();
-                WalkTysIter::ProjectionTypes(
-                    inner.projection_ty.substs.types().chain(Some(inner.ty)),
-                )
-            }
-            ty::Predicate::WellFormed(data) => WalkTysIter::One(data),
-            ty::Predicate::ObjectSafe(_trait_def_id) => WalkTysIter::None,
-            ty::Predicate::ClosureKind(_closure_def_id, closure_substs, _kind) => {
-                WalkTysIter::Types(closure_substs.types())
-            }
-            ty::Predicate::ConstEvaluatable(_, substs) => WalkTysIter::Types(substs.types()),
-        }
-    }
-
-    pub fn to_opt_poly_trait_ref(&self) -> Option<PolyTraitRef<'tcx>> {
-        match *self {
-            Predicate::Trait(ref t, _) => Some(t.to_poly_trait_ref()),
-            Predicate::Projection(..)
-            | Predicate::Subtype(..)
-            | Predicate::RegionOutlives(..)
-            | Predicate::WellFormed(..)
-            | Predicate::ObjectSafe(..)
-            | Predicate::ClosureKind(..)
-            | Predicate::TypeOutlives(..)
-            | Predicate::ConstEvaluatable(..) => None,
-        }
-    }
-
-    pub fn to_opt_type_outlives(&self) -> Option<PolyTypeOutlivesPredicate<'tcx>> {
-        match *self {
-            Predicate::TypeOutlives(data) => Some(data),
-            Predicate::Trait(..)
-            | Predicate::Projection(..)
-            | Predicate::Subtype(..)
-            | Predicate::RegionOutlives(..)
-            | Predicate::WellFormed(..)
-            | Predicate::ObjectSafe(..)
-            | Predicate::ClosureKind(..)
-            | Predicate::ConstEvaluatable(..) => None,
-        }
-    }
-}
-
-/// Represents the bounds declared on a particular set of type
-/// parameters. Should eventually be generalized into a flag list of
-/// where-clauses. You can obtain a `InstantiatedPredicates` list from a
-/// `GenericPredicates` by using the `instantiate` method. Note that this method
-/// reflects an important semantic invariant of `InstantiatedPredicates`: while
-/// the `GenericPredicates` are expressed in terms of the bound type
-/// parameters of the impl/trait/whatever, an `InstantiatedPredicates` instance
-/// represented a set of bounds for some particular instantiation,
-/// meaning that the generic parameters have been substituted with
-/// their values.
-///
-/// Example:
-///
-///     struct Foo<T, U: Bar<T>> { ... }
-///
-/// Here, the `GenericPredicates` for `Foo` would contain a list of bounds like
-/// `[[], [U:Bar<T>]]`. Now if there were some particular reference
-/// like `Foo<isize,usize>`, then the `InstantiatedPredicates` would be `[[],
-/// [usize:Bar<isize>]]`.
-#[derive(Clone, Debug, TypeFoldable)]
-pub struct InstantiatedPredicates<'tcx> {
-    pub predicates: Vec<Predicate<'tcx>>,
-    pub spans: Vec<Span>,
-}
-
-impl<'tcx> InstantiatedPredicates<'tcx> {
-    pub fn empty() -> InstantiatedPredicates<'tcx> {
-        InstantiatedPredicates { predicates: vec![], spans: vec![] }
-    }
-
-    pub fn is_empty(&self) -> bool {
-        self.predicates.is_empty()
-    }
-}
-
-rustc_index::newtype_index! {
-    /// "Universes" are used during type- and trait-checking in the
-    /// presence of `for<..>` binders to control what sets of names are
-    /// visible. Universes are arranged into a tree: the root universe
-    /// contains names that are always visible. Each child then adds a new
-    /// set of names that are visible, in addition to those of its parent.
-    /// We say that the child universe "extends" the parent universe with
-    /// new names.
-    ///
-    /// To make this more concrete, consider this program:
-    ///
-    /// ```
-    /// struct Foo { }
-    /// fn bar<T>(x: T) {
-    ///   let y: for<'a> fn(&'a u8, Foo) = ...;
-    /// }
-    /// ```
-    ///
-    /// The struct name `Foo` is in the root universe U0. But the type
-    /// parameter `T`, introduced on `bar`, is in an extended universe U1
-    /// -- i.e., within `bar`, we can name both `T` and `Foo`, but outside
-    /// of `bar`, we cannot name `T`. Then, within the type of `y`, the
-    /// region `'a` is in a universe U2 that extends U1, because we can
-    /// name it inside the fn type but not outside.
-    ///
-    /// Universes are used to do type- and trait-checking around these
-    /// "forall" binders (also called **universal quantification**). The
-    /// idea is that when, in the body of `bar`, we refer to `T` as a
-    /// type, we aren't referring to any type in particular, but rather a
-    /// kind of "fresh" type that is distinct from all other types we have
-    /// actually declared. This is called a **placeholder** type, and we
-    /// use universes to talk about this. In other words, a type name in
-    /// universe 0 always corresponds to some "ground" type that the user
-    /// declared, but a type name in a non-zero universe is a placeholder
-    /// type -- an idealized representative of "types in general" that we
-    /// use for checking generic functions.
-    pub struct UniverseIndex {
-        derive [HashStable]
-        DEBUG_FORMAT = "U{}",
-    }
-}
-
-impl UniverseIndex {
-    pub const ROOT: UniverseIndex = UniverseIndex::from_u32_const(0);
-
-    /// Returns the "next" universe index in order -- this new index
-    /// is considered to extend all previous universes. This
-    /// corresponds to entering a `forall` quantifier. So, for
-    /// example, suppose we have this type in universe `U`:
-    ///
-    /// ```
-    /// for<'a> fn(&'a u32)
-    /// ```
-    ///
-    /// Once we "enter" into this `for<'a>` quantifier, we are in a
-    /// new universe that extends `U` -- in this new universe, we can
-    /// name the region `'a`, but that region was not nameable from
-    /// `U` because it was not in scope there.
-    pub fn next_universe(self) -> UniverseIndex {
-        UniverseIndex::from_u32(self.private.checked_add(1).unwrap())
-    }
-
-    /// Returns `true` if `self` can name a name from `other` -- in other words,
-    /// if the set of names in `self` is a superset of those in
-    /// `other` (`self >= other`).
-    pub fn can_name(self, other: UniverseIndex) -> bool {
-        self.private >= other.private
-    }
-
-    /// Returns `true` if `self` cannot name some names from `other` -- in other
-    /// words, if the set of names in `self` is a strict subset of
-    /// those in `other` (`self < other`).
-    pub fn cannot_name(self, other: UniverseIndex) -> bool {
-        self.private < other.private
-    }
-}
-
-/// The "placeholder index" fully defines a placeholder region.
-/// Placeholder regions are identified by both a **universe** as well
-/// as a "bound-region" within that universe. The `bound_region` is
-/// basically a name -- distinct bound regions within the same
-/// universe are just two regions with an unknown relationship to one
-/// another.
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, PartialOrd, Ord)]
-pub struct Placeholder<T> {
-    pub universe: UniverseIndex,
-    pub name: T,
-}
-
-impl<'a, T> HashStable<StableHashingContext<'a>> for Placeholder<T>
-where
-    T: HashStable<StableHashingContext<'a>>,
-{
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        self.universe.hash_stable(hcx, hasher);
-        self.name.hash_stable(hcx, hasher);
-    }
-}
-
-pub type PlaceholderRegion = Placeholder<BoundRegion>;
-
-pub type PlaceholderType = Placeholder<BoundVar>;
-
-pub type PlaceholderConst = Placeholder<BoundVar>;
-
-/// When type checking, we use the `ParamEnv` to track
-/// details about the set of where-clauses that are in scope at this
-/// particular point.
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable, TypeFoldable)]
-pub struct ParamEnv<'tcx> {
-    /// `Obligation`s that the caller must satisfy. This is basically
-    /// the set of bounds on the in-scope type parameters, translated
-    /// into `Obligation`s, and elaborated and normalized.
-    pub caller_bounds: &'tcx List<ty::Predicate<'tcx>>,
-
-    /// Typically, this is `Reveal::UserFacing`, but during codegen we
-    /// want `Reveal::All` -- note that this is always paired with an
-    /// empty environment. To get that, use `ParamEnv::reveal()`.
-    pub reveal: traits::Reveal,
-
-    /// If this `ParamEnv` comes from a call to `tcx.param_env(def_id)`,
-    /// register that `def_id` (useful for transitioning to the chalk trait
-    /// solver).
-    pub def_id: Option<DefId>,
-}
-
-impl<'tcx> ParamEnv<'tcx> {
-    /// Construct a trait environment suitable for contexts where
-    /// there are no where-clauses in scope. Hidden types (like `impl
-    /// Trait`) are left hidden, so this is suitable for ordinary
-    /// type-checking.
-    #[inline]
-    pub fn empty() -> Self {
-        Self::new(List::empty(), Reveal::UserFacing, None)
-    }
-
-    /// Construct a trait environment with no where-clauses in scope
-    /// where the values of all `impl Trait` and other hidden types
-    /// are revealed. This is suitable for monomorphized, post-typeck
-    /// environments like codegen or doing optimizations.
-    ///
-    /// N.B., if you want to have predicates in scope, use `ParamEnv::new`,
-    /// or invoke `param_env.with_reveal_all()`.
-    #[inline]
-    pub fn reveal_all() -> Self {
-        Self::new(List::empty(), Reveal::All, None)
-    }
-
-    /// Construct a trait environment with the given set of predicates.
-    #[inline]
-    pub fn new(
-        caller_bounds: &'tcx List<ty::Predicate<'tcx>>,
-        reveal: Reveal,
-        def_id: Option<DefId>,
-    ) -> Self {
-        ty::ParamEnv { caller_bounds, reveal, def_id }
-    }
-
-    /// Returns a new parameter environment with the same clauses, but
-    /// which "reveals" the true results of projections in all cases
-    /// (even for associated types that are specializable). This is
-    /// the desired behavior during codegen and certain other special
-    /// contexts; normally though we want to use `Reveal::UserFacing`,
-    /// which is the default.
-    pub fn with_reveal_all(self) -> Self {
-        ty::ParamEnv { reveal: Reveal::All, ..self }
-    }
-
-    /// Returns this same environment but with no caller bounds.
-    pub fn without_caller_bounds(self) -> Self {
-        ty::ParamEnv { caller_bounds: List::empty(), ..self }
-    }
-
-    /// Creates a suitable environment in which to perform trait
-    /// queries on the given value. When type-checking, this is simply
-    /// the pair of the environment plus value. But when reveal is set to
-    /// All, then if `value` does not reference any type parameters, we will
-    /// pair it with the empty environment. This improves caching and is generally
-    /// invisible.
-    ///
-    /// N.B., we preserve the environment when type-checking because it
-    /// is possible for the user to have wacky where-clauses like
-    /// `where Box<u32>: Copy`, which are clearly never
-    /// satisfiable. We generally want to behave as if they were true,
-    /// although the surrounding function is never reachable.
-    pub fn and<T: TypeFoldable<'tcx>>(self, value: T) -> ParamEnvAnd<'tcx, T> {
-        match self.reveal {
-            Reveal::UserFacing => ParamEnvAnd { param_env: self, value },
-
-            Reveal::All => {
-                if value.has_placeholders() || value.needs_infer() || value.has_param_types() {
-                    ParamEnvAnd { param_env: self, value }
-                } else {
-                    ParamEnvAnd { param_env: self.without_caller_bounds(), value }
-                }
-            }
-        }
-    }
-}
-
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
-pub struct ConstnessAnd<T> {
-    pub constness: Constness,
-    pub value: T,
-}
-
-// FIXME(ecstaticmorse): Audit all occurrences of `without_const().to_predicate()` to ensure that
-// the constness of trait bounds is being propagated correctly.
-pub trait WithConstness: Sized {
-    #[inline]
-    fn with_constness(self, constness: Constness) -> ConstnessAnd<Self> {
-        ConstnessAnd { constness, value: self }
-    }
-
-    #[inline]
-    fn with_const(self) -> ConstnessAnd<Self> {
-        self.with_constness(Constness::Const)
-    }
-
-    #[inline]
-    fn without_const(self) -> ConstnessAnd<Self> {
-        self.with_constness(Constness::NotConst)
-    }
-}
-
-impl<T> WithConstness for T {}
-
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TypeFoldable)]
-pub struct ParamEnvAnd<'tcx, T> {
-    pub param_env: ParamEnv<'tcx>,
-    pub value: T,
-}
-
-impl<'tcx, T> ParamEnvAnd<'tcx, T> {
-    pub fn into_parts(self) -> (ParamEnv<'tcx>, T) {
-        (self.param_env, self.value)
-    }
-}
-
-impl<'a, 'tcx, T> HashStable<StableHashingContext<'a>> for ParamEnvAnd<'tcx, T>
-where
-    T: HashStable<StableHashingContext<'a>>,
-{
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        let ParamEnvAnd { ref param_env, ref value } = *self;
-
-        param_env.hash_stable(hcx, hasher);
-        value.hash_stable(hcx, hasher);
-    }
-}
-
-#[derive(Copy, Clone, Debug, HashStable)]
-pub struct Destructor {
-    /// The `DefId` of the destructor method
-    pub did: DefId,
-}
-
-bitflags! {
-    #[derive(HashStable)]
-    pub struct AdtFlags: u32 {
-        const NO_ADT_FLAGS        = 0;
-        /// Indicates whether the ADT is an enum.
-        const IS_ENUM             = 1 << 0;
-        /// Indicates whether the ADT is a union.
-        const IS_UNION            = 1 << 1;
-        /// Indicates whether the ADT is a struct.
-        const IS_STRUCT           = 1 << 2;
-        /// Indicates whether the ADT is a struct and has a constructor.
-        const HAS_CTOR            = 1 << 3;
-        /// Indicates whether the type is `PhantomData`.
-        const IS_PHANTOM_DATA     = 1 << 4;
-        /// Indicates whether the type has a `#[fundamental]` attribute.
-        const IS_FUNDAMENTAL      = 1 << 5;
-        /// Indicates whether the type is `Box`.
-        const IS_BOX              = 1 << 6;
-        /// Indicates whether the type is `ManuallyDrop`.
-        const IS_MANUALLY_DROP    = 1 << 7;
-        // FIXME(matthewjasper) replace these with diagnostic items
-        /// Indicates whether the type is an `Arc`.
-        const IS_ARC              = 1 << 8;
-        /// Indicates whether the type is an `Rc`.
-        const IS_RC               = 1 << 9;
-        /// Indicates whether the variant list of this ADT is `#[non_exhaustive]`.
-        /// (i.e., this flag is never set unless this ADT is an enum).
-        const IS_VARIANT_LIST_NON_EXHAUSTIVE = 1 << 10;
-    }
-}
-
-bitflags! {
-    #[derive(HashStable)]
-    pub struct VariantFlags: u32 {
-        const NO_VARIANT_FLAGS        = 0;
-        /// Indicates whether the field list of this variant is `#[non_exhaustive]`.
-        const IS_FIELD_LIST_NON_EXHAUSTIVE = 1 << 0;
-    }
-}
-
-/// Definition of a variant -- a struct's fields or a enum variant.
-#[derive(Debug, HashStable)]
-pub struct VariantDef {
-    /// `DefId` that identifies the variant itself.
-    /// If this variant belongs to a struct or union, then this is a copy of its `DefId`.
-    pub def_id: DefId,
-    /// `DefId` that identifies the variant's constructor.
-    /// If this variant is a struct variant, then this is `None`.
-    pub ctor_def_id: Option<DefId>,
-    /// Variant or struct name.
-    #[stable_hasher(project(name))]
-    pub ident: Ident,
-    /// Discriminant of this variant.
-    pub discr: VariantDiscr,
-    /// Fields of this variant.
-    pub fields: Vec<FieldDef>,
-    /// Type of constructor of variant.
-    pub ctor_kind: CtorKind,
-    /// Flags of the variant (e.g. is field list non-exhaustive)?
-    flags: VariantFlags,
-    /// Variant is obtained as part of recovering from a syntactic error.
-    /// May be incomplete or bogus.
-    pub recovered: bool,
-}
-
-impl<'tcx> VariantDef {
-    /// Creates a new `VariantDef`.
-    ///
-    /// `variant_did` is the `DefId` that identifies the enum variant (if this `VariantDef`
-    /// represents an enum variant).
-    ///
-    /// `ctor_did` is the `DefId` that identifies the constructor of unit or
-    /// tuple-variants/structs. If this is a `struct`-variant then this should be `None`.
-    ///
-    /// `parent_did` is the `DefId` of the `AdtDef` representing the enum or struct that
-    /// owns this variant. It is used for checking if a struct has `#[non_exhaustive]` w/out having
-    /// to go through the redirect of checking the ctor's attributes - but compiling a small crate
-    /// requires loading the `AdtDef`s for all the structs in the universe (e.g., coherence for any
-    /// built-in trait), and we do not want to load attributes twice.
-    ///
-    /// If someone speeds up attribute loading to not be a performance concern, they can
-    /// remove this hack and use the constructor `DefId` everywhere.
-    pub fn new(
-        tcx: TyCtxt<'tcx>,
-        ident: Ident,
-        variant_did: Option<DefId>,
-        ctor_def_id: Option<DefId>,
-        discr: VariantDiscr,
-        fields: Vec<FieldDef>,
-        ctor_kind: CtorKind,
-        adt_kind: AdtKind,
-        parent_did: DefId,
-        recovered: bool,
-    ) -> Self {
-        debug!(
-            "VariantDef::new(ident = {:?}, variant_did = {:?}, ctor_def_id = {:?}, discr = {:?},
-             fields = {:?}, ctor_kind = {:?}, adt_kind = {:?}, parent_did = {:?})",
-            ident, variant_did, ctor_def_id, discr, fields, ctor_kind, adt_kind, parent_did,
-        );
-
-        let mut flags = VariantFlags::NO_VARIANT_FLAGS;
-        if adt_kind == AdtKind::Struct && tcx.has_attr(parent_did, sym::non_exhaustive) {
-            debug!("found non-exhaustive field list for {:?}", parent_did);
-            flags = flags | VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE;
-        } else if let Some(variant_did) = variant_did {
-            if tcx.has_attr(variant_did, sym::non_exhaustive) {
-                debug!("found non-exhaustive field list for {:?}", variant_did);
-                flags = flags | VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE;
-            }
-        }
-
-        VariantDef {
-            def_id: variant_did.unwrap_or(parent_did),
-            ctor_def_id,
-            ident,
-            discr,
-            fields,
-            ctor_kind,
-            flags,
-            recovered,
-        }
-    }
-
-    /// Is this field list non-exhaustive?
-    #[inline]
-    pub fn is_field_list_non_exhaustive(&self) -> bool {
-        self.flags.intersects(VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE)
-    }
-}
-
-#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
-pub enum VariantDiscr {
-    /// Explicit value for this variant, i.e., `X = 123`.
-    /// The `DefId` corresponds to the embedded constant.
-    Explicit(DefId),
-
-    /// The previous variant's discriminant plus one.
-    /// For efficiency reasons, the distance from the
-    /// last `Explicit` discriminant is being stored,
-    /// or `0` for the first variant, if it has none.
-    Relative(u32),
-}
-
-#[derive(Debug, HashStable)]
-pub struct FieldDef {
-    pub did: DefId,
-    #[stable_hasher(project(name))]
-    pub ident: Ident,
-    pub vis: Visibility,
-}
-
-/// The definition of a user-defined type, e.g., a `struct`, `enum`, or `union`.
-///
-/// These are all interned (by `intern_adt_def`) into the `adt_defs` table.
-///
-/// The initialism *ADT* stands for an [*algebraic data type (ADT)*][adt].
-/// This is slightly wrong because `union`s are not ADTs.
-/// Moreover, Rust only allows recursive data types through indirection.
-///
-/// [adt]: https://en.wikipedia.org/wiki/Algebraic_data_type
-pub struct AdtDef {
-    /// The `DefId` of the struct, enum or union item.
-    pub did: DefId,
-    /// Variants of the ADT. If this is a struct or union, then there will be a single variant.
-    pub variants: IndexVec<self::layout::VariantIdx, VariantDef>,
-    /// Flags of the ADT (e.g., is this a struct? is this non-exhaustive?).
-    flags: AdtFlags,
-    /// Repr options provided by the user.
-    pub repr: ReprOptions,
-}
-
-impl PartialOrd for AdtDef {
-    fn partial_cmp(&self, other: &AdtDef) -> Option<Ordering> {
-        Some(self.cmp(&other))
-    }
-}
-
-/// There should be only one AdtDef for each `did`, therefore
-/// it is fine to implement `Ord` only based on `did`.
-impl Ord for AdtDef {
-    fn cmp(&self, other: &AdtDef) -> Ordering {
-        self.did.cmp(&other.did)
-    }
-}
-
-impl PartialEq for AdtDef {
-    // `AdtDef`s are always interned, and this is part of `TyS` equality.
-    #[inline]
-    fn eq(&self, other: &Self) -> bool {
-        ptr::eq(self, other)
-    }
-}
-
-impl Eq for AdtDef {}
-
-impl Hash for AdtDef {
-    #[inline]
-    fn hash<H: Hasher>(&self, s: &mut H) {
-        (self as *const AdtDef).hash(s)
-    }
-}
-
-impl<'tcx> rustc_serialize::UseSpecializedEncodable for &'tcx AdtDef {
-    fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
-        self.did.encode(s)
-    }
-}
-
-impl<'tcx> rustc_serialize::UseSpecializedDecodable for &'tcx AdtDef {}
-
-impl<'a> HashStable<StableHashingContext<'a>> for AdtDef {
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        thread_local! {
-            static CACHE: RefCell<FxHashMap<usize, Fingerprint>> = Default::default();
-        }
-
-        let hash: Fingerprint = CACHE.with(|cache| {
-            let addr = self as *const AdtDef as usize;
-            *cache.borrow_mut().entry(addr).or_insert_with(|| {
-                let ty::AdtDef { did, ref variants, ref flags, ref repr } = *self;
-
-                let mut hasher = StableHasher::new();
-                did.hash_stable(hcx, &mut hasher);
-                variants.hash_stable(hcx, &mut hasher);
-                flags.hash_stable(hcx, &mut hasher);
-                repr.hash_stable(hcx, &mut hasher);
-
-                hasher.finish()
-            })
-        });
-
-        hash.hash_stable(hcx, hasher);
-    }
-}
-
-#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
-pub enum AdtKind {
-    Struct,
-    Union,
-    Enum,
-}
-
-impl Into<DataTypeKind> for AdtKind {
-    fn into(self) -> DataTypeKind {
-        match self {
-            AdtKind::Struct => DataTypeKind::Struct,
-            AdtKind::Union => DataTypeKind::Union,
-            AdtKind::Enum => DataTypeKind::Enum,
-        }
-    }
-}
-
-bitflags! {
-    #[derive(RustcEncodable, RustcDecodable, Default, HashStable)]
-    pub struct ReprFlags: u8 {
-        const IS_C               = 1 << 0;
-        const IS_SIMD            = 1 << 1;
-        const IS_TRANSPARENT     = 1 << 2;
-        // Internal only for now. If true, don't reorder fields.
-        const IS_LINEAR          = 1 << 3;
-        // If true, don't expose any niche to type's context.
-        const HIDE_NICHE         = 1 << 4;
-        // Any of these flags being set prevent field reordering optimisation.
-        const IS_UNOPTIMISABLE   = ReprFlags::IS_C.bits |
-                                   ReprFlags::IS_SIMD.bits |
-                                   ReprFlags::IS_LINEAR.bits;
-    }
-}
-
-/// Represents the repr options provided by the user,
-#[derive(Copy, Clone, Debug, Eq, PartialEq, RustcEncodable, RustcDecodable, Default, HashStable)]
-pub struct ReprOptions {
-    pub int: Option<attr::IntType>,
-    pub align: Option<Align>,
-    pub pack: Option<Align>,
-    pub flags: ReprFlags,
-}
-
-impl ReprOptions {
-    pub fn new(tcx: TyCtxt<'_>, did: DefId) -> ReprOptions {
-        let mut flags = ReprFlags::empty();
-        let mut size = None;
-        let mut max_align: Option<Align> = None;
-        let mut min_pack: Option<Align> = None;
-        for attr in tcx.get_attrs(did).iter() {
-            for r in attr::find_repr_attrs(&tcx.sess.parse_sess, attr) {
-                flags.insert(match r {
-                    attr::ReprC => ReprFlags::IS_C,
-                    attr::ReprPacked(pack) => {
-                        let pack = Align::from_bytes(pack as u64).unwrap();
-                        min_pack = Some(if let Some(min_pack) = min_pack {
-                            min_pack.min(pack)
-                        } else {
-                            pack
-                        });
-                        ReprFlags::empty()
-                    }
-                    attr::ReprTransparent => ReprFlags::IS_TRANSPARENT,
-                    attr::ReprNoNiche => ReprFlags::HIDE_NICHE,
-                    attr::ReprSimd => ReprFlags::IS_SIMD,
-                    attr::ReprInt(i) => {
-                        size = Some(i);
-                        ReprFlags::empty()
-                    }
-                    attr::ReprAlign(align) => {
-                        max_align = max_align.max(Some(Align::from_bytes(align as u64).unwrap()));
-                        ReprFlags::empty()
-                    }
-                });
-            }
-        }
-
-        // This is here instead of layout because the choice must make it into metadata.
-        if !tcx.consider_optimizing(|| format!("Reorder fields of {:?}", tcx.def_path_str(did))) {
-            flags.insert(ReprFlags::IS_LINEAR);
-        }
-        ReprOptions { int: size, align: max_align, pack: min_pack, flags: flags }
-    }
-
-    #[inline]
-    pub fn simd(&self) -> bool {
-        self.flags.contains(ReprFlags::IS_SIMD)
-    }
-    #[inline]
-    pub fn c(&self) -> bool {
-        self.flags.contains(ReprFlags::IS_C)
-    }
-    #[inline]
-    pub fn packed(&self) -> bool {
-        self.pack.is_some()
-    }
-    #[inline]
-    pub fn transparent(&self) -> bool {
-        self.flags.contains(ReprFlags::IS_TRANSPARENT)
-    }
-    #[inline]
-    pub fn linear(&self) -> bool {
-        self.flags.contains(ReprFlags::IS_LINEAR)
-    }
-    #[inline]
-    pub fn hide_niche(&self) -> bool {
-        self.flags.contains(ReprFlags::HIDE_NICHE)
-    }
-
-    pub fn discr_type(&self) -> attr::IntType {
-        self.int.unwrap_or(attr::SignedInt(ast::IntTy::Isize))
-    }
-
-    /// Returns `true` if this `#[repr()]` should inhabit "smart enum
-    /// layout" optimizations, such as representing `Foo<&T>` as a
-    /// single pointer.
-    pub fn inhibit_enum_layout_opt(&self) -> bool {
-        self.c() || self.int.is_some()
-    }
-
-    /// Returns `true` if this `#[repr()]` should inhibit struct field reordering
-    /// optimizations, such as with `repr(C)`, `repr(packed(1))`, or `repr(<int>)`.
-    pub fn inhibit_struct_field_reordering_opt(&self) -> bool {
-        if let Some(pack) = self.pack {
-            if pack.bytes() == 1 {
-                return true;
-            }
-        }
-        self.flags.intersects(ReprFlags::IS_UNOPTIMISABLE) || self.int.is_some()
-    }
-
-    /// Returns `true` if this `#[repr()]` should inhibit union ABI optimisations.
-    pub fn inhibit_union_abi_opt(&self) -> bool {
-        self.c()
-    }
-}
-
-impl<'tcx> AdtDef {
-    /// Creates a new `AdtDef`.
-    fn new(
-        tcx: TyCtxt<'_>,
-        did: DefId,
-        kind: AdtKind,
-        variants: IndexVec<VariantIdx, VariantDef>,
-        repr: ReprOptions,
-    ) -> Self {
-        debug!("AdtDef::new({:?}, {:?}, {:?}, {:?})", did, kind, variants, repr);
-        let mut flags = AdtFlags::NO_ADT_FLAGS;
-
-        if kind == AdtKind::Enum && tcx.has_attr(did, sym::non_exhaustive) {
-            debug!("found non-exhaustive variant list for {:?}", did);
-            flags = flags | AdtFlags::IS_VARIANT_LIST_NON_EXHAUSTIVE;
-        }
-
-        flags |= match kind {
-            AdtKind::Enum => AdtFlags::IS_ENUM,
-            AdtKind::Union => AdtFlags::IS_UNION,
-            AdtKind::Struct => AdtFlags::IS_STRUCT,
-        };
-
-        if kind == AdtKind::Struct && variants[VariantIdx::new(0)].ctor_def_id.is_some() {
-            flags |= AdtFlags::HAS_CTOR;
-        }
-
-        let attrs = tcx.get_attrs(did);
-        if attr::contains_name(&attrs, sym::fundamental) {
-            flags |= AdtFlags::IS_FUNDAMENTAL;
-        }
-        if Some(did) == tcx.lang_items().phantom_data() {
-            flags |= AdtFlags::IS_PHANTOM_DATA;
-        }
-        if Some(did) == tcx.lang_items().owned_box() {
-            flags |= AdtFlags::IS_BOX;
-        }
-        if Some(did) == tcx.lang_items().manually_drop() {
-            flags |= AdtFlags::IS_MANUALLY_DROP;
-        }
-        if Some(did) == tcx.lang_items().arc() {
-            flags |= AdtFlags::IS_ARC;
-        }
-        if Some(did) == tcx.lang_items().rc() {
-            flags |= AdtFlags::IS_RC;
-        }
-
-        AdtDef { did, variants, flags, repr }
-    }
-
-    /// Returns `true` if this is a struct.
-    #[inline]
-    pub fn is_struct(&self) -> bool {
-        self.flags.contains(AdtFlags::IS_STRUCT)
-    }
-
-    /// Returns `true` if this is a union.
-    #[inline]
-    pub fn is_union(&self) -> bool {
-        self.flags.contains(AdtFlags::IS_UNION)
-    }
-
-    /// Returns `true` if this is a enum.
-    #[inline]
-    pub fn is_enum(&self) -> bool {
-        self.flags.contains(AdtFlags::IS_ENUM)
-    }
-
-    /// Returns `true` if the variant list of this ADT is `#[non_exhaustive]`.
-    #[inline]
-    pub fn is_variant_list_non_exhaustive(&self) -> bool {
-        self.flags.contains(AdtFlags::IS_VARIANT_LIST_NON_EXHAUSTIVE)
-    }
-
-    /// Returns the kind of the ADT.
-    #[inline]
-    pub fn adt_kind(&self) -> AdtKind {
-        if self.is_enum() {
-            AdtKind::Enum
-        } else if self.is_union() {
-            AdtKind::Union
-        } else {
-            AdtKind::Struct
-        }
-    }
-
-    /// Returns a description of this abstract data type.
-    pub fn descr(&self) -> &'static str {
-        match self.adt_kind() {
-            AdtKind::Struct => "struct",
-            AdtKind::Union => "union",
-            AdtKind::Enum => "enum",
-        }
-    }
-
-    /// Returns a description of a variant of this abstract data type.
-    #[inline]
-    pub fn variant_descr(&self) -> &'static str {
-        match self.adt_kind() {
-            AdtKind::Struct => "struct",
-            AdtKind::Union => "union",
-            AdtKind::Enum => "variant",
-        }
-    }
-
-    /// If this function returns `true`, it implies that `is_struct` must return `true`.
-    #[inline]
-    pub fn has_ctor(&self) -> bool {
-        self.flags.contains(AdtFlags::HAS_CTOR)
-    }
-
-    /// Returns `true` if this type is `#[fundamental]` for the purposes
-    /// of coherence checking.
-    #[inline]
-    pub fn is_fundamental(&self) -> bool {
-        self.flags.contains(AdtFlags::IS_FUNDAMENTAL)
-    }
-
-    /// Returns `true` if this is `PhantomData<T>`.
-    #[inline]
-    pub fn is_phantom_data(&self) -> bool {
-        self.flags.contains(AdtFlags::IS_PHANTOM_DATA)
-    }
-
-    /// Returns `true` if this is `Arc<T>`.
-    pub fn is_arc(&self) -> bool {
-        self.flags.contains(AdtFlags::IS_ARC)
-    }
-
-    /// Returns `true` if this is `Rc<T>`.
-    pub fn is_rc(&self) -> bool {
-        self.flags.contains(AdtFlags::IS_RC)
-    }
-
-    /// Returns `true` if this is Box<T>.
-    #[inline]
-    pub fn is_box(&self) -> bool {
-        self.flags.contains(AdtFlags::IS_BOX)
-    }
-
-    /// Returns `true` if this is `ManuallyDrop<T>`.
-    #[inline]
-    pub fn is_manually_drop(&self) -> bool {
-        self.flags.contains(AdtFlags::IS_MANUALLY_DROP)
-    }
-
-    /// Returns `true` if this type has a destructor.
-    pub fn has_dtor(&self, tcx: TyCtxt<'tcx>) -> bool {
-        self.destructor(tcx).is_some()
-    }
-
-    /// Asserts this is a struct or union and returns its unique variant.
-    pub fn non_enum_variant(&self) -> &VariantDef {
-        assert!(self.is_struct() || self.is_union());
-        &self.variants[VariantIdx::new(0)]
-    }
-
-    #[inline]
-    pub fn predicates(&self, tcx: TyCtxt<'tcx>) -> GenericPredicates<'tcx> {
-        tcx.predicates_of(self.did)
-    }
-
-    /// Returns an iterator over all fields contained
-    /// by this ADT.
-    #[inline]
-    pub fn all_fields(&self) -> impl Iterator<Item = &FieldDef> + Clone {
-        self.variants.iter().flat_map(|v| v.fields.iter())
-    }
-
-    pub fn is_payloadfree(&self) -> bool {
-        !self.variants.is_empty() && self.variants.iter().all(|v| v.fields.is_empty())
-    }
-
-    /// Return a `VariantDef` given a variant id.
-    pub fn variant_with_id(&self, vid: DefId) -> &VariantDef {
-        self.variants.iter().find(|v| v.def_id == vid).expect("variant_with_id: unknown variant")
-    }
-
-    /// Return a `VariantDef` given a constructor id.
-    pub fn variant_with_ctor_id(&self, cid: DefId) -> &VariantDef {
-        self.variants
-            .iter()
-            .find(|v| v.ctor_def_id == Some(cid))
-            .expect("variant_with_ctor_id: unknown variant")
-    }
-
-    /// Return the index of `VariantDef` given a variant id.
-    pub fn variant_index_with_id(&self, vid: DefId) -> VariantIdx {
-        self.variants
-            .iter_enumerated()
-            .find(|(_, v)| v.def_id == vid)
-            .expect("variant_index_with_id: unknown variant")
-            .0
-    }
-
-    /// Return the index of `VariantDef` given a constructor id.
-    pub fn variant_index_with_ctor_id(&self, cid: DefId) -> VariantIdx {
-        self.variants
-            .iter_enumerated()
-            .find(|(_, v)| v.ctor_def_id == Some(cid))
-            .expect("variant_index_with_ctor_id: unknown variant")
-            .0
-    }
-
-    pub fn variant_of_res(&self, res: Res) -> &VariantDef {
-        match res {
-            Res::Def(DefKind::Variant, vid) => self.variant_with_id(vid),
-            Res::Def(DefKind::Ctor(..), cid) => self.variant_with_ctor_id(cid),
-            Res::Def(DefKind::Struct, _)
-            | Res::Def(DefKind::Union, _)
-            | Res::Def(DefKind::TyAlias, _)
-            | Res::Def(DefKind::AssocTy, _)
-            | Res::SelfTy(..)
-            | Res::SelfCtor(..) => self.non_enum_variant(),
-            _ => bug!("unexpected res {:?} in variant_of_res", res),
-        }
-    }
-
-    #[inline]
-    pub fn eval_explicit_discr(&self, tcx: TyCtxt<'tcx>, expr_did: DefId) -> Option<Discr<'tcx>> {
-        let param_env = tcx.param_env(expr_did);
-        let repr_type = self.repr.discr_type();
-        match tcx.const_eval_poly(expr_did) {
-            Ok(val) => {
-                let ty = repr_type.to_ty(tcx);
-                if let Some(b) = val.try_to_bits_for_ty(tcx, param_env, ty) {
-                    trace!("discriminants: {} ({:?})", b, repr_type);
-                    Some(Discr { val: b, ty })
-                } else {
-                    info!("invalid enum discriminant: {:#?}", val);
-                    crate::mir::interpret::struct_error(
-                        tcx.at(tcx.def_span(expr_did)),
-                        "constant evaluation of enum discriminant resulted in non-integer",
-                    )
-                    .emit();
-                    None
-                }
-            }
-            Err(ErrorHandled::Reported) => {
-                if !expr_did.is_local() {
-                    span_bug!(
-                        tcx.def_span(expr_did),
-                        "variant discriminant evaluation succeeded \
-                         in its crate but failed locally"
-                    );
-                }
-                None
-            }
-            Err(ErrorHandled::TooGeneric) => {
-                span_bug!(tcx.def_span(expr_did), "enum discriminant depends on generic arguments",)
-            }
-        }
-    }
-
-    #[inline]
-    pub fn discriminants(
-        &'tcx self,
-        tcx: TyCtxt<'tcx>,
-    ) -> impl Iterator<Item = (VariantIdx, Discr<'tcx>)> + Captures<'tcx> {
-        let repr_type = self.repr.discr_type();
-        let initial = repr_type.initial_discriminant(tcx);
-        let mut prev_discr = None::<Discr<'tcx>>;
-        self.variants.iter_enumerated().map(move |(i, v)| {
-            let mut discr = prev_discr.map_or(initial, |d| d.wrap_incr(tcx));
-            if let VariantDiscr::Explicit(expr_did) = v.discr {
-                if let Some(new_discr) = self.eval_explicit_discr(tcx, expr_did) {
-                    discr = new_discr;
-                }
-            }
-            prev_discr = Some(discr);
-
-            (i, discr)
-        })
-    }
-
-    #[inline]
-    pub fn variant_range(&self) -> Range<VariantIdx> {
-        VariantIdx::new(0)..VariantIdx::new(self.variants.len())
-    }
-
-    /// Computes the discriminant value used by a specific variant.
-    /// Unlike `discriminants`, this is (amortized) constant-time,
-    /// only doing at most one query for evaluating an explicit
-    /// discriminant (the last one before the requested variant),
-    /// assuming there are no constant-evaluation errors there.
-    #[inline]
-    pub fn discriminant_for_variant(
-        &self,
-        tcx: TyCtxt<'tcx>,
-        variant_index: VariantIdx,
-    ) -> Discr<'tcx> {
-        let (val, offset) = self.discriminant_def_for_variant(variant_index);
-        let explicit_value = val
-            .and_then(|expr_did| self.eval_explicit_discr(tcx, expr_did))
-            .unwrap_or_else(|| self.repr.discr_type().initial_discriminant(tcx));
-        explicit_value.checked_add(tcx, offset as u128).0
-    }
-
-    /// Yields a `DefId` for the discriminant and an offset to add to it
-    /// Alternatively, if there is no explicit discriminant, returns the
-    /// inferred discriminant directly.
-    pub fn discriminant_def_for_variant(&self, variant_index: VariantIdx) -> (Option<DefId>, u32) {
-        let mut explicit_index = variant_index.as_u32();
-        let expr_did;
-        loop {
-            match self.variants[VariantIdx::from_u32(explicit_index)].discr {
-                ty::VariantDiscr::Relative(0) => {
-                    expr_did = None;
-                    break;
-                }
-                ty::VariantDiscr::Relative(distance) => {
-                    explicit_index -= distance;
-                }
-                ty::VariantDiscr::Explicit(did) => {
-                    expr_did = Some(did);
-                    break;
-                }
-            }
-        }
-        (expr_did, variant_index.as_u32() - explicit_index)
-    }
-
-    pub fn destructor(&self, tcx: TyCtxt<'tcx>) -> Option<Destructor> {
-        tcx.adt_destructor(self.did)
-    }
-
-    /// Returns a list of types such that `Self: Sized` if and only
-    /// if that type is `Sized`, or `TyErr` if this type is recursive.
-    ///
-    /// Oddly enough, checking that the sized-constraint is `Sized` is
-    /// actually more expressive than checking all members:
-    /// the `Sized` trait is inductive, so an associated type that references
-    /// `Self` would prevent its containing ADT from being `Sized`.
-    ///
-    /// Due to normalization being eager, this applies even if
-    /// the associated type is behind a pointer (e.g., issue #31299).
-    pub fn sized_constraint(&self, tcx: TyCtxt<'tcx>) -> &'tcx [Ty<'tcx>] {
-        tcx.adt_sized_constraint(self.did).0
-    }
-}
-
-impl<'tcx> FieldDef {
-    /// Returns the type of this field. The `subst` is typically obtained
-    /// via the second field of `TyKind::AdtDef`.
-    pub fn ty(&self, tcx: TyCtxt<'tcx>, subst: SubstsRef<'tcx>) -> Ty<'tcx> {
-        tcx.type_of(self.did).subst(tcx, subst)
-    }
-}
-
-/// Represents the various closure traits in the language. This
-/// will determine the type of the environment (`self`, in the
-/// desugaring) argument that the closure expects.
-///
-/// You can get the environment type of a closure using
-/// `tcx.closure_env_ty()`.
-#[derive(
-    Clone,
-    Copy,
-    PartialOrd,
-    Ord,
-    PartialEq,
-    Eq,
-    Hash,
-    Debug,
-    RustcEncodable,
-    RustcDecodable,
-    HashStable
-)]
-pub enum ClosureKind {
-    // Warning: Ordering is significant here! The ordering is chosen
-    // because the trait Fn is a subtrait of FnMut and so in turn, and
-    // hence we order it so that Fn < FnMut < FnOnce.
-    Fn,
-    FnMut,
-    FnOnce,
-}
-
-impl<'tcx> ClosureKind {
-    // This is the initial value used when doing upvar inference.
-    pub const LATTICE_BOTTOM: ClosureKind = ClosureKind::Fn;
-
-    pub fn trait_did(&self, tcx: TyCtxt<'tcx>) -> DefId {
-        match *self {
-            ClosureKind::Fn => tcx.require_lang_item(FnTraitLangItem, None),
-            ClosureKind::FnMut => tcx.require_lang_item(FnMutTraitLangItem, None),
-            ClosureKind::FnOnce => tcx.require_lang_item(FnOnceTraitLangItem, None),
-        }
-    }
-
-    /// Returns `true` if this a type that impls this closure kind
-    /// must also implement `other`.
-    pub fn extends(self, other: ty::ClosureKind) -> bool {
-        match (self, other) {
-            (ClosureKind::Fn, ClosureKind::Fn) => true,
-            (ClosureKind::Fn, ClosureKind::FnMut) => true,
-            (ClosureKind::Fn, ClosureKind::FnOnce) => true,
-            (ClosureKind::FnMut, ClosureKind::FnMut) => true,
-            (ClosureKind::FnMut, ClosureKind::FnOnce) => true,
-            (ClosureKind::FnOnce, ClosureKind::FnOnce) => true,
-            _ => false,
-        }
-    }
-
-    /// Returns the representative scalar type for this closure kind.
-    /// See `TyS::to_opt_closure_kind` for more details.
-    pub fn to_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
-        match self {
-            ty::ClosureKind::Fn => tcx.types.i8,
-            ty::ClosureKind::FnMut => tcx.types.i16,
-            ty::ClosureKind::FnOnce => tcx.types.i32,
-        }
-    }
-}
-
-impl<'tcx> TyS<'tcx> {
-    /// Iterator that walks `self` and any types reachable from
-    /// `self`, in depth-first order. Note that just walks the types
-    /// that appear in `self`, it does not descend into the fields of
-    /// structs or variants. For example:
-    ///
-    /// ```notrust
-    /// isize => { isize }
-    /// Foo<Bar<isize>> => { Foo<Bar<isize>>, Bar<isize>, isize }
-    /// [isize] => { [isize], isize }
-    /// ```
-    pub fn walk(&'tcx self) -> TypeWalker<'tcx> {
-        TypeWalker::new(self)
-    }
-
-    /// Iterator that walks the immediate children of `self`. Hence
-    /// `Foo<Bar<i32>, u32>` yields the sequence `[Bar<i32>, u32]`
-    /// (but not `i32`, like `walk`).
-    pub fn walk_shallow(&'tcx self) -> smallvec::IntoIter<walk::TypeWalkerArray<'tcx>> {
-        walk::walk_shallow(self)
-    }
-
-    /// Walks `ty` and any types appearing within `ty`, invoking the
-    /// callback `f` on each type. If the callback returns `false`, then the
-    /// children of the current type are ignored.
-    ///
-    /// Note: prefer `ty.walk()` where possible.
-    pub fn maybe_walk<F>(&'tcx self, mut f: F)
-    where
-        F: FnMut(Ty<'tcx>) -> bool,
-    {
-        let mut walker = self.walk();
-        while let Some(ty) = walker.next() {
-            if !f(ty) {
-                walker.skip_current_subtree();
-            }
-        }
-    }
-}
-
-impl BorrowKind {
-    pub fn from_mutbl(m: hir::Mutability) -> BorrowKind {
-        match m {
-            hir::Mutability::Mut => MutBorrow,
-            hir::Mutability::Not => ImmBorrow,
-        }
-    }
-
-    /// Returns a mutability `m` such that an `&m T` pointer could be used to obtain this borrow
-    /// kind. Because borrow kinds are richer than mutabilities, we sometimes have to pick a
-    /// mutability that is stronger than necessary so that it at least *would permit* the borrow in
-    /// question.
-    pub fn to_mutbl_lossy(self) -> hir::Mutability {
-        match self {
-            MutBorrow => hir::Mutability::Mut,
-            ImmBorrow => hir::Mutability::Not,
-
-            // We have no type corresponding to a unique imm borrow, so
-            // use `&mut`. It gives all the capabilities of an `&uniq`
-            // and hence is a safe "over approximation".
-            UniqueImmBorrow => hir::Mutability::Mut,
-        }
-    }
-
-    pub fn to_user_str(&self) -> &'static str {
-        match *self {
-            MutBorrow => "mutable",
-            ImmBorrow => "immutable",
-            UniqueImmBorrow => "uniquely immutable",
-        }
-    }
-}
-
-#[derive(Debug, Clone)]
-pub enum Attributes<'tcx> {
-    Owned(Lrc<[ast::Attribute]>),
-    Borrowed(&'tcx [ast::Attribute]),
-}
-
-impl<'tcx> ::std::ops::Deref for Attributes<'tcx> {
-    type Target = [ast::Attribute];
-
-    fn deref(&self) -> &[ast::Attribute] {
-        match self {
-            &Attributes::Owned(ref data) => &data,
-            &Attributes::Borrowed(data) => data,
-        }
-    }
-}
-
-#[derive(Debug, PartialEq, Eq)]
-pub enum ImplOverlapKind {
-    /// These impls are always allowed to overlap.
-    Permitted {
-        /// Whether or not the impl is permitted due to the trait being a `#[marker]` trait
-        marker: bool,
-    },
-    /// These impls are allowed to overlap, but that raises
-    /// an issue #33140 future-compatibility warning.
-    ///
-    /// Some background: in Rust 1.0, the trait-object types `Send + Sync` (today's
-    /// `dyn Send + Sync`) and `Sync + Send` (now `dyn Sync + Send`) were different.
-    ///
-    /// The widely-used version 0.1.0 of the crate `traitobject` had accidentally relied
-    /// that difference, making what reduces to the following set of impls:
-    ///
-    /// ```
-    /// trait Trait {}
-    /// impl Trait for dyn Send + Sync {}
-    /// impl Trait for dyn Sync + Send {}
-    /// ```
-    ///
-    /// Obviously, once we made these types be identical, that code causes a coherence
-    /// error and a fairly big headache for us. However, luckily for us, the trait
-    /// `Trait` used in this case is basically a marker trait, and therefore having
-    /// overlapping impls for it is sound.
-    ///
-    /// To handle this, we basically regard the trait as a marker trait, with an additional
-    /// future-compatibility warning. To avoid accidentally "stabilizing" this feature,
-    /// it has the following restrictions:
-    ///
-    /// 1. The trait must indeed be a marker-like trait (i.e., no items), and must be
-    /// positive impls.
-    /// 2. The trait-ref of both impls must be equal.
-    /// 3. The trait-ref of both impls must be a trait object type consisting only of
-    /// marker traits.
-    /// 4. Neither of the impls can have any where-clauses.
-    ///
-    /// Once `traitobject` 0.1.0 is no longer an active concern, this hack can be removed.
-    Issue33140,
-}
-
-impl<'tcx> TyCtxt<'tcx> {
-    pub fn body_tables(self, body: hir::BodyId) -> &'tcx TypeckTables<'tcx> {
-        self.typeck_tables_of(self.hir().body_owner_def_id(body))
-    }
-
-    /// Returns an iterator of the `DefId`s for all body-owners in this
-    /// crate. If you would prefer to iterate over the bodies
-    /// themselves, you can do `self.hir().krate().body_ids.iter()`.
-    pub fn body_owners(self) -> impl Iterator<Item = DefId> + Captures<'tcx> + 'tcx {
-        self.hir()
-            .krate()
-            .body_ids
-            .iter()
-            .map(move |&body_id| self.hir().body_owner_def_id(body_id))
-    }
-
-    pub fn par_body_owners<F: Fn(DefId) + sync::Sync + sync::Send>(self, f: F) {
-        par_iter(&self.hir().krate().body_ids)
-            .for_each(|&body_id| f(self.hir().body_owner_def_id(body_id)));
-    }
-
-    pub fn provided_trait_methods(self, id: DefId) -> impl 'tcx + Iterator<Item = &'tcx AssocItem> {
-        self.associated_items(id)
-            .in_definition_order()
-            .filter(|item| item.kind == AssocKind::Method && item.defaultness.has_value())
-    }
-
-    pub fn trait_relevant_for_never(self, did: DefId) -> bool {
-        self.associated_items(did).in_definition_order().any(|item| item.relevant_for_never())
-    }
-
-    pub fn opt_item_name(self, def_id: DefId) -> Option<Ident> {
-        self.hir().as_local_hir_id(def_id).and_then(|hir_id| self.hir().get(hir_id).ident())
-    }
-
-    pub fn opt_associated_item(self, def_id: DefId) -> Option<AssocItem> {
-        let is_associated_item = if let Some(hir_id) = self.hir().as_local_hir_id(def_id) {
-            match self.hir().get(hir_id) {
-                Node::TraitItem(_) | Node::ImplItem(_) => true,
-                _ => false,
-            }
-        } else {
-            match self.def_kind(def_id).expect("no def for `DefId`") {
-                DefKind::AssocConst | DefKind::Method | DefKind::AssocTy => true,
-                _ => false,
-            }
-        };
-
-        is_associated_item.then(|| self.associated_item(def_id))
-    }
-
-    pub fn field_index(self, hir_id: hir::HirId, tables: &TypeckTables<'_>) -> usize {
-        tables.field_indices().get(hir_id).cloned().expect("no index for a field")
-    }
-
-    pub fn find_field_index(self, ident: Ident, variant: &VariantDef) -> Option<usize> {
-        variant.fields.iter().position(|field| self.hygienic_eq(ident, field.ident, variant.def_id))
-    }
-
-    /// Returns `true` if the impls are the same polarity and the trait either
-    /// has no items or is annotated #[marker] and prevents item overrides.
-    pub fn impls_are_allowed_to_overlap(
-        self,
-        def_id1: DefId,
-        def_id2: DefId,
-    ) -> Option<ImplOverlapKind> {
-        // If either trait impl references an error, they're allowed to overlap,
-        // as one of them essentially doesn't exist.
-        if self.impl_trait_ref(def_id1).map_or(false, |tr| tr.references_error())
-            || self.impl_trait_ref(def_id2).map_or(false, |tr| tr.references_error())
-        {
-            return Some(ImplOverlapKind::Permitted { marker: false });
-        }
-
-        match (self.impl_polarity(def_id1), self.impl_polarity(def_id2)) {
-            (ImplPolarity::Reservation, _) | (_, ImplPolarity::Reservation) => {
-                // `#[rustc_reservation_impl]` impls don't overlap with anything
-                debug!(
-                    "impls_are_allowed_to_overlap({:?}, {:?}) = Some(Permitted) (reservations)",
-                    def_id1, def_id2
-                );
-                return Some(ImplOverlapKind::Permitted { marker: false });
-            }
-            (ImplPolarity::Positive, ImplPolarity::Negative)
-            | (ImplPolarity::Negative, ImplPolarity::Positive) => {
-                // `impl AutoTrait for Type` + `impl !AutoTrait for Type`
-                debug!(
-                    "impls_are_allowed_to_overlap({:?}, {:?}) - None (differing polarities)",
-                    def_id1, def_id2
-                );
-                return None;
-            }
-            (ImplPolarity::Positive, ImplPolarity::Positive)
-            | (ImplPolarity::Negative, ImplPolarity::Negative) => {}
-        };
-
-        let is_marker_overlap = {
-            let is_marker_impl = |def_id: DefId| -> bool {
-                let trait_ref = self.impl_trait_ref(def_id);
-                trait_ref.map_or(false, |tr| self.trait_def(tr.def_id).is_marker)
-            };
-            is_marker_impl(def_id1) && is_marker_impl(def_id2)
-        };
-
-        if is_marker_overlap {
-            debug!(
-                "impls_are_allowed_to_overlap({:?}, {:?}) = Some(Permitted) (marker overlap)",
-                def_id1, def_id2
-            );
-            Some(ImplOverlapKind::Permitted { marker: true })
-        } else {
-            if let Some(self_ty1) = self.issue33140_self_ty(def_id1) {
-                if let Some(self_ty2) = self.issue33140_self_ty(def_id2) {
-                    if self_ty1 == self_ty2 {
-                        debug!(
-                            "impls_are_allowed_to_overlap({:?}, {:?}) - issue #33140 HACK",
-                            def_id1, def_id2
-                        );
-                        return Some(ImplOverlapKind::Issue33140);
-                    } else {
-                        debug!(
-                            "impls_are_allowed_to_overlap({:?}, {:?}) - found {:?} != {:?}",
-                            def_id1, def_id2, self_ty1, self_ty2
-                        );
-                    }
-                }
-            }
-
-            debug!("impls_are_allowed_to_overlap({:?}, {:?}) = None", def_id1, def_id2);
-            None
-        }
-    }
-
-    /// Returns `ty::VariantDef` if `res` refers to a struct,
-    /// or variant or their constructors, panics otherwise.
-    pub fn expect_variant_res(self, res: Res) -> &'tcx VariantDef {
-        match res {
-            Res::Def(DefKind::Variant, did) => {
-                let enum_did = self.parent(did).unwrap();
-                self.adt_def(enum_did).variant_with_id(did)
-            }
-            Res::Def(DefKind::Struct, did) | Res::Def(DefKind::Union, did) => {
-                self.adt_def(did).non_enum_variant()
-            }
-            Res::Def(DefKind::Ctor(CtorOf::Variant, ..), variant_ctor_did) => {
-                let variant_did = self.parent(variant_ctor_did).unwrap();
-                let enum_did = self.parent(variant_did).unwrap();
-                self.adt_def(enum_did).variant_with_ctor_id(variant_ctor_did)
-            }
-            Res::Def(DefKind::Ctor(CtorOf::Struct, ..), ctor_did) => {
-                let struct_did = self.parent(ctor_did).expect("struct ctor has no parent");
-                self.adt_def(struct_did).non_enum_variant()
-            }
-            _ => bug!("expect_variant_res used with unexpected res {:?}", res),
-        }
-    }
-
-    pub fn item_name(self, id: DefId) -> Symbol {
-        if id.index == CRATE_DEF_INDEX {
-            self.original_crate_name(id.krate)
-        } else {
-            let def_key = self.def_key(id);
-            match def_key.disambiguated_data.data {
-                // The name of a constructor is that of its parent.
-                hir_map::DefPathData::Ctor => {
-                    self.item_name(DefId { krate: id.krate, index: def_key.parent.unwrap() })
-                }
-                _ => def_key.disambiguated_data.data.get_opt_name().unwrap_or_else(|| {
-                    bug!("item_name: no name for {:?}", self.def_path(id));
-                }),
-            }
-        }
-    }
-
-    /// Returns the possibly-auto-generated MIR of a `(DefId, Subst)` pair.
-    pub fn instance_mir(self, instance: ty::InstanceDef<'tcx>) -> ReadOnlyBodyAndCache<'tcx, 'tcx> {
-        match instance {
-            ty::InstanceDef::Item(did) => self.optimized_mir(did).unwrap_read_only(),
-            ty::InstanceDef::VtableShim(..)
-            | ty::InstanceDef::ReifyShim(..)
-            | ty::InstanceDef::Intrinsic(..)
-            | ty::InstanceDef::FnPtrShim(..)
-            | ty::InstanceDef::Virtual(..)
-            | ty::InstanceDef::ClosureOnceShim { .. }
-            | ty::InstanceDef::DropGlue(..)
-            | ty::InstanceDef::CloneShim(..) => self.mir_shims(instance).unwrap_read_only(),
-        }
-    }
-
-    /// Gets the attributes of a definition.
-    pub fn get_attrs(self, did: DefId) -> Attributes<'tcx> {
-        if let Some(id) = self.hir().as_local_hir_id(did) {
-            Attributes::Borrowed(self.hir().attrs(id))
-        } else {
-            Attributes::Owned(self.item_attrs(did))
-        }
-    }
-
-    /// Determines whether an item is annotated with an attribute.
-    pub fn has_attr(self, did: DefId, attr: Symbol) -> bool {
-        attr::contains_name(&self.get_attrs(did), attr)
-    }
-
-    /// Returns `true` if this is an `auto trait`.
-    pub fn trait_is_auto(self, trait_def_id: DefId) -> bool {
-        self.trait_def(trait_def_id).has_auto_impl
-    }
-
-    pub fn generator_layout(self, def_id: DefId) -> &'tcx GeneratorLayout<'tcx> {
-        self.optimized_mir(def_id).generator_layout.as_ref().unwrap()
-    }
-
-    /// Given the `DefId` of an impl, returns the `DefId` of the trait it implements.
-    /// If it implements no trait, returns `None`.
-    pub fn trait_id_of_impl(self, def_id: DefId) -> Option<DefId> {
-        self.impl_trait_ref(def_id).map(|tr| tr.def_id)
-    }
-
-    /// If the given defid describes a method belonging to an impl, returns the
-    /// `DefId` of the impl that the method belongs to; otherwise, returns `None`.
-    pub fn impl_of_method(self, def_id: DefId) -> Option<DefId> {
-        let item = if def_id.krate != LOCAL_CRATE {
-            if let Some(DefKind::Method) = self.def_kind(def_id) {
-                Some(self.associated_item(def_id))
-            } else {
-                None
-            }
-        } else {
-            self.opt_associated_item(def_id)
-        };
-
-        item.and_then(|trait_item| match trait_item.container {
-            TraitContainer(_) => None,
-            ImplContainer(def_id) => Some(def_id),
-        })
-    }
-
-    /// Looks up the span of `impl_did` if the impl is local; otherwise returns `Err`
-    /// with the name of the crate containing the impl.
-    pub fn span_of_impl(self, impl_did: DefId) -> Result<Span, Symbol> {
-        if impl_did.is_local() {
-            let hir_id = self.hir().as_local_hir_id(impl_did).unwrap();
-            Ok(self.hir().span(hir_id))
-        } else {
-            Err(self.crate_name(impl_did.krate))
-        }
-    }
-
-    /// Hygienically compares a use-site name (`use_name`) for a field or an associated item with
-    /// its supposed definition name (`def_name`). The method also needs `DefId` of the supposed
-    /// definition's parent/scope to perform comparison.
-    pub fn hygienic_eq(self, use_name: Ident, def_name: Ident, def_parent_def_id: DefId) -> bool {
-        // We could use `Ident::eq` here, but we deliberately don't. The name
-        // comparison fails frequently, and we want to avoid the expensive
-        // `modern()` calls required for the span comparison whenever possible.
-        use_name.name == def_name.name
-            && use_name
-                .span
-                .ctxt()
-                .hygienic_eq(def_name.span.ctxt(), self.expansion_that_defined(def_parent_def_id))
-    }
-
-    fn expansion_that_defined(self, scope: DefId) -> ExpnId {
-        match scope.krate {
-            LOCAL_CRATE => self.hir().definitions().expansion_that_defined(scope.index),
-            _ => ExpnId::root(),
-        }
-    }
-
-    pub fn adjust_ident(self, mut ident: Ident, scope: DefId) -> Ident {
-        ident.span.modernize_and_adjust(self.expansion_that_defined(scope));
-        ident
-    }
-
-    pub fn adjust_ident_and_get_scope(
-        self,
-        mut ident: Ident,
-        scope: DefId,
-        block: hir::HirId,
-    ) -> (Ident, DefId) {
-        let scope = match ident.span.modernize_and_adjust(self.expansion_that_defined(scope)) {
-            Some(actual_expansion) => {
-                self.hir().definitions().parent_module_of_macro_def(actual_expansion)
-            }
-            None => self.hir().get_module_parent(block),
-        };
-        (ident, scope)
-    }
-
-    pub fn is_object_safe(self, key: DefId) -> bool {
-        self.object_safety_violations(key).is_empty()
-    }
-}
-
-#[derive(Clone, HashStable)]
-pub struct AdtSizedConstraint<'tcx>(pub &'tcx [Ty<'tcx>]);
-
-/// Yields the parent function's `DefId` if `def_id` is an `impl Trait` definition.
-pub fn is_impl_trait_defn(tcx: TyCtxt<'_>, def_id: DefId) -> Option<DefId> {
-    if let Some(hir_id) = tcx.hir().as_local_hir_id(def_id) {
-        if let Node::Item(item) = tcx.hir().get(hir_id) {
-            if let hir::ItemKind::OpaqueTy(ref opaque_ty) = item.kind {
-                return opaque_ty.impl_trait_fn;
-            }
-        }
-    }
-    None
-}
-
-pub fn provide(providers: &mut ty::query::Providers<'_>) {
-    context::provide(providers);
-    erase_regions::provide(providers);
-    layout::provide(providers);
-    *providers =
-        ty::query::Providers { trait_impls_of: trait_def::trait_impls_of_provider, ..*providers };
-}
-
-/// A map for the local crate mapping each type to a vector of its
-/// inherent impls. This is not meant to be used outside of coherence;
-/// rather, you should request the vector for a specific type via
-/// `tcx.inherent_impls(def_id)` so as to minimize your dependencies
-/// (constructing this map requires touching the entire crate).
-#[derive(Clone, Debug, Default, HashStable)]
-pub struct CrateInherentImpls {
-    pub inherent_impls: DefIdMap<Vec<DefId>>,
-}
-
-#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
-pub struct SymbolName {
-    // FIXME: we don't rely on interning or equality here - better have
-    // this be a `&'tcx str`.
-    pub name: Symbol,
-}
-
-impl SymbolName {
-    pub fn new(name: &str) -> SymbolName {
-        SymbolName { name: Symbol::intern(name) }
-    }
-}
-
-impl PartialOrd for SymbolName {
-    fn partial_cmp(&self, other: &SymbolName) -> Option<Ordering> {
-        self.name.as_str().partial_cmp(&other.name.as_str())
-    }
-}
-
-/// Ordering must use the chars to ensure reproducible builds.
-impl Ord for SymbolName {
-    fn cmp(&self, other: &SymbolName) -> Ordering {
-        self.name.as_str().cmp(&other.name.as_str())
-    }
-}
-
-impl fmt::Display for SymbolName {
-    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-        fmt::Display::fmt(&self.name, fmt)
-    }
-}
-
-impl fmt::Debug for SymbolName {
-    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-        fmt::Display::fmt(&self.name, fmt)
-    }
-}
diff --git a/src/librustc/ty/normalize_erasing_regions.rs b/src/librustc/ty/normalize_erasing_regions.rs
deleted file mode 100644
index dc64482907f..00000000000
--- a/src/librustc/ty/normalize_erasing_regions.rs
+++ /dev/null
@@ -1,102 +0,0 @@
-//! Methods for normalizing when you don't care about regions (and
-//! aren't doing type inference). If either of those things don't
-//! apply to you, use `infcx.normalize(...)`.
-//!
-//! The methods in this file use a `TypeFolder` to recursively process
-//! contents, invoking the underlying
-//! `normalize_ty_after_erasing_regions` query for each type found
-//! within. (This underlying query is what is cached.)
-
-use crate::ty::fold::{TypeFoldable, TypeFolder};
-use crate::ty::subst::{Subst, SubstsRef};
-use crate::ty::{self, Ty, TyCtxt};
-
-impl<'tcx> TyCtxt<'tcx> {
-    /// Erase the regions in `value` and then fully normalize all the
-    /// types found within. The result will also have regions erased.
-    ///
-    /// This is appropriate to use only after type-check: it assumes
-    /// that normalization will succeed, for example.
-    pub fn normalize_erasing_regions<T>(self, param_env: ty::ParamEnv<'tcx>, value: T) -> T
-    where
-        T: TypeFoldable<'tcx>,
-    {
-        debug!(
-            "normalize_erasing_regions::<{}>(value={:?}, param_env={:?})",
-            ::std::any::type_name::<T>(),
-            value,
-            param_env,
-        );
-
-        // Erase first before we do the real query -- this keeps the
-        // cache from being too polluted.
-        let value = self.erase_regions(&value);
-        if !value.has_projections() {
-            value
-        } else {
-            value.fold_with(&mut NormalizeAfterErasingRegionsFolder {
-                tcx: self,
-                param_env: param_env,
-            })
-        }
-    }
-
-    /// If you have a `Binder<T>`, you can do this to strip out the
-    /// late-bound regions and then normalize the result, yielding up
-    /// a `T` (with regions erased). This is appropriate when the
-    /// binder is being instantiated at the call site.
-    ///
-    /// N.B., currently, higher-ranked type bounds inhibit
-    /// normalization. Therefore, each time we erase them in
-    /// codegen, we need to normalize the contents.
-    pub fn normalize_erasing_late_bound_regions<T>(
-        self,
-        param_env: ty::ParamEnv<'tcx>,
-        value: &ty::Binder<T>,
-    ) -> T
-    where
-        T: TypeFoldable<'tcx>,
-    {
-        assert!(!value.needs_subst());
-        let value = self.erase_late_bound_regions(value);
-        self.normalize_erasing_regions(param_env, value)
-    }
-
-    /// Monomorphizes a type from the AST by first applying the
-    /// in-scope substitutions and then normalizing any associated
-    /// types.
-    pub fn subst_and_normalize_erasing_regions<T>(
-        self,
-        param_substs: SubstsRef<'tcx>,
-        param_env: ty::ParamEnv<'tcx>,
-        value: &T,
-    ) -> T
-    where
-        T: TypeFoldable<'tcx>,
-    {
-        debug!(
-            "subst_and_normalize_erasing_regions(\
-             param_substs={:?}, \
-             value={:?}, \
-             param_env={:?})",
-            param_substs, value, param_env,
-        );
-        let substituted = value.subst(self, param_substs);
-        self.normalize_erasing_regions(param_env, substituted)
-    }
-}
-
-struct NormalizeAfterErasingRegionsFolder<'tcx> {
-    tcx: TyCtxt<'tcx>,
-    param_env: ty::ParamEnv<'tcx>,
-}
-
-impl TypeFolder<'tcx> for NormalizeAfterErasingRegionsFolder<'tcx> {
-    fn tcx(&self) -> TyCtxt<'tcx> {
-        self.tcx
-    }
-
-    fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
-        self.tcx.normalize_ty_after_erasing_regions(self.param_env.and(ty))
-    }
-}
diff --git a/src/librustc/ty/outlives.rs b/src/librustc/ty/outlives.rs
deleted file mode 100644
index b397a2c80d5..00000000000
--- a/src/librustc/ty/outlives.rs
+++ /dev/null
@@ -1,178 +0,0 @@
-// The outlines relation `T: 'a` or `'a: 'b`. This code frequently
-// refers to rules defined in RFC 1214 (`OutlivesFooBar`), so see that
-// RFC for reference.
-
-use crate::ty::{self, Ty, TyCtxt, TypeFoldable};
-use smallvec::SmallVec;
-
-#[derive(Debug)]
-pub enum Component<'tcx> {
-    Region(ty::Region<'tcx>),
-    Param(ty::ParamTy),
-    UnresolvedInferenceVariable(ty::InferTy),
-
-    // Projections like `T::Foo` are tricky because a constraint like
-    // `T::Foo: 'a` can be satisfied in so many ways. There may be a
-    // where-clause that says `T::Foo: 'a`, or the defining trait may
-    // include a bound like `type Foo: 'static`, or -- in the most
-    // conservative way -- we can prove that `T: 'a` (more generally,
-    // that all components in the projection outlive `'a`). This code
-    // is not in a position to judge which is the best technique, so
-    // we just product the projection as a component and leave it to
-    // the consumer to decide (but see `EscapingProjection` below).
-    Projection(ty::ProjectionTy<'tcx>),
-
-    // In the case where a projection has escaping regions -- meaning
-    // regions bound within the type itself -- we always use
-    // the most conservative rule, which requires that all components
-    // outlive the bound. So for example if we had a type like this:
-    //
-    //     for<'a> Trait1<  <T as Trait2<'a,'b>>::Foo  >
-    //                      ~~~~~~~~~~~~~~~~~~~~~~~~~
-    //
-    // then the inner projection (underlined) has an escaping region
-    // `'a`. We consider that outer trait `'c` to meet a bound if `'b`
-    // outlives `'b: 'c`, and we don't consider whether the trait
-    // declares that `Foo: 'static` etc. Therefore, we just return the
-    // free components of such a projection (in this case, `'b`).
-    //
-    // However, in the future, we may want to get smarter, and
-    // actually return a "higher-ranked projection" here. Therefore,
-    // we mark that these components are part of an escaping
-    // projection, so that implied bounds code can avoid relying on
-    // them. This gives us room to improve the regionck reasoning in
-    // the future without breaking backwards compat.
-    EscapingProjection(Vec<Component<'tcx>>),
-}
-
-impl<'tcx> TyCtxt<'tcx> {
-    /// Push onto `out` all the things that must outlive `'a` for the condition
-    /// `ty0: 'a` to hold. Note that `ty0` must be a **fully resolved type**.
-    pub fn push_outlives_components(self, ty0: Ty<'tcx>, out: &mut SmallVec<[Component<'tcx>; 4]>) {
-        compute_components(self, ty0, out);
-        debug!("components({:?}) = {:?}", ty0, out);
-    }
-}
-
-fn compute_components(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, out: &mut SmallVec<[Component<'tcx>; 4]>) {
-    // Descend through the types, looking for the various "base"
-    // components and collecting them into `out`. This is not written
-    // with `collect()` because of the need to sometimes skip subtrees
-    // in the `subtys` iterator (e.g., when encountering a
-    // projection).
-    match ty.kind {
-            ty::Closure(def_id, ref substs) => {
-                for upvar_ty in substs.as_closure().upvar_tys(def_id, tcx) {
-                    compute_components(tcx, upvar_ty, out);
-                }
-            }
-
-            ty::Generator(def_id, ref substs, _) => {
-                // Same as the closure case
-                for upvar_ty in substs.as_generator().upvar_tys(def_id, tcx) {
-                    compute_components(tcx, upvar_ty, out);
-                }
-
-                // We ignore regions in the generator interior as we don't
-                // want these to affect region inference
-            }
-
-            // All regions are bound inside a witness
-            ty::GeneratorWitness(..) => (),
-
-            // OutlivesTypeParameterEnv -- the actual checking that `X:'a`
-            // is implied by the environment is done in regionck.
-            ty::Param(p) => {
-                out.push(Component::Param(p));
-            }
-
-            // For projections, we prefer to generate an obligation like
-            // `<P0 as Trait<P1...Pn>>::Foo: 'a`, because this gives the
-            // regionck more ways to prove that it holds. However,
-            // regionck is not (at least currently) prepared to deal with
-            // higher-ranked regions that may appear in the
-            // trait-ref. Therefore, if we see any higher-ranke regions,
-            // we simply fallback to the most restrictive rule, which
-            // requires that `Pi: 'a` for all `i`.
-            ty::Projection(ref data) => {
-                if !data.has_escaping_bound_vars() {
-                    // best case: no escaping regions, so push the
-                    // projection and skip the subtree (thus generating no
-                    // constraints for Pi). This defers the choice between
-                    // the rules OutlivesProjectionEnv,
-                    // OutlivesProjectionTraitDef, and
-                    // OutlivesProjectionComponents to regionck.
-                    out.push(Component::Projection(*data));
-                } else {
-                    // fallback case: hard code
-                    // OutlivesProjectionComponents.  Continue walking
-                    // through and constrain Pi.
-                    let subcomponents = capture_components(tcx, ty);
-                    out.push(Component::EscapingProjection(subcomponents));
-                }
-            }
-
-            ty::UnnormalizedProjection(..) => bug!("only used with chalk-engine"),
-
-            // We assume that inference variables are fully resolved.
-            // So, if we encounter an inference variable, just record
-            // the unresolved variable as a component.
-            ty::Infer(infer_ty) => {
-                out.push(Component::UnresolvedInferenceVariable(infer_ty));
-            }
-
-            // Most types do not introduce any region binders, nor
-            // involve any other subtle cases, and so the WF relation
-            // simply constraints any regions referenced directly by
-            // the type and then visits the types that are lexically
-            // contained within. (The comments refer to relevant rules
-            // from RFC1214.)
-            ty::Bool |            // OutlivesScalar
-            ty::Char |            // OutlivesScalar
-            ty::Int(..) |         // OutlivesScalar
-            ty::Uint(..) |        // OutlivesScalar
-            ty::Float(..) |       // OutlivesScalar
-            ty::Never |           // ...
-            ty::Adt(..) |         // OutlivesNominalType
-            ty::Opaque(..) |        // OutlivesNominalType (ish)
-            ty::Foreign(..) |     // OutlivesNominalType
-            ty::Str |             // OutlivesScalar (ish)
-            ty::Array(..) |       // ...
-            ty::Slice(..) |       // ...
-            ty::RawPtr(..) |      // ...
-            ty::Ref(..) |         // OutlivesReference
-            ty::Tuple(..) |       // ...
-            ty::FnDef(..) |       // OutlivesFunction (*)
-            ty::FnPtr(_) |        // OutlivesFunction (*)
-            ty::Dynamic(..) |       // OutlivesObject, OutlivesFragment (*)
-            ty::Placeholder(..) |
-            ty::Bound(..) |
-            ty::Error => {
-                // (*) Bare functions and traits are both binders. In the
-                // RFC, this means we would add the bound regions to the
-                // "bound regions list".  In our representation, no such
-                // list is maintained explicitly, because bound regions
-                // themselves can be readily identified.
-
-                push_region_constraints(ty, out);
-                for subty in ty.walk_shallow() {
-                    compute_components(tcx, subty, out);
-                }
-            }
-        }
-}
-
-fn capture_components(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Vec<Component<'tcx>> {
-    let mut temp = smallvec![];
-    push_region_constraints(ty, &mut temp);
-    for subty in ty.walk_shallow() {
-        compute_components(tcx, subty, &mut temp);
-    }
-    temp.into_iter().collect()
-}
-
-fn push_region_constraints<'tcx>(ty: Ty<'tcx>, out: &mut SmallVec<[Component<'tcx>; 4]>) {
-    let mut regions = smallvec![];
-    ty.push_regions(&mut regions);
-    out.extend(regions.iter().filter(|&r| !r.is_late_bound()).map(|r| Component::Region(r)));
-}
diff --git a/src/librustc/ty/print/mod.rs b/src/librustc/ty/print/mod.rs
deleted file mode 100644
index 3ade9661917..00000000000
--- a/src/librustc/ty/print/mod.rs
+++ /dev/null
@@ -1,347 +0,0 @@
-use crate::hir::map::{DefPathData, DisambiguatedDefPathData};
-use crate::ty::subst::{GenericArg, Subst};
-use crate::ty::{self, DefIdTree, Ty, TyCtxt};
-
-use rustc_data_structures::fx::FxHashSet;
-use rustc_hir::def_id::{CrateNum, DefId};
-
-// `pretty` is a separate module only for organization.
-mod pretty;
-pub use self::pretty::*;
-
-pub mod obsolete;
-
-// FIXME(eddyb) false positive, the lifetime parameters are used with `P:  Printer<...>`.
-#[allow(unused_lifetimes)]
-pub trait Print<'tcx, P> {
-    type Output;
-    type Error;
-
-    fn print(&self, cx: P) -> Result<Self::Output, Self::Error>;
-}
-
-/// Interface for outputting user-facing "type-system entities"
-/// (paths, types, lifetimes, constants, etc.) as a side-effect
-/// (e.g. formatting, like `PrettyPrinter` implementors do) or by
-/// constructing some alternative representation (e.g. an AST),
-/// which the associated types allow passing through the methods.
-///
-/// For pretty-printing/formatting in particular, see `PrettyPrinter`.
-//
-// FIXME(eddyb) find a better name; this is more general than "printing".
-pub trait Printer<'tcx>: Sized {
-    type Error;
-
-    type Path;
-    type Region;
-    type Type;
-    type DynExistential;
-    type Const;
-
-    fn tcx(&'a self) -> TyCtxt<'tcx>;
-
-    fn print_def_path(
-        self,
-        def_id: DefId,
-        substs: &'tcx [GenericArg<'tcx>],
-    ) -> Result<Self::Path, Self::Error> {
-        self.default_print_def_path(def_id, substs)
-    }
-
-    fn print_impl_path(
-        self,
-        impl_def_id: DefId,
-        substs: &'tcx [GenericArg<'tcx>],
-        self_ty: Ty<'tcx>,
-        trait_ref: Option<ty::TraitRef<'tcx>>,
-    ) -> Result<Self::Path, Self::Error> {
-        self.default_print_impl_path(impl_def_id, substs, self_ty, trait_ref)
-    }
-
-    fn print_region(self, region: ty::Region<'_>) -> Result<Self::Region, Self::Error>;
-
-    fn print_type(self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error>;
-
-    fn print_dyn_existential(
-        self,
-        predicates: &'tcx ty::List<ty::ExistentialPredicate<'tcx>>,
-    ) -> Result<Self::DynExistential, Self::Error>;
-
-    fn print_const(self, ct: &'tcx ty::Const<'tcx>) -> Result<Self::Const, Self::Error>;
-
-    fn path_crate(self, cnum: CrateNum) -> Result<Self::Path, Self::Error>;
-
-    fn path_qualified(
-        self,
-        self_ty: Ty<'tcx>,
-        trait_ref: Option<ty::TraitRef<'tcx>>,
-    ) -> Result<Self::Path, Self::Error>;
-
-    fn path_append_impl(
-        self,
-        print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
-        disambiguated_data: &DisambiguatedDefPathData,
-        self_ty: Ty<'tcx>,
-        trait_ref: Option<ty::TraitRef<'tcx>>,
-    ) -> Result<Self::Path, Self::Error>;
-
-    fn path_append(
-        self,
-        print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
-        disambiguated_data: &DisambiguatedDefPathData,
-    ) -> Result<Self::Path, Self::Error>;
-
-    fn path_generic_args(
-        self,
-        print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
-        args: &[GenericArg<'tcx>],
-    ) -> Result<Self::Path, Self::Error>;
-
-    // Defaults (should not be overriden):
-
-    fn default_print_def_path(
-        self,
-        def_id: DefId,
-        substs: &'tcx [GenericArg<'tcx>],
-    ) -> Result<Self::Path, Self::Error> {
-        debug!("default_print_def_path: def_id={:?}, substs={:?}", def_id, substs);
-        let key = self.tcx().def_key(def_id);
-        debug!("default_print_def_path: key={:?}", key);
-
-        match key.disambiguated_data.data {
-            DefPathData::CrateRoot => {
-                assert!(key.parent.is_none());
-                self.path_crate(def_id.krate)
-            }
-
-            DefPathData::Impl => {
-                let generics = self.tcx().generics_of(def_id);
-                let mut self_ty = self.tcx().type_of(def_id);
-                let mut impl_trait_ref = self.tcx().impl_trait_ref(def_id);
-                if substs.len() >= generics.count() {
-                    self_ty = self_ty.subst(self.tcx(), substs);
-                    impl_trait_ref = impl_trait_ref.subst(self.tcx(), substs);
-                }
-                self.print_impl_path(def_id, substs, self_ty, impl_trait_ref)
-            }
-
-            _ => {
-                let parent_def_id = DefId { index: key.parent.unwrap(), ..def_id };
-
-                let mut parent_substs = substs;
-                let mut trait_qualify_parent = false;
-                if !substs.is_empty() {
-                    let generics = self.tcx().generics_of(def_id);
-                    parent_substs = &substs[..generics.parent_count.min(substs.len())];
-
-                    match key.disambiguated_data.data {
-                        // Closures' own generics are only captures, don't print them.
-                        DefPathData::ClosureExpr => {}
-
-                        // If we have any generic arguments to print, we do that
-                        // on top of the same path, but without its own generics.
-                        _ => {
-                            if !generics.params.is_empty() && substs.len() >= generics.count() {
-                                let args = self.generic_args_to_print(generics, substs);
-                                return self.path_generic_args(
-                                    |cx| cx.print_def_path(def_id, parent_substs),
-                                    args,
-                                );
-                            }
-                        }
-                    }
-
-                    // FIXME(eddyb) try to move this into the parent's printing
-                    // logic, instead of doing it when printing the child.
-                    trait_qualify_parent = generics.has_self
-                        && generics.parent == Some(parent_def_id)
-                        && parent_substs.len() == generics.parent_count
-                        && self.tcx().generics_of(parent_def_id).parent_count == 0;
-                }
-
-                self.path_append(
-                    |cx: Self| {
-                        if trait_qualify_parent {
-                            let trait_ref = ty::TraitRef::new(
-                                parent_def_id,
-                                cx.tcx().intern_substs(parent_substs),
-                            );
-                            cx.path_qualified(trait_ref.self_ty(), Some(trait_ref))
-                        } else {
-                            cx.print_def_path(parent_def_id, parent_substs)
-                        }
-                    },
-                    &key.disambiguated_data,
-                )
-            }
-        }
-    }
-
-    fn generic_args_to_print(
-        &self,
-        generics: &'tcx ty::Generics,
-        substs: &'tcx [GenericArg<'tcx>],
-    ) -> &'tcx [GenericArg<'tcx>] {
-        let mut own_params = generics.parent_count..generics.count();
-
-        // Don't print args for `Self` parameters (of traits).
-        if generics.has_self && own_params.start == 0 {
-            own_params.start = 1;
-        }
-
-        // Don't print args that are the defaults of their respective parameters.
-        own_params.end -= generics
-            .params
-            .iter()
-            .rev()
-            .take_while(|param| {
-                match param.kind {
-                    ty::GenericParamDefKind::Lifetime => false,
-                    ty::GenericParamDefKind::Type { has_default, .. } => {
-                        has_default
-                            && substs[param.index as usize]
-                                == GenericArg::from(
-                                    self.tcx().type_of(param.def_id).subst(self.tcx(), substs),
-                                )
-                    }
-                    ty::GenericParamDefKind::Const => false, // FIXME(const_generics:defaults)
-                }
-            })
-            .count();
-
-        &substs[own_params]
-    }
-
-    fn default_print_impl_path(
-        self,
-        impl_def_id: DefId,
-        _substs: &'tcx [GenericArg<'tcx>],
-        self_ty: Ty<'tcx>,
-        impl_trait_ref: Option<ty::TraitRef<'tcx>>,
-    ) -> Result<Self::Path, Self::Error> {
-        debug!(
-            "default_print_impl_path: impl_def_id={:?}, self_ty={}, impl_trait_ref={:?}",
-            impl_def_id, self_ty, impl_trait_ref
-        );
-
-        let key = self.tcx().def_key(impl_def_id);
-        let parent_def_id = DefId { index: key.parent.unwrap(), ..impl_def_id };
-
-        // Decide whether to print the parent path for the impl.
-        // Logically, since impls are global, it's never needed, but
-        // users may find it useful. Currently, we omit the parent if
-        // the impl is either in the same module as the self-type or
-        // as the trait.
-        let in_self_mod = match characteristic_def_id_of_type(self_ty) {
-            None => false,
-            Some(ty_def_id) => self.tcx().parent(ty_def_id) == Some(parent_def_id),
-        };
-        let in_trait_mod = match impl_trait_ref {
-            None => false,
-            Some(trait_ref) => self.tcx().parent(trait_ref.def_id) == Some(parent_def_id),
-        };
-
-        if !in_self_mod && !in_trait_mod {
-            // If the impl is not co-located with either self-type or
-            // trait-type, then fallback to a format that identifies
-            // the module more clearly.
-            self.path_append_impl(
-                |cx| cx.print_def_path(parent_def_id, &[]),
-                &key.disambiguated_data,
-                self_ty,
-                impl_trait_ref,
-            )
-        } else {
-            // Otherwise, try to give a good form that would be valid language
-            // syntax. Preferably using associated item notation.
-            self.path_qualified(self_ty, impl_trait_ref)
-        }
-    }
-}
-
-/// As a heuristic, when we see an impl, if we see that the
-/// 'self type' is a type defined in the same module as the impl,
-/// we can omit including the path to the impl itself. This
-/// function tries to find a "characteristic `DefId`" for a
-/// type. It's just a heuristic so it makes some questionable
-/// decisions and we may want to adjust it later.
-pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option<DefId> {
-    match ty.kind {
-        ty::Adt(adt_def, _) => Some(adt_def.did),
-
-        ty::Dynamic(data, ..) => data.principal_def_id(),
-
-        ty::Array(subty, _) | ty::Slice(subty) => characteristic_def_id_of_type(subty),
-
-        ty::RawPtr(mt) => characteristic_def_id_of_type(mt.ty),
-
-        ty::Ref(_, ty, _) => characteristic_def_id_of_type(ty),
-
-        ty::Tuple(ref tys) => {
-            tys.iter().filter_map(|ty| characteristic_def_id_of_type(ty.expect_ty())).next()
-        }
-
-        ty::FnDef(def_id, _)
-        | ty::Closure(def_id, _)
-        | ty::Generator(def_id, _, _)
-        | ty::Foreign(def_id) => Some(def_id),
-
-        ty::Bool
-        | ty::Char
-        | ty::Int(_)
-        | ty::Uint(_)
-        | ty::Str
-        | ty::FnPtr(_)
-        | ty::Projection(_)
-        | ty::Placeholder(..)
-        | ty::UnnormalizedProjection(..)
-        | ty::Param(_)
-        | ty::Opaque(..)
-        | ty::Infer(_)
-        | ty::Bound(..)
-        | ty::Error
-        | ty::GeneratorWitness(..)
-        | ty::Never
-        | ty::Float(_) => None,
-    }
-}
-
-impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> for ty::RegionKind {
-    type Output = P::Region;
-    type Error = P::Error;
-    fn print(&self, cx: P) -> Result<Self::Output, Self::Error> {
-        cx.print_region(self)
-    }
-}
-
-impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> for ty::Region<'_> {
-    type Output = P::Region;
-    type Error = P::Error;
-    fn print(&self, cx: P) -> Result<Self::Output, Self::Error> {
-        cx.print_region(self)
-    }
-}
-
-impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> for Ty<'tcx> {
-    type Output = P::Type;
-    type Error = P::Error;
-    fn print(&self, cx: P) -> Result<Self::Output, Self::Error> {
-        cx.print_type(self)
-    }
-}
-
-impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> for &'tcx ty::List<ty::ExistentialPredicate<'tcx>> {
-    type Output = P::DynExistential;
-    type Error = P::Error;
-    fn print(&self, cx: P) -> Result<Self::Output, Self::Error> {
-        cx.print_dyn_existential(self)
-    }
-}
-
-impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> for &'tcx ty::Const<'tcx> {
-    type Output = P::Const;
-    type Error = P::Error;
-    fn print(&self, cx: P) -> Result<Self::Output, Self::Error> {
-        cx.print_const(self)
-    }
-}
diff --git a/src/librustc/ty/print/obsolete.rs b/src/librustc/ty/print/obsolete.rs
deleted file mode 100644
index 7605d44c7f3..00000000000
--- a/src/librustc/ty/print/obsolete.rs
+++ /dev/null
@@ -1,250 +0,0 @@
-//! Allows for producing a unique string key for a mono item.
-//! These keys are used by the handwritten auto-tests, so they need to be
-//! predictable and human-readable.
-//!
-//! Note: A lot of this could looks very similar to what's already in `ty::print`.
-//! FIXME(eddyb) implement a custom `PrettyPrinter` for this.
-
-use rustc::bug;
-use rustc::ty::subst::SubstsRef;
-use rustc::ty::{self, Const, Instance, Ty, TyCtxt};
-use rustc_hir as hir;
-use rustc_hir::def_id::DefId;
-use std::fmt::Write;
-use std::iter;
-
-/// Same as `unique_type_name()` but with the result pushed onto the given
-/// `output` parameter.
-pub struct DefPathBasedNames<'tcx> {
-    tcx: TyCtxt<'tcx>,
-    omit_disambiguators: bool,
-    omit_local_crate_name: bool,
-}
-
-impl DefPathBasedNames<'tcx> {
-    pub fn new(tcx: TyCtxt<'tcx>, omit_disambiguators: bool, omit_local_crate_name: bool) -> Self {
-        DefPathBasedNames { tcx, omit_disambiguators, omit_local_crate_name }
-    }
-
-    // Pushes the type name of the specified type to the provided string.
-    // If `debug` is true, printing normally unprintable types is allowed
-    // (e.g. `ty::GeneratorWitness`). This parameter should only be set when
-    // this method is being used for logging purposes (e.g. with `debug!` or `info!`)
-    // When being used for codegen purposes, `debug` should be set to `false`
-    // in order to catch unexpected types that should never end up in a type name.
-    pub fn push_type_name(&self, t: Ty<'tcx>, output: &mut String, debug: bool) {
-        match t.kind {
-            ty::Bool => output.push_str("bool"),
-            ty::Char => output.push_str("char"),
-            ty::Str => output.push_str("str"),
-            ty::Never => output.push_str("!"),
-            ty::Int(ty) => output.push_str(ty.name_str()),
-            ty::Uint(ty) => output.push_str(ty.name_str()),
-            ty::Float(ty) => output.push_str(ty.name_str()),
-            ty::Adt(adt_def, substs) => {
-                self.push_def_path(adt_def.did, output);
-                self.push_generic_params(substs, iter::empty(), output, debug);
-            }
-            ty::Tuple(component_types) => {
-                output.push('(');
-                for &component_type in component_types {
-                    self.push_type_name(component_type.expect_ty(), output, debug);
-                    output.push_str(", ");
-                }
-                if !component_types.is_empty() {
-                    output.pop();
-                    output.pop();
-                }
-                output.push(')');
-            }
-            ty::RawPtr(ty::TypeAndMut { ty: inner_type, mutbl }) => {
-                output.push('*');
-                match mutbl {
-                    hir::Mutability::Not => output.push_str("const "),
-                    hir::Mutability::Mut => output.push_str("mut "),
-                }
-
-                self.push_type_name(inner_type, output, debug);
-            }
-            ty::Ref(_, inner_type, mutbl) => {
-                output.push('&');
-                output.push_str(mutbl.prefix_str());
-
-                self.push_type_name(inner_type, output, debug);
-            }
-            ty::Array(inner_type, len) => {
-                output.push('[');
-                self.push_type_name(inner_type, output, debug);
-                let len = len.eval_usize(self.tcx, ty::ParamEnv::reveal_all());
-                write!(output, "; {}", len).unwrap();
-                output.push(']');
-            }
-            ty::Slice(inner_type) => {
-                output.push('[');
-                self.push_type_name(inner_type, output, debug);
-                output.push(']');
-            }
-            ty::Dynamic(ref trait_data, ..) => {
-                if let Some(principal) = trait_data.principal() {
-                    self.push_def_path(principal.def_id(), output);
-                    self.push_generic_params(
-                        principal.skip_binder().substs,
-                        trait_data.projection_bounds(),
-                        output,
-                        debug,
-                    );
-                } else {
-                    output.push_str("dyn '_");
-                }
-            }
-            ty::Foreign(did) => self.push_def_path(did, output),
-            ty::FnDef(..) | ty::FnPtr(_) => {
-                let sig = t.fn_sig(self.tcx);
-                output.push_str(sig.unsafety().prefix_str());
-
-                let abi = sig.abi();
-                if abi != ::rustc_target::spec::abi::Abi::Rust {
-                    output.push_str("extern \"");
-                    output.push_str(abi.name());
-                    output.push_str("\" ");
-                }
-
-                output.push_str("fn(");
-
-                let sig =
-                    self.tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig);
-
-                if !sig.inputs().is_empty() {
-                    for &parameter_type in sig.inputs() {
-                        self.push_type_name(parameter_type, output, debug);
-                        output.push_str(", ");
-                    }
-                    output.pop();
-                    output.pop();
-                }
-
-                if sig.c_variadic {
-                    if !sig.inputs().is_empty() {
-                        output.push_str(", ...");
-                    } else {
-                        output.push_str("...");
-                    }
-                }
-
-                output.push(')');
-
-                if !sig.output().is_unit() {
-                    output.push_str(" -> ");
-                    self.push_type_name(sig.output(), output, debug);
-                }
-            }
-            ty::Generator(def_id, substs, _) | ty::Closure(def_id, substs) => {
-                self.push_def_path(def_id, output);
-                let generics = self.tcx.generics_of(self.tcx.closure_base_def_id(def_id));
-                let substs = substs.truncate_to(self.tcx, generics);
-                self.push_generic_params(substs, iter::empty(), output, debug);
-            }
-            ty::Error
-            | ty::Bound(..)
-            | ty::Infer(_)
-            | ty::Placeholder(..)
-            | ty::UnnormalizedProjection(..)
-            | ty::Projection(..)
-            | ty::Param(_)
-            | ty::GeneratorWitness(_)
-            | ty::Opaque(..) => {
-                if debug {
-                    output.push_str(&format!("`{:?}`", t));
-                } else {
-                    bug!(
-                        "DefPathBasedNames: trying to create type name for unexpected type: {:?}",
-                        t,
-                    );
-                }
-            }
-        }
-    }
-
-    // Pushes the the name of the specified const to the provided string.
-    // If `debug` is true, the unprintable types of constants will be printed with `fmt::Debug`
-    // (see `push_type_name` for more details).
-    pub fn push_const_name(&self, ct: &Const<'tcx>, output: &mut String, debug: bool) {
-        write!(output, "{}", ct).unwrap();
-        output.push_str(": ");
-        self.push_type_name(ct.ty, output, debug);
-    }
-
-    pub fn push_def_path(&self, def_id: DefId, output: &mut String) {
-        let def_path = self.tcx.def_path(def_id);
-
-        // some_crate::
-        if !(self.omit_local_crate_name && def_id.is_local()) {
-            output.push_str(&self.tcx.crate_name(def_path.krate).as_str());
-            output.push_str("::");
-        }
-
-        // foo::bar::ItemName::
-        for part in self.tcx.def_path(def_id).data {
-            if self.omit_disambiguators {
-                write!(output, "{}::", part.data.as_symbol()).unwrap();
-            } else {
-                write!(output, "{}[{}]::", part.data.as_symbol(), part.disambiguator).unwrap();
-            }
-        }
-
-        // remove final "::"
-        output.pop();
-        output.pop();
-    }
-
-    fn push_generic_params<I>(
-        &self,
-        substs: SubstsRef<'tcx>,
-        projections: I,
-        output: &mut String,
-        debug: bool,
-    ) where
-        I: Iterator<Item = ty::PolyExistentialProjection<'tcx>>,
-    {
-        let mut projections = projections.peekable();
-        if substs.non_erasable_generics().next().is_none() && projections.peek().is_none() {
-            return;
-        }
-
-        output.push('<');
-
-        for type_parameter in substs.types() {
-            self.push_type_name(type_parameter, output, debug);
-            output.push_str(", ");
-        }
-
-        for projection in projections {
-            let projection = projection.skip_binder();
-            let name = &self.tcx.associated_item(projection.item_def_id).ident.as_str();
-            output.push_str(name);
-            output.push_str("=");
-            self.push_type_name(projection.ty, output, debug);
-            output.push_str(", ");
-        }
-
-        for const_parameter in substs.consts() {
-            self.push_const_name(const_parameter, output, debug);
-            output.push_str(", ");
-        }
-
-        output.pop();
-        output.pop();
-
-        output.push('>');
-    }
-
-    pub fn push_instance_as_string(
-        &self,
-        instance: Instance<'tcx>,
-        output: &mut String,
-        debug: bool,
-    ) {
-        self.push_def_path(instance.def_id(), output);
-        self.push_generic_params(instance.substs, iter::empty(), output, debug);
-    }
-}
diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs
deleted file mode 100644
index 0726bf30d3b..00000000000
--- a/src/librustc/ty/print/pretty.rs
+++ /dev/null
@@ -1,1853 +0,0 @@
-use crate::hir::map::{DefPathData, DisambiguatedDefPathData};
-use crate::middle::cstore::{ExternCrate, ExternCrateSource};
-use crate::middle::region;
-use crate::mir::interpret::{sign_extend, truncate, ConstValue, Scalar};
-use crate::ty::layout::{Integer, IntegerExt, Size};
-use crate::ty::subst::{GenericArg, GenericArgKind, Subst};
-use crate::ty::{self, DefIdTree, ParamConst, Ty, TyCtxt, TypeFoldable};
-use rustc_hir as hir;
-use rustc_hir::def::{DefKind, Namespace};
-use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
-
-use rustc_apfloat::ieee::{Double, Single};
-use rustc_apfloat::Float;
-use rustc_attr::{SignedInt, UnsignedInt};
-use rustc_span::symbol::{kw, Symbol};
-use rustc_target::spec::abi::Abi;
-use syntax::ast;
-
-use std::cell::Cell;
-use std::collections::BTreeMap;
-use std::fmt::{self, Write as _};
-use std::ops::{Deref, DerefMut};
-
-// `pretty` is a separate module only for organization.
-use super::*;
-
-macro_rules! p {
-    (@write($($data:expr),+)) => {
-        write!(scoped_cx!(), $($data),+)?
-    };
-    (@print($x:expr)) => {
-        scoped_cx!() = $x.print(scoped_cx!())?
-    };
-    (@$method:ident($($arg:expr),*)) => {
-        scoped_cx!() = scoped_cx!().$method($($arg),*)?
-    };
-    ($($kind:ident $data:tt),+) => {{
-        $(p!(@$kind $data);)+
-    }};
-}
-macro_rules! define_scoped_cx {
-    ($cx:ident) => {
-        #[allow(unused_macros)]
-        macro_rules! scoped_cx {
-            () => {
-                $cx
-            };
-        }
-    };
-}
-
-thread_local! {
-    static FORCE_IMPL_FILENAME_LINE: Cell<bool> = Cell::new(false);
-    static SHOULD_PREFIX_WITH_CRATE: Cell<bool> = Cell::new(false);
-    static NO_QUERIES: Cell<bool> = Cell::new(false);
-}
-
-/// Avoids running any queries during any prints that occur
-/// during the closure. This may alter the appearance of some
-/// types (e.g. forcing verbose printing for opaque types).
-/// This method is used during some queries (e.g. `predicates_of`
-/// for opaque types), to ensure that any debug printing that
-/// occurs during the query computation does not end up recursively
-/// calling the same query.
-pub fn with_no_queries<F: FnOnce() -> R, R>(f: F) -> R {
-    NO_QUERIES.with(|no_queries| {
-        let old = no_queries.replace(true);
-        let result = f();
-        no_queries.set(old);
-        result
-    })
-}
-
-/// Force us to name impls with just the filename/line number. We
-/// normally try to use types. But at some points, notably while printing
-/// cycle errors, this can result in extra or suboptimal error output,
-/// so this variable disables that check.
-pub fn with_forced_impl_filename_line<F: FnOnce() -> R, R>(f: F) -> R {
-    FORCE_IMPL_FILENAME_LINE.with(|force| {
-        let old = force.replace(true);
-        let result = f();
-        force.set(old);
-        result
-    })
-}
-
-/// Adds the `crate::` prefix to paths where appropriate.
-pub fn with_crate_prefix<F: FnOnce() -> R, R>(f: F) -> R {
-    SHOULD_PREFIX_WITH_CRATE.with(|flag| {
-        let old = flag.replace(true);
-        let result = f();
-        flag.set(old);
-        result
-    })
-}
-
-/// The "region highlights" are used to control region printing during
-/// specific error messages. When a "region highlight" is enabled, it
-/// gives an alternate way to print specific regions. For now, we
-/// always print those regions using a number, so something like "`'0`".
-///
-/// Regions not selected by the region highlight mode are presently
-/// unaffected.
-#[derive(Copy, Clone, Default)]
-pub struct RegionHighlightMode {
-    /// If enabled, when we see the selected region, use "`'N`"
-    /// instead of the ordinary behavior.
-    highlight_regions: [Option<(ty::RegionKind, usize)>; 3],
-
-    /// If enabled, when printing a "free region" that originated from
-    /// the given `ty::BoundRegion`, print it as "`'1`". Free regions that would ordinarily
-    /// have names print as normal.
-    ///
-    /// This is used when you have a signature like `fn foo(x: &u32,
-    /// y: &'a u32)` and we want to give a name to the region of the
-    /// reference `x`.
-    highlight_bound_region: Option<(ty::BoundRegion, usize)>,
-}
-
-impl RegionHighlightMode {
-    /// If `region` and `number` are both `Some`, invokes
-    /// `highlighting_region`.
-    pub fn maybe_highlighting_region(
-        &mut self,
-        region: Option<ty::Region<'_>>,
-        number: Option<usize>,
-    ) {
-        if let Some(k) = region {
-            if let Some(n) = number {
-                self.highlighting_region(k, n);
-            }
-        }
-    }
-
-    /// Highlights the region inference variable `vid` as `'N`.
-    pub fn highlighting_region(&mut self, region: ty::Region<'_>, number: usize) {
-        let num_slots = self.highlight_regions.len();
-        let first_avail_slot =
-            self.highlight_regions.iter_mut().filter(|s| s.is_none()).next().unwrap_or_else(|| {
-                bug!("can only highlight {} placeholders at a time", num_slots,)
-            });
-        *first_avail_slot = Some((*region, number));
-    }
-
-    /// Convenience wrapper for `highlighting_region`.
-    pub fn highlighting_region_vid(&mut self, vid: ty::RegionVid, number: usize) {
-        self.highlighting_region(&ty::ReVar(vid), number)
-    }
-
-    /// Returns `Some(n)` with the number to use for the given region, if any.
-    fn region_highlighted(&self, region: ty::Region<'_>) -> Option<usize> {
-        self.highlight_regions
-            .iter()
-            .filter_map(|h| match h {
-                Some((r, n)) if r == region => Some(*n),
-                _ => None,
-            })
-            .next()
-    }
-
-    /// Highlight the given bound region.
-    /// We can only highlight one bound region at a time. See
-    /// the field `highlight_bound_region` for more detailed notes.
-    pub fn highlighting_bound_region(&mut self, br: ty::BoundRegion, number: usize) {
-        assert!(self.highlight_bound_region.is_none());
-        self.highlight_bound_region = Some((br, number));
-    }
-}
-
-/// Trait for printers that pretty-print using `fmt::Write` to the printer.
-pub trait PrettyPrinter<'tcx>:
-    Printer<
-        'tcx,
-        Error = fmt::Error,
-        Path = Self,
-        Region = Self,
-        Type = Self,
-        DynExistential = Self,
-        Const = Self,
-    > + fmt::Write
-{
-    /// Like `print_def_path` but for value paths.
-    fn print_value_path(
-        self,
-        def_id: DefId,
-        substs: &'tcx [GenericArg<'tcx>],
-    ) -> Result<Self::Path, Self::Error> {
-        self.print_def_path(def_id, substs)
-    }
-
-    fn in_binder<T>(self, value: &ty::Binder<T>) -> Result<Self, Self::Error>
-    where
-        T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx>,
-    {
-        value.skip_binder().print(self)
-    }
-
-    /// Prints comma-separated elements.
-    fn comma_sep<T>(mut self, mut elems: impl Iterator<Item = T>) -> Result<Self, Self::Error>
-    where
-        T: Print<'tcx, Self, Output = Self, Error = Self::Error>,
-    {
-        if let Some(first) = elems.next() {
-            self = first.print(self)?;
-            for elem in elems {
-                self.write_str(", ")?;
-                self = elem.print(self)?;
-            }
-        }
-        Ok(self)
-    }
-
-    /// Prints `<...>` around what `f` prints.
-    fn generic_delimiters(
-        self,
-        f: impl FnOnce(Self) -> Result<Self, Self::Error>,
-    ) -> Result<Self, Self::Error>;
-
-    /// Returns `true` if the region should be printed in
-    /// optional positions, e.g., `&'a T` or `dyn Tr + 'b`.
-    /// This is typically the case for all non-`'_` regions.
-    fn region_should_not_be_omitted(&self, region: ty::Region<'_>) -> bool;
-
-    // Defaults (should not be overriden):
-
-    /// If possible, this returns a global path resolving to `def_id` that is visible
-    /// from at least one local module, and returns `true`. If the crate defining `def_id` is
-    /// declared with an `extern crate`, the path is guaranteed to use the `extern crate`.
-    fn try_print_visible_def_path(self, def_id: DefId) -> Result<(Self, bool), Self::Error> {
-        let mut callers = Vec::new();
-        self.try_print_visible_def_path_recur(def_id, &mut callers)
-    }
-
-    /// Does the work of `try_print_visible_def_path`, building the
-    /// full definition path recursively before attempting to
-    /// post-process it into the valid and visible version that
-    /// accounts for re-exports.
-    ///
-    /// This method should only be callled by itself or
-    /// `try_print_visible_def_path`.
-    ///
-    /// `callers` is a chain of visible_parent's leading to `def_id`,
-    /// to support cycle detection during recursion.
-    fn try_print_visible_def_path_recur(
-        mut self,
-        def_id: DefId,
-        callers: &mut Vec<DefId>,
-    ) -> Result<(Self, bool), Self::Error> {
-        define_scoped_cx!(self);
-
-        debug!("try_print_visible_def_path: def_id={:?}", def_id);
-
-        // If `def_id` is a direct or injected extern crate, return the
-        // path to the crate followed by the path to the item within the crate.
-        if def_id.index == CRATE_DEF_INDEX {
-            let cnum = def_id.krate;
-
-            if cnum == LOCAL_CRATE {
-                return Ok((self.path_crate(cnum)?, true));
-            }
-
-            // In local mode, when we encounter a crate other than
-            // LOCAL_CRATE, execution proceeds in one of two ways:
-            //
-            // 1. For a direct dependency, where user added an
-            //    `extern crate` manually, we put the `extern
-            //    crate` as the parent. So you wind up with
-            //    something relative to the current crate.
-            // 2. For an extern inferred from a path or an indirect crate,
-            //    where there is no explicit `extern crate`, we just prepend
-            //    the crate name.
-            match self.tcx().extern_crate(def_id) {
-                Some(&ExternCrate {
-                    src: ExternCrateSource::Extern(def_id),
-                    dependency_of: LOCAL_CRATE,
-                    span,
-                    ..
-                }) => {
-                    debug!("try_print_visible_def_path: def_id={:?}", def_id);
-                    return Ok((
-                        if !span.is_dummy() {
-                            self.print_def_path(def_id, &[])?
-                        } else {
-                            self.path_crate(cnum)?
-                        },
-                        true,
-                    ));
-                }
-                None => {
-                    return Ok((self.path_crate(cnum)?, true));
-                }
-                _ => {}
-            }
-        }
-
-        if def_id.is_local() {
-            return Ok((self, false));
-        }
-
-        let visible_parent_map = self.tcx().visible_parent_map(LOCAL_CRATE);
-
-        let mut cur_def_key = self.tcx().def_key(def_id);
-        debug!("try_print_visible_def_path: cur_def_key={:?}", cur_def_key);
-
-        // For a constructor, we want the name of its parent rather than <unnamed>.
-        match cur_def_key.disambiguated_data.data {
-            DefPathData::Ctor => {
-                let parent = DefId {
-                    krate: def_id.krate,
-                    index: cur_def_key
-                        .parent
-                        .expect("`DefPathData::Ctor` / `VariantData` missing a parent"),
-                };
-
-                cur_def_key = self.tcx().def_key(parent);
-            }
-            _ => {}
-        }
-
-        let visible_parent = match visible_parent_map.get(&def_id).cloned() {
-            Some(parent) => parent,
-            None => return Ok((self, false)),
-        };
-        if callers.contains(&visible_parent) {
-            return Ok((self, false));
-        }
-        callers.push(visible_parent);
-        // HACK(eddyb) this bypasses `path_append`'s prefix printing to avoid
-        // knowing ahead of time whether the entire path will succeed or not.
-        // To support printers that do not implement `PrettyPrinter`, a `Vec` or
-        // linked list on the stack would need to be built, before any printing.
-        match self.try_print_visible_def_path_recur(visible_parent, callers)? {
-            (cx, false) => return Ok((cx, false)),
-            (cx, true) => self = cx,
-        }
-        callers.pop();
-        let actual_parent = self.tcx().parent(def_id);
-        debug!(
-            "try_print_visible_def_path: visible_parent={:?} actual_parent={:?}",
-            visible_parent, actual_parent,
-        );
-
-        let mut data = cur_def_key.disambiguated_data.data;
-        debug!(
-            "try_print_visible_def_path: data={:?} visible_parent={:?} actual_parent={:?}",
-            data, visible_parent, actual_parent,
-        );
-
-        match data {
-            // In order to output a path that could actually be imported (valid and visible),
-            // we need to handle re-exports correctly.
-            //
-            // For example, take `std::os::unix::process::CommandExt`, this trait is actually
-            // defined at `std::sys::unix::ext::process::CommandExt` (at time of writing).
-            //
-            // `std::os::unix` rexports the contents of `std::sys::unix::ext`. `std::sys` is
-            // private so the "true" path to `CommandExt` isn't accessible.
-            //
-            // In this case, the `visible_parent_map` will look something like this:
-            //
-            // (child) -> (parent)
-            // `std::sys::unix::ext::process::CommandExt` -> `std::sys::unix::ext::process`
-            // `std::sys::unix::ext::process` -> `std::sys::unix::ext`
-            // `std::sys::unix::ext` -> `std::os`
-            //
-            // This is correct, as the visible parent of `std::sys::unix::ext` is in fact
-            // `std::os`.
-            //
-            // When printing the path to `CommandExt` and looking at the `cur_def_key` that
-            // corresponds to `std::sys::unix::ext`, we would normally print `ext` and then go
-            // to the parent - resulting in a mangled path like
-            // `std::os::ext::process::CommandExt`.
-            //
-            // Instead, we must detect that there was a re-export and instead print `unix`
-            // (which is the name `std::sys::unix::ext` was re-exported as in `std::os`). To
-            // do this, we compare the parent of `std::sys::unix::ext` (`std::sys::unix`) with
-            // the visible parent (`std::os`). If these do not match, then we iterate over
-            // the children of the visible parent (as was done when computing
-            // `visible_parent_map`), looking for the specific child we currently have and then
-            // have access to the re-exported name.
-            DefPathData::TypeNs(ref mut name) if Some(visible_parent) != actual_parent => {
-                let reexport = self
-                    .tcx()
-                    .item_children(visible_parent)
-                    .iter()
-                    .find(|child| child.res.def_id() == def_id)
-                    .map(|child| child.ident.name);
-                if let Some(reexport) = reexport {
-                    *name = reexport;
-                }
-            }
-            // Re-exported `extern crate` (#43189).
-            DefPathData::CrateRoot => {
-                data = DefPathData::TypeNs(self.tcx().original_crate_name(def_id.krate));
-            }
-            _ => {}
-        }
-        debug!("try_print_visible_def_path: data={:?}", data);
-
-        Ok((self.path_append(Ok, &DisambiguatedDefPathData { data, disambiguator: 0 })?, true))
-    }
-
-    fn pretty_path_qualified(
-        self,
-        self_ty: Ty<'tcx>,
-        trait_ref: Option<ty::TraitRef<'tcx>>,
-    ) -> Result<Self::Path, Self::Error> {
-        if trait_ref.is_none() {
-            // Inherent impls. Try to print `Foo::bar` for an inherent
-            // impl on `Foo`, but fallback to `<Foo>::bar` if self-type is
-            // anything other than a simple path.
-            match self_ty.kind {
-                ty::Adt(..)
-                | ty::Foreign(_)
-                | ty::Bool
-                | ty::Char
-                | ty::Str
-                | ty::Int(_)
-                | ty::Uint(_)
-                | ty::Float(_) => {
-                    return self_ty.print(self);
-                }
-
-                _ => {}
-            }
-        }
-
-        self.generic_delimiters(|mut cx| {
-            define_scoped_cx!(cx);
-
-            p!(print(self_ty));
-            if let Some(trait_ref) = trait_ref {
-                p!(write(" as "), print(trait_ref.print_only_trait_path()));
-            }
-            Ok(cx)
-        })
-    }
-
-    fn pretty_path_append_impl(
-        mut self,
-        print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
-        self_ty: Ty<'tcx>,
-        trait_ref: Option<ty::TraitRef<'tcx>>,
-    ) -> Result<Self::Path, Self::Error> {
-        self = print_prefix(self)?;
-
-        self.generic_delimiters(|mut cx| {
-            define_scoped_cx!(cx);
-
-            p!(write("impl "));
-            if let Some(trait_ref) = trait_ref {
-                p!(print(trait_ref.print_only_trait_path()), write(" for "));
-            }
-            p!(print(self_ty));
-
-            Ok(cx)
-        })
-    }
-
-    fn pretty_print_type(mut self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error> {
-        define_scoped_cx!(self);
-
-        match ty.kind {
-            ty::Bool => p!(write("bool")),
-            ty::Char => p!(write("char")),
-            ty::Int(t) => p!(write("{}", t.name_str())),
-            ty::Uint(t) => p!(write("{}", t.name_str())),
-            ty::Float(t) => p!(write("{}", t.name_str())),
-            ty::RawPtr(ref tm) => {
-                p!(write(
-                    "*{} ",
-                    match tm.mutbl {
-                        hir::Mutability::Mut => "mut",
-                        hir::Mutability::Not => "const",
-                    }
-                ));
-                p!(print(tm.ty))
-            }
-            ty::Ref(r, ty, mutbl) => {
-                p!(write("&"));
-                if self.region_should_not_be_omitted(r) {
-                    p!(print(r), write(" "));
-                }
-                p!(print(ty::TypeAndMut { ty, mutbl }))
-            }
-            ty::Never => p!(write("!")),
-            ty::Tuple(ref tys) => {
-                p!(write("("));
-                let mut tys = tys.iter();
-                if let Some(&ty) = tys.next() {
-                    p!(print(ty), write(","));
-                    if let Some(&ty) = tys.next() {
-                        p!(write(" "), print(ty));
-                        for &ty in tys {
-                            p!(write(", "), print(ty));
-                        }
-                    }
-                }
-                p!(write(")"))
-            }
-            ty::FnDef(def_id, substs) => {
-                let sig = self.tcx().fn_sig(def_id).subst(self.tcx(), substs);
-                p!(print(sig), write(" {{"), print_value_path(def_id, substs), write("}}"));
-            }
-            ty::FnPtr(ref bare_fn) => p!(print(bare_fn)),
-            ty::Infer(infer_ty) => {
-                if let ty::TyVar(ty_vid) = infer_ty {
-                    if let Some(name) = self.infer_ty_name(ty_vid) {
-                        p!(write("{}", name))
-                    } else {
-                        p!(write("{}", infer_ty))
-                    }
-                } else {
-                    p!(write("{}", infer_ty))
-                }
-            }
-            ty::Error => p!(write("[type error]")),
-            ty::Param(ref param_ty) => p!(write("{}", param_ty)),
-            ty::Bound(debruijn, bound_ty) => match bound_ty.kind {
-                ty::BoundTyKind::Anon => {
-                    if debruijn == ty::INNERMOST {
-                        p!(write("^{}", bound_ty.var.index()))
-                    } else {
-                        p!(write("^{}_{}", debruijn.index(), bound_ty.var.index()))
-                    }
-                }
-
-                ty::BoundTyKind::Param(p) => p!(write("{}", p)),
-            },
-            ty::Adt(def, substs) => {
-                p!(print_def_path(def.did, substs));
-            }
-            ty::Dynamic(data, r) => {
-                let print_r = self.region_should_not_be_omitted(r);
-                if print_r {
-                    p!(write("("));
-                }
-                p!(write("dyn "), print(data));
-                if print_r {
-                    p!(write(" + "), print(r), write(")"));
-                }
-            }
-            ty::Foreign(def_id) => {
-                p!(print_def_path(def_id, &[]));
-            }
-            ty::Projection(ref data) => p!(print(data)),
-            ty::UnnormalizedProjection(ref data) => {
-                p!(write("Unnormalized("), print(data), write(")"))
-            }
-            ty::Placeholder(placeholder) => p!(write("Placeholder({:?})", placeholder)),
-            ty::Opaque(def_id, substs) => {
-                // FIXME(eddyb) print this with `print_def_path`.
-                // We use verbose printing in 'NO_QUERIES' mode, to
-                // avoid needing to call `predicates_of`. This should
-                // only affect certain debug messages (e.g. messages printed
-                // from `rustc::ty` during the computation of `tcx.predicates_of`),
-                // and should have no effect on any compiler output.
-                if self.tcx().sess.verbose() || NO_QUERIES.with(|q| q.get()) {
-                    p!(write("Opaque({:?}, {:?})", def_id, substs));
-                    return Ok(self);
-                }
-
-                return Ok(with_no_queries(|| {
-                    let def_key = self.tcx().def_key(def_id);
-                    if let Some(name) = def_key.disambiguated_data.data.get_opt_name() {
-                        p!(write("{}", name));
-                        let mut substs = substs.iter();
-                        // FIXME(eddyb) print this with `print_def_path`.
-                        if let Some(first) = substs.next() {
-                            p!(write("::<"));
-                            p!(print(first));
-                            for subst in substs {
-                                p!(write(", "), print(subst));
-                            }
-                            p!(write(">"));
-                        }
-                        return Ok(self);
-                    }
-                    // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`,
-                    // by looking up the projections associated with the def_id.
-                    let bounds = self.tcx().predicates_of(def_id).instantiate(self.tcx(), substs);
-
-                    let mut first = true;
-                    let mut is_sized = false;
-                    p!(write("impl"));
-                    for predicate in bounds.predicates {
-                        if let Some(trait_ref) = predicate.to_opt_poly_trait_ref() {
-                            // Don't print +Sized, but rather +?Sized if absent.
-                            if Some(trait_ref.def_id()) == self.tcx().lang_items().sized_trait() {
-                                is_sized = true;
-                                continue;
-                            }
-
-                            p!(
-                                write("{}", if first { " " } else { "+" }),
-                                print(trait_ref.print_only_trait_path())
-                            );
-                            first = false;
-                        }
-                    }
-                    if !is_sized {
-                        p!(write("{}?Sized", if first { " " } else { "+" }));
-                    } else if first {
-                        p!(write(" Sized"));
-                    }
-                    Ok(self)
-                })?);
-            }
-            ty::Str => p!(write("str")),
-            ty::Generator(did, substs, movability) => {
-                let upvar_tys = substs.as_generator().upvar_tys(did, self.tcx());
-                let witness = substs.as_generator().witness(did, self.tcx());
-                match movability {
-                    hir::Movability::Movable => p!(write("[generator")),
-                    hir::Movability::Static => p!(write("[static generator")),
-                }
-
-                // FIXME(eddyb) should use `def_span`.
-                if let Some(hir_id) = self.tcx().hir().as_local_hir_id(did) {
-                    p!(write("@{:?}", self.tcx().hir().span(hir_id)));
-                    let mut sep = " ";
-                    for (&var_id, upvar_ty) in
-                        self.tcx().upvars(did).as_ref().iter().flat_map(|v| v.keys()).zip(upvar_tys)
-                    {
-                        p!(write("{}{}:", sep, self.tcx().hir().name(var_id)), print(upvar_ty));
-                        sep = ", ";
-                    }
-                } else {
-                    // Cross-crate closure types should only be
-                    // visible in codegen bug reports, I imagine.
-                    p!(write("@{:?}", did));
-                    let mut sep = " ";
-                    for (index, upvar_ty) in upvar_tys.enumerate() {
-                        p!(write("{}{}:", sep, index), print(upvar_ty));
-                        sep = ", ";
-                    }
-                }
-
-                p!(write(" "), print(witness), write("]"))
-            }
-            ty::GeneratorWitness(types) => {
-                p!(in_binder(&types));
-            }
-            ty::Closure(did, substs) => {
-                let upvar_tys = substs.as_closure().upvar_tys(did, self.tcx());
-                p!(write("[closure"));
-
-                // FIXME(eddyb) should use `def_span`.
-                if let Some(hir_id) = self.tcx().hir().as_local_hir_id(did) {
-                    if self.tcx().sess.opts.debugging_opts.span_free_formats {
-                        p!(write("@"), print_def_path(did, substs));
-                    } else {
-                        p!(write("@{:?}", self.tcx().hir().span(hir_id)));
-                    }
-                    let mut sep = " ";
-                    for (&var_id, upvar_ty) in
-                        self.tcx().upvars(did).as_ref().iter().flat_map(|v| v.keys()).zip(upvar_tys)
-                    {
-                        p!(write("{}{}:", sep, self.tcx().hir().name(var_id)), print(upvar_ty));
-                        sep = ", ";
-                    }
-                } else {
-                    // Cross-crate closure types should only be
-                    // visible in codegen bug reports, I imagine.
-                    p!(write("@{:?}", did));
-                    let mut sep = " ";
-                    for (index, upvar_ty) in upvar_tys.enumerate() {
-                        p!(write("{}{}:", sep, index), print(upvar_ty));
-                        sep = ", ";
-                    }
-                }
-
-                if self.tcx().sess.verbose() {
-                    p!(write(
-                        " closure_kind_ty={:?} closure_sig_ty={:?}",
-                        substs.as_closure().kind_ty(did, self.tcx()),
-                        substs.as_closure().sig_ty(did, self.tcx())
-                    ));
-                }
-
-                p!(write("]"))
-            }
-            ty::Array(ty, sz) => {
-                p!(write("["), print(ty), write("; "));
-                if self.tcx().sess.verbose() {
-                    p!(write("{:?}", sz));
-                } else if let ty::ConstKind::Unevaluated(..) = sz.val {
-                    // do not try to evalute unevaluated constants. If we are const evaluating an
-                    // array length anon const, rustc will (with debug assertions) print the
-                    // constant's path. Which will end up here again.
-                    p!(write("_"));
-                } else if let Some(n) = sz.try_eval_usize(self.tcx(), ty::ParamEnv::empty()) {
-                    p!(write("{}", n));
-                } else {
-                    p!(write("_"));
-                }
-                p!(write("]"))
-            }
-            ty::Slice(ty) => p!(write("["), print(ty), write("]")),
-        }
-
-        Ok(self)
-    }
-
-    fn infer_ty_name(&self, _: ty::TyVid) -> Option<String> {
-        None
-    }
-
-    fn pretty_print_dyn_existential(
-        mut self,
-        predicates: &'tcx ty::List<ty::ExistentialPredicate<'tcx>>,
-    ) -> Result<Self::DynExistential, Self::Error> {
-        define_scoped_cx!(self);
-
-        // Generate the main trait ref, including associated types.
-        let mut first = true;
-
-        if let Some(principal) = predicates.principal() {
-            p!(print_def_path(principal.def_id, &[]));
-
-            let mut resugared = false;
-
-            // Special-case `Fn(...) -> ...` and resugar it.
-            let fn_trait_kind = self.tcx().fn_trait_kind_from_lang_item(principal.def_id);
-            if !self.tcx().sess.verbose() && fn_trait_kind.is_some() {
-                if let ty::Tuple(ref args) = principal.substs.type_at(0).kind {
-                    let mut projections = predicates.projection_bounds();
-                    if let (Some(proj), None) = (projections.next(), projections.next()) {
-                        let tys: Vec<_> = args.iter().map(|k| k.expect_ty()).collect();
-                        p!(pretty_fn_sig(&tys, false, proj.ty));
-                        resugared = true;
-                    }
-                }
-            }
-
-            // HACK(eddyb) this duplicates `FmtPrinter`'s `path_generic_args`,
-            // in order to place the projections inside the `<...>`.
-            if !resugared {
-                // Use a type that can't appear in defaults of type parameters.
-                let dummy_self = self.tcx().mk_ty_infer(ty::FreshTy(0));
-                let principal = principal.with_self_ty(self.tcx(), dummy_self);
-
-                let args = self.generic_args_to_print(
-                    self.tcx().generics_of(principal.def_id),
-                    principal.substs,
-                );
-
-                // Don't print `'_` if there's no unerased regions.
-                let print_regions = args.iter().any(|arg| match arg.unpack() {
-                    GenericArgKind::Lifetime(r) => *r != ty::ReErased,
-                    _ => false,
-                });
-                let mut args = args.iter().cloned().filter(|arg| match arg.unpack() {
-                    GenericArgKind::Lifetime(_) => print_regions,
-                    _ => true,
-                });
-                let mut projections = predicates.projection_bounds();
-
-                let arg0 = args.next();
-                let projection0 = projections.next();
-                if arg0.is_some() || projection0.is_some() {
-                    let args = arg0.into_iter().chain(args);
-                    let projections = projection0.into_iter().chain(projections);
-
-                    p!(generic_delimiters(|mut cx| {
-                        cx = cx.comma_sep(args)?;
-                        if arg0.is_some() && projection0.is_some() {
-                            write!(cx, ", ")?;
-                        }
-                        cx.comma_sep(projections)
-                    }));
-                }
-            }
-            first = false;
-        }
-
-        // Builtin bounds.
-        // FIXME(eddyb) avoid printing twice (needed to ensure
-        // that the auto traits are sorted *and* printed via cx).
-        let mut auto_traits: Vec<_> =
-            predicates.auto_traits().map(|did| (self.tcx().def_path_str(did), did)).collect();
-
-        // The auto traits come ordered by `DefPathHash`. While
-        // `DefPathHash` is *stable* in the sense that it depends on
-        // neither the host nor the phase of the moon, it depends
-        // "pseudorandomly" on the compiler version and the target.
-        //
-        // To avoid that causing instabilities in compiletest
-        // output, sort the auto-traits alphabetically.
-        auto_traits.sort();
-
-        for (_, def_id) in auto_traits {
-            if !first {
-                p!(write(" + "));
-            }
-            first = false;
-
-            p!(print_def_path(def_id, &[]));
-        }
-
-        Ok(self)
-    }
-
-    fn pretty_fn_sig(
-        mut self,
-        inputs: &[Ty<'tcx>],
-        c_variadic: bool,
-        output: Ty<'tcx>,
-    ) -> Result<Self, Self::Error> {
-        define_scoped_cx!(self);
-
-        p!(write("("));
-        let mut inputs = inputs.iter();
-        if let Some(&ty) = inputs.next() {
-            p!(print(ty));
-            for &ty in inputs {
-                p!(write(", "), print(ty));
-            }
-            if c_variadic {
-                p!(write(", ..."));
-            }
-        }
-        p!(write(")"));
-        if !output.is_unit() {
-            p!(write(" -> "), print(output));
-        }
-
-        Ok(self)
-    }
-
-    fn pretty_print_const(
-        mut self,
-        ct: &'tcx ty::Const<'tcx>,
-        print_ty: bool,
-    ) -> Result<Self::Const, Self::Error> {
-        define_scoped_cx!(self);
-
-        if self.tcx().sess.verbose() {
-            p!(write("Const({:?}: {:?})", ct.val, ct.ty));
-            return Ok(self);
-        }
-
-        macro_rules! print_underscore {
-            () => {{
-                p!(write("_"));
-                if print_ty {
-                    p!(write(": "), print(ct.ty));
-                }
-            }};
-        }
-
-        match (ct.val, &ct.ty.kind) {
-            (_, ty::FnDef(did, substs)) => p!(print_value_path(*did, substs)),
-            (ty::ConstKind::Unevaluated(did, substs, promoted), _) => {
-                if let Some(promoted) = promoted {
-                    p!(print_value_path(did, substs));
-                    p!(write("::{:?}", promoted));
-                } else {
-                    match self.tcx().def_kind(did) {
-                        Some(DefKind::Static)
-                        | Some(DefKind::Const)
-                        | Some(DefKind::AssocConst) => p!(print_value_path(did, substs)),
-                        _ => {
-                            if did.is_local() {
-                                let span = self.tcx().def_span(did);
-                                if let Ok(snip) = self.tcx().sess.source_map().span_to_snippet(span)
-                                {
-                                    p!(write("{}", snip))
-                                } else {
-                                    print_underscore!()
-                                }
-                            } else {
-                                print_underscore!()
-                            }
-                        }
-                    }
-                }
-            }
-            (ty::ConstKind::Infer(..), _) => print_underscore!(),
-            (ty::ConstKind::Param(ParamConst { name, .. }), _) => p!(write("{}", name)),
-            (ty::ConstKind::Value(value), _) => {
-                return self.pretty_print_const_value(value, ct.ty, print_ty);
-            }
-
-            _ => {
-                // fallback
-                p!(write("{:?}", ct.val));
-                if print_ty {
-                    p!(write(": "), print(ct.ty));
-                }
-            }
-        };
-        Ok(self)
-    }
-
-    fn pretty_print_const_value(
-        mut self,
-        ct: ConstValue<'tcx>,
-        ty: Ty<'tcx>,
-        print_ty: bool,
-    ) -> Result<Self::Const, Self::Error> {
-        define_scoped_cx!(self);
-
-        if self.tcx().sess.verbose() {
-            p!(write("ConstValue({:?}: {:?})", ct, ty));
-            return Ok(self);
-        }
-
-        let u8 = self.tcx().types.u8;
-
-        match (ct, &ty.kind) {
-            (ConstValue::Scalar(Scalar::Raw { data, .. }), ty::Bool) => {
-                p!(write("{}", if data == 0 { "false" } else { "true" }))
-            }
-            (ConstValue::Scalar(Scalar::Raw { data, .. }), ty::Float(ast::FloatTy::F32)) => {
-                p!(write("{}f32", Single::from_bits(data)))
-            }
-            (ConstValue::Scalar(Scalar::Raw { data, .. }), ty::Float(ast::FloatTy::F64)) => {
-                p!(write("{}f64", Double::from_bits(data)))
-            }
-            (ConstValue::Scalar(Scalar::Raw { data, .. }), ty::Uint(ui)) => {
-                let bit_size = Integer::from_attr(&self.tcx(), UnsignedInt(*ui)).size();
-                let max = truncate(u128::max_value(), bit_size);
-
-                let ui_str = ui.name_str();
-                if data == max {
-                    p!(write("std::{}::MAX", ui_str))
-                } else {
-                    p!(write("{}{}", data, ui_str))
-                };
-            }
-            (ConstValue::Scalar(Scalar::Raw { data, .. }), ty::Int(i)) => {
-                let bit_size = Integer::from_attr(&self.tcx(), SignedInt(*i)).size().bits() as u128;
-                let min = 1u128 << (bit_size - 1);
-                let max = min - 1;
-
-                let ty = self.tcx().lift(&ty).unwrap();
-                let size = self.tcx().layout_of(ty::ParamEnv::empty().and(ty)).unwrap().size;
-                let i_str = i.name_str();
-                match data {
-                    d if d == min => p!(write("std::{}::MIN", i_str)),
-                    d if d == max => p!(write("std::{}::MAX", i_str)),
-                    _ => p!(write("{}{}", sign_extend(data, size) as i128, i_str)),
-                }
-            }
-            (ConstValue::Scalar(Scalar::Raw { data, .. }), ty::Char) => {
-                p!(write("{:?}", ::std::char::from_u32(data as u32).unwrap()))
-            }
-            (ConstValue::Scalar(_), ty::RawPtr(_)) => p!(write("{{pointer}}")),
-            (ConstValue::Scalar(Scalar::Ptr(ptr)), ty::FnPtr(_)) => {
-                let instance = {
-                    let alloc_map = self.tcx().alloc_map.lock();
-                    alloc_map.unwrap_fn(ptr.alloc_id)
-                };
-                p!(print_value_path(instance.def_id(), instance.substs));
-            }
-            _ => {
-                let printed = if let ty::Ref(_, ref_ty, _) = ty.kind {
-                    let byte_str = match (ct, &ref_ty.kind) {
-                        (ConstValue::Scalar(Scalar::Ptr(ptr)), ty::Array(t, n)) if *t == u8 => {
-                            let n = n.eval_usize(self.tcx(), ty::ParamEnv::empty());
-                            Some(
-                                self.tcx()
-                                    .alloc_map
-                                    .lock()
-                                    .unwrap_memory(ptr.alloc_id)
-                                    .get_bytes(&self.tcx(), ptr, Size::from_bytes(n))
-                                    .unwrap(),
-                            )
-                        }
-                        (ConstValue::Slice { data, start, end }, ty::Slice(t)) if *t == u8 => {
-                            // The `inspect` here is okay since we checked the bounds, and there are
-                            // no relocations (we have an active slice reference here). We don't use
-                            // this result to affect interpreter execution.
-                            Some(data.inspect_with_undef_and_ptr_outside_interpreter(start..end))
-                        }
-                        _ => None,
-                    };
-
-                    if let Some(byte_str) = byte_str {
-                        p!(write("b\""));
-                        for &c in byte_str {
-                            for e in std::ascii::escape_default(c) {
-                                self.write_char(e as char)?;
-                            }
-                        }
-                        p!(write("\""));
-                        true
-                    } else if let (ConstValue::Slice { data, start, end }, ty::Str) =
-                        (ct, &ref_ty.kind)
-                    {
-                        // The `inspect` here is okay since we checked the bounds, and there are no
-                        // relocations (we have an active `str` reference here). We don't use this
-                        // result to affect interpreter execution.
-                        let slice = data.inspect_with_undef_and_ptr_outside_interpreter(start..end);
-                        let s = ::std::str::from_utf8(slice).expect("non utf8 str from miri");
-                        p!(write("{:?}", s));
-                        true
-                    } else {
-                        false
-                    }
-                } else {
-                    false
-                };
-                if !printed {
-                    // fallback
-                    p!(write("{:?}", ct));
-                    if print_ty {
-                        p!(write(": "), print(ty));
-                    }
-                }
-            }
-        };
-        Ok(self)
-    }
-}
-
-// HACK(eddyb) boxed to avoid moving around a large struct by-value.
-pub struct FmtPrinter<'a, 'tcx, F>(Box<FmtPrinterData<'a, 'tcx, F>>);
-
-pub struct FmtPrinterData<'a, 'tcx, F> {
-    tcx: TyCtxt<'tcx>,
-    fmt: F,
-
-    empty_path: bool,
-    in_value: bool,
-
-    used_region_names: FxHashSet<Symbol>,
-    region_index: usize,
-    binder_depth: usize,
-
-    pub region_highlight_mode: RegionHighlightMode,
-
-    pub name_resolver: Option<Box<&'a dyn Fn(ty::sty::TyVid) -> Option<String>>>,
-}
-
-impl<F> Deref for FmtPrinter<'a, 'tcx, F> {
-    type Target = FmtPrinterData<'a, 'tcx, F>;
-    fn deref(&self) -> &Self::Target {
-        &self.0
-    }
-}
-
-impl<F> DerefMut for FmtPrinter<'_, '_, F> {
-    fn deref_mut(&mut self) -> &mut Self::Target {
-        &mut self.0
-    }
-}
-
-impl<F> FmtPrinter<'a, 'tcx, F> {
-    pub fn new(tcx: TyCtxt<'tcx>, fmt: F, ns: Namespace) -> Self {
-        FmtPrinter(Box::new(FmtPrinterData {
-            tcx,
-            fmt,
-            empty_path: false,
-            in_value: ns == Namespace::ValueNS,
-            used_region_names: Default::default(),
-            region_index: 0,
-            binder_depth: 0,
-            region_highlight_mode: RegionHighlightMode::default(),
-            name_resolver: None,
-        }))
-    }
-}
-
-// HACK(eddyb) get rid of `def_path_str` and/or pass `Namespace` explicitly always
-// (but also some things just print a `DefId` generally so maybe we need this?)
-fn guess_def_namespace(tcx: TyCtxt<'_>, def_id: DefId) -> Namespace {
-    match tcx.def_key(def_id).disambiguated_data.data {
-        DefPathData::TypeNs(..) | DefPathData::CrateRoot | DefPathData::ImplTrait => {
-            Namespace::TypeNS
-        }
-
-        DefPathData::ValueNs(..)
-        | DefPathData::AnonConst
-        | DefPathData::ClosureExpr
-        | DefPathData::Ctor => Namespace::ValueNS,
-
-        DefPathData::MacroNs(..) => Namespace::MacroNS,
-
-        _ => Namespace::TypeNS,
-    }
-}
-
-impl TyCtxt<'t> {
-    /// Returns a string identifying this `DefId`. This string is
-    /// suitable for user output.
-    pub fn def_path_str(self, def_id: DefId) -> String {
-        self.def_path_str_with_substs(def_id, &[])
-    }
-
-    pub fn def_path_str_with_substs(self, def_id: DefId, substs: &'t [GenericArg<'t>]) -> String {
-        let ns = guess_def_namespace(self, def_id);
-        debug!("def_path_str: def_id={:?}, ns={:?}", def_id, ns);
-        let mut s = String::new();
-        let _ = FmtPrinter::new(self, &mut s, ns).print_def_path(def_id, substs);
-        s
-    }
-}
-
-impl<F: fmt::Write> fmt::Write for FmtPrinter<'_, '_, F> {
-    fn write_str(&mut self, s: &str) -> fmt::Result {
-        self.fmt.write_str(s)
-    }
-}
-
-impl<F: fmt::Write> Printer<'tcx> for FmtPrinter<'_, 'tcx, F> {
-    type Error = fmt::Error;
-
-    type Path = Self;
-    type Region = Self;
-    type Type = Self;
-    type DynExistential = Self;
-    type Const = Self;
-
-    fn tcx(&'a self) -> TyCtxt<'tcx> {
-        self.tcx
-    }
-
-    fn print_def_path(
-        mut self,
-        def_id: DefId,
-        substs: &'tcx [GenericArg<'tcx>],
-    ) -> Result<Self::Path, Self::Error> {
-        define_scoped_cx!(self);
-
-        if substs.is_empty() {
-            match self.try_print_visible_def_path(def_id)? {
-                (cx, true) => return Ok(cx),
-                (cx, false) => self = cx,
-            }
-        }
-
-        let key = self.tcx.def_key(def_id);
-        if let DefPathData::Impl = key.disambiguated_data.data {
-            // Always use types for non-local impls, where types are always
-            // available, and filename/line-number is mostly uninteresting.
-            let use_types = !def_id.is_local() || {
-                // Otherwise, use filename/line-number if forced.
-                let force_no_types = FORCE_IMPL_FILENAME_LINE.with(|f| f.get());
-                !force_no_types
-            };
-
-            if !use_types {
-                // If no type info is available, fall back to
-                // pretty printing some span information. This should
-                // only occur very early in the compiler pipeline.
-                let parent_def_id = DefId { index: key.parent.unwrap(), ..def_id };
-                let span = self.tcx.def_span(def_id);
-
-                self = self.print_def_path(parent_def_id, &[])?;
-
-                // HACK(eddyb) copy of `path_append` to avoid
-                // constructing a `DisambiguatedDefPathData`.
-                if !self.empty_path {
-                    write!(self, "::")?;
-                }
-                write!(self, "<impl at {:?}>", span)?;
-                self.empty_path = false;
-
-                return Ok(self);
-            }
-        }
-
-        self.default_print_def_path(def_id, substs)
-    }
-
-    fn print_region(self, region: ty::Region<'_>) -> Result<Self::Region, Self::Error> {
-        self.pretty_print_region(region)
-    }
-
-    fn print_type(self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error> {
-        self.pretty_print_type(ty)
-    }
-
-    fn print_dyn_existential(
-        self,
-        predicates: &'tcx ty::List<ty::ExistentialPredicate<'tcx>>,
-    ) -> Result<Self::DynExistential, Self::Error> {
-        self.pretty_print_dyn_existential(predicates)
-    }
-
-    fn print_const(self, ct: &'tcx ty::Const<'tcx>) -> Result<Self::Const, Self::Error> {
-        self.pretty_print_const(ct, true)
-    }
-
-    fn path_crate(mut self, cnum: CrateNum) -> Result<Self::Path, Self::Error> {
-        self.empty_path = true;
-        if cnum == LOCAL_CRATE {
-            if self.tcx.sess.rust_2018() {
-                // We add the `crate::` keyword on Rust 2018, only when desired.
-                if SHOULD_PREFIX_WITH_CRATE.with(|flag| flag.get()) {
-                    write!(self, "{}", kw::Crate)?;
-                    self.empty_path = false;
-                }
-            }
-        } else {
-            write!(self, "{}", self.tcx.crate_name(cnum))?;
-            self.empty_path = false;
-        }
-        Ok(self)
-    }
-
-    fn path_qualified(
-        mut self,
-        self_ty: Ty<'tcx>,
-        trait_ref: Option<ty::TraitRef<'tcx>>,
-    ) -> Result<Self::Path, Self::Error> {
-        self = self.pretty_path_qualified(self_ty, trait_ref)?;
-        self.empty_path = false;
-        Ok(self)
-    }
-
-    fn path_append_impl(
-        mut self,
-        print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
-        _disambiguated_data: &DisambiguatedDefPathData,
-        self_ty: Ty<'tcx>,
-        trait_ref: Option<ty::TraitRef<'tcx>>,
-    ) -> Result<Self::Path, Self::Error> {
-        self = self.pretty_path_append_impl(
-            |mut cx| {
-                cx = print_prefix(cx)?;
-                if !cx.empty_path {
-                    write!(cx, "::")?;
-                }
-
-                Ok(cx)
-            },
-            self_ty,
-            trait_ref,
-        )?;
-        self.empty_path = false;
-        Ok(self)
-    }
-
-    fn path_append(
-        mut self,
-        print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
-        disambiguated_data: &DisambiguatedDefPathData,
-    ) -> Result<Self::Path, Self::Error> {
-        self = print_prefix(self)?;
-
-        // Skip `::{{constructor}}` on tuple/unit structs.
-        match disambiguated_data.data {
-            DefPathData::Ctor => return Ok(self),
-            _ => {}
-        }
-
-        // FIXME(eddyb) `name` should never be empty, but it
-        // currently is for `extern { ... }` "foreign modules".
-        let name = disambiguated_data.data.as_symbol().as_str();
-        if !name.is_empty() {
-            if !self.empty_path {
-                write!(self, "::")?;
-            }
-            if ast::Ident::from_str(&name).is_raw_guess() {
-                write!(self, "r#")?;
-            }
-            write!(self, "{}", name)?;
-
-            // FIXME(eddyb) this will print e.g. `{{closure}}#3`, but it
-            // might be nicer to use something else, e.g. `{closure#3}`.
-            let dis = disambiguated_data.disambiguator;
-            let print_dis = disambiguated_data.data.get_opt_name().is_none()
-                || dis != 0 && self.tcx.sess.verbose();
-            if print_dis {
-                write!(self, "#{}", dis)?;
-            }
-
-            self.empty_path = false;
-        }
-
-        Ok(self)
-    }
-
-    fn path_generic_args(
-        mut self,
-        print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
-        args: &[GenericArg<'tcx>],
-    ) -> Result<Self::Path, Self::Error> {
-        self = print_prefix(self)?;
-
-        // Don't print `'_` if there's no unerased regions.
-        let print_regions = args.iter().any(|arg| match arg.unpack() {
-            GenericArgKind::Lifetime(r) => *r != ty::ReErased,
-            _ => false,
-        });
-        let args = args.iter().cloned().filter(|arg| match arg.unpack() {
-            GenericArgKind::Lifetime(_) => print_regions,
-            _ => true,
-        });
-
-        if args.clone().next().is_some() {
-            if self.in_value {
-                write!(self, "::")?;
-            }
-            self.generic_delimiters(|cx| cx.comma_sep(args))
-        } else {
-            Ok(self)
-        }
-    }
-}
-
-impl<F: fmt::Write> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx, F> {
-    fn infer_ty_name(&self, id: ty::TyVid) -> Option<String> {
-        self.0.name_resolver.as_ref().and_then(|func| func(id))
-    }
-
-    fn print_value_path(
-        mut self,
-        def_id: DefId,
-        substs: &'tcx [GenericArg<'tcx>],
-    ) -> Result<Self::Path, Self::Error> {
-        let was_in_value = std::mem::replace(&mut self.in_value, true);
-        self = self.print_def_path(def_id, substs)?;
-        self.in_value = was_in_value;
-
-        Ok(self)
-    }
-
-    fn in_binder<T>(self, value: &ty::Binder<T>) -> Result<Self, Self::Error>
-    where
-        T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx>,
-    {
-        self.pretty_in_binder(value)
-    }
-
-    fn generic_delimiters(
-        mut self,
-        f: impl FnOnce(Self) -> Result<Self, Self::Error>,
-    ) -> Result<Self, Self::Error> {
-        write!(self, "<")?;
-
-        let was_in_value = std::mem::replace(&mut self.in_value, false);
-        let mut inner = f(self)?;
-        inner.in_value = was_in_value;
-
-        write!(inner, ">")?;
-        Ok(inner)
-    }
-
-    fn region_should_not_be_omitted(&self, region: ty::Region<'_>) -> bool {
-        let highlight = self.region_highlight_mode;
-        if highlight.region_highlighted(region).is_some() {
-            return true;
-        }
-
-        if self.tcx.sess.verbose() {
-            return true;
-        }
-
-        let identify_regions = self.tcx.sess.opts.debugging_opts.identify_regions;
-
-        match *region {
-            ty::ReEarlyBound(ref data) => {
-                data.name != kw::Invalid && data.name != kw::UnderscoreLifetime
-            }
-
-            ty::ReLateBound(_, br)
-            | ty::ReFree(ty::FreeRegion { bound_region: br, .. })
-            | ty::RePlaceholder(ty::Placeholder { name: br, .. }) => {
-                if let ty::BrNamed(_, name) = br {
-                    if name != kw::Invalid && name != kw::UnderscoreLifetime {
-                        return true;
-                    }
-                }
-
-                if let Some((region, _)) = highlight.highlight_bound_region {
-                    if br == region {
-                        return true;
-                    }
-                }
-
-                false
-            }
-
-            ty::ReScope(_) | ty::ReVar(_) if identify_regions => true,
-
-            ty::ReVar(_) | ty::ReScope(_) | ty::ReErased => false,
-
-            ty::ReStatic | ty::ReEmpty(_) | ty::ReClosureBound(_) => true,
-        }
-    }
-}
-
-// HACK(eddyb) limited to `FmtPrinter` because of `region_highlight_mode`.
-impl<F: fmt::Write> FmtPrinter<'_, '_, F> {
-    pub fn pretty_print_region(mut self, region: ty::Region<'_>) -> Result<Self, fmt::Error> {
-        define_scoped_cx!(self);
-
-        // Watch out for region highlights.
-        let highlight = self.region_highlight_mode;
-        if let Some(n) = highlight.region_highlighted(region) {
-            p!(write("'{}", n));
-            return Ok(self);
-        }
-
-        if self.tcx.sess.verbose() {
-            p!(write("{:?}", region));
-            return Ok(self);
-        }
-
-        let identify_regions = self.tcx.sess.opts.debugging_opts.identify_regions;
-
-        // These printouts are concise.  They do not contain all the information
-        // the user might want to diagnose an error, but there is basically no way
-        // to fit that into a short string.  Hence the recommendation to use
-        // `explain_region()` or `note_and_explain_region()`.
-        match *region {
-            ty::ReEarlyBound(ref data) => {
-                if data.name != kw::Invalid {
-                    p!(write("{}", data.name));
-                    return Ok(self);
-                }
-            }
-            ty::ReLateBound(_, br)
-            | ty::ReFree(ty::FreeRegion { bound_region: br, .. })
-            | ty::RePlaceholder(ty::Placeholder { name: br, .. }) => {
-                if let ty::BrNamed(_, name) = br {
-                    if name != kw::Invalid && name != kw::UnderscoreLifetime {
-                        p!(write("{}", name));
-                        return Ok(self);
-                    }
-                }
-
-                if let Some((region, counter)) = highlight.highlight_bound_region {
-                    if br == region {
-                        p!(write("'{}", counter));
-                        return Ok(self);
-                    }
-                }
-            }
-            ty::ReScope(scope) if identify_regions => {
-                match scope.data {
-                    region::ScopeData::Node => p!(write("'{}s", scope.item_local_id().as_usize())),
-                    region::ScopeData::CallSite => {
-                        p!(write("'{}cs", scope.item_local_id().as_usize()))
-                    }
-                    region::ScopeData::Arguments => {
-                        p!(write("'{}as", scope.item_local_id().as_usize()))
-                    }
-                    region::ScopeData::Destruction => {
-                        p!(write("'{}ds", scope.item_local_id().as_usize()))
-                    }
-                    region::ScopeData::Remainder(first_statement_index) => p!(write(
-                        "'{}_{}rs",
-                        scope.item_local_id().as_usize(),
-                        first_statement_index.index()
-                    )),
-                }
-                return Ok(self);
-            }
-            ty::ReVar(region_vid) if identify_regions => {
-                p!(write("{:?}", region_vid));
-                return Ok(self);
-            }
-            ty::ReVar(_) => {}
-            ty::ReScope(_) | ty::ReErased => {}
-            ty::ReStatic => {
-                p!(write("'static"));
-                return Ok(self);
-            }
-            ty::ReEmpty(ty::UniverseIndex::ROOT) => {
-                p!(write("'<empty>"));
-                return Ok(self);
-            }
-            ty::ReEmpty(ui) => {
-                p!(write("'<empty:{:?}>", ui));
-                return Ok(self);
-            }
-
-            // The user should never encounter these in unsubstituted form.
-            ty::ReClosureBound(vid) => {
-                p!(write("{:?}", vid));
-                return Ok(self);
-            }
-        }
-
-        p!(write("'_"));
-
-        Ok(self)
-    }
-}
-
-// HACK(eddyb) limited to `FmtPrinter` because of `binder_depth`,
-// `region_index` and `used_region_names`.
-impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
-    pub fn name_all_regions<T>(
-        mut self,
-        value: &ty::Binder<T>,
-    ) -> Result<(Self, (T, BTreeMap<ty::BoundRegion, ty::Region<'tcx>>)), fmt::Error>
-    where
-        T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>,
-    {
-        fn name_by_region_index(index: usize) -> Symbol {
-            match index {
-                0 => Symbol::intern("'r"),
-                1 => Symbol::intern("'s"),
-                i => Symbol::intern(&format!("'t{}", i - 2)),
-            }
-        }
-
-        // Replace any anonymous late-bound regions with named
-        // variants, using new unique identifiers, so that we can
-        // clearly differentiate between named and unnamed regions in
-        // the output. We'll probably want to tweak this over time to
-        // decide just how much information to give.
-        if self.binder_depth == 0 {
-            self.prepare_late_bound_region_info(value);
-        }
-
-        let mut empty = true;
-        let mut start_or_continue = |cx: &mut Self, start: &str, cont: &str| {
-            write!(
-                cx,
-                "{}",
-                if empty {
-                    empty = false;
-                    start
-                } else {
-                    cont
-                }
-            )
-        };
-
-        define_scoped_cx!(self);
-
-        let mut region_index = self.region_index;
-        let new_value = self.tcx.replace_late_bound_regions(value, |br| {
-            let _ = start_or_continue(&mut self, "for<", ", ");
-            let br = match br {
-                ty::BrNamed(_, name) => {
-                    let _ = write!(self, "{}", name);
-                    br
-                }
-                ty::BrAnon(_) | ty::BrEnv => {
-                    let name = loop {
-                        let name = name_by_region_index(region_index);
-                        region_index += 1;
-                        if !self.used_region_names.contains(&name) {
-                            break name;
-                        }
-                    };
-                    let _ = write!(self, "{}", name);
-                    ty::BrNamed(DefId::local(CRATE_DEF_INDEX), name)
-                }
-            };
-            self.tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br))
-        });
-        start_or_continue(&mut self, "", "> ")?;
-
-        self.binder_depth += 1;
-        self.region_index = region_index;
-        Ok((self, new_value))
-    }
-
-    pub fn pretty_in_binder<T>(self, value: &ty::Binder<T>) -> Result<Self, fmt::Error>
-    where
-        T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>,
-    {
-        let old_region_index = self.region_index;
-        let (new, new_value) = self.name_all_regions(value)?;
-        let mut inner = new_value.0.print(new)?;
-        inner.region_index = old_region_index;
-        inner.binder_depth -= 1;
-        Ok(inner)
-    }
-
-    fn prepare_late_bound_region_info<T>(&mut self, value: &ty::Binder<T>)
-    where
-        T: TypeFoldable<'tcx>,
-    {
-        struct LateBoundRegionNameCollector<'a>(&'a mut FxHashSet<Symbol>);
-        impl<'tcx> ty::fold::TypeVisitor<'tcx> for LateBoundRegionNameCollector<'_> {
-            fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
-                match *r {
-                    ty::ReLateBound(_, ty::BrNamed(_, name)) => {
-                        self.0.insert(name);
-                    }
-                    _ => {}
-                }
-                r.super_visit_with(self)
-            }
-        }
-
-        self.used_region_names.clear();
-        let mut collector = LateBoundRegionNameCollector(&mut self.used_region_names);
-        value.visit_with(&mut collector);
-        self.region_index = 0;
-    }
-}
-
-impl<'tcx, T, P: PrettyPrinter<'tcx>> Print<'tcx, P> for ty::Binder<T>
-where
-    T: Print<'tcx, P, Output = P, Error = P::Error> + TypeFoldable<'tcx>,
-{
-    type Output = P;
-    type Error = P::Error;
-    fn print(&self, cx: P) -> Result<Self::Output, Self::Error> {
-        cx.in_binder(self)
-    }
-}
-
-impl<'tcx, T, U, P: PrettyPrinter<'tcx>> Print<'tcx, P> for ty::OutlivesPredicate<T, U>
-where
-    T: Print<'tcx, P, Output = P, Error = P::Error>,
-    U: Print<'tcx, P, Output = P, Error = P::Error>,
-{
-    type Output = P;
-    type Error = P::Error;
-    fn print(&self, mut cx: P) -> Result<Self::Output, Self::Error> {
-        define_scoped_cx!(cx);
-        p!(print(self.0), write(": "), print(self.1));
-        Ok(cx)
-    }
-}
-
-macro_rules! forward_display_to_print {
-    ($($ty:ty),+) => {
-        $(impl fmt::Display for $ty {
-            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-                ty::tls::with(|tcx| {
-                    tcx.lift(self)
-                        .expect("could not lift for printing")
-                        .print(FmtPrinter::new(tcx, f, Namespace::TypeNS))?;
-                    Ok(())
-                })
-            }
-        })+
-    };
-}
-
-macro_rules! define_print_and_forward_display {
-    (($self:ident, $cx:ident): $($ty:ty $print:block)+) => {
-        $(impl<'tcx, P: PrettyPrinter<'tcx>> Print<'tcx, P> for $ty {
-            type Output = P;
-            type Error = fmt::Error;
-            fn print(&$self, $cx: P) -> Result<Self::Output, Self::Error> {
-                #[allow(unused_mut)]
-                let mut $cx = $cx;
-                define_scoped_cx!($cx);
-                let _: () = $print;
-                #[allow(unreachable_code)]
-                Ok($cx)
-            }
-        })+
-
-        forward_display_to_print!($($ty),+);
-    };
-}
-
-// HACK(eddyb) this is separate because `ty::RegionKind` doesn't need lifting.
-impl fmt::Display for ty::RegionKind {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        ty::tls::with(|tcx| {
-            self.print(FmtPrinter::new(tcx, f, Namespace::TypeNS))?;
-            Ok(())
-        })
-    }
-}
-
-/// Wrapper type for `ty::TraitRef` which opts-in to pretty printing only
-/// the trait path. That is, it will print `Trait<U>` instead of
-/// `<T as Trait<U>>`.
-#[derive(Copy, Clone, TypeFoldable, Lift)]
-pub struct TraitRefPrintOnlyTraitPath<'tcx>(ty::TraitRef<'tcx>);
-
-impl fmt::Debug for TraitRefPrintOnlyTraitPath<'tcx> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        fmt::Display::fmt(self, f)
-    }
-}
-
-impl ty::TraitRef<'tcx> {
-    pub fn print_only_trait_path(self) -> TraitRefPrintOnlyTraitPath<'tcx> {
-        TraitRefPrintOnlyTraitPath(self)
-    }
-}
-
-impl ty::Binder<ty::TraitRef<'tcx>> {
-    pub fn print_only_trait_path(self) -> ty::Binder<TraitRefPrintOnlyTraitPath<'tcx>> {
-        self.map_bound(|tr| tr.print_only_trait_path())
-    }
-}
-
-forward_display_to_print! {
-    Ty<'tcx>,
-    &'tcx ty::List<ty::ExistentialPredicate<'tcx>>,
-    &'tcx ty::Const<'tcx>,
-
-    // HACK(eddyb) these are exhaustive instead of generic,
-    // because `for<'tcx>` isn't possible yet.
-    ty::Binder<&'tcx ty::List<ty::ExistentialPredicate<'tcx>>>,
-    ty::Binder<ty::TraitRef<'tcx>>,
-    ty::Binder<TraitRefPrintOnlyTraitPath<'tcx>>,
-    ty::Binder<ty::FnSig<'tcx>>,
-    ty::Binder<ty::TraitPredicate<'tcx>>,
-    ty::Binder<ty::SubtypePredicate<'tcx>>,
-    ty::Binder<ty::ProjectionPredicate<'tcx>>,
-    ty::Binder<ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>>,
-    ty::Binder<ty::OutlivesPredicate<ty::Region<'tcx>, ty::Region<'tcx>>>,
-
-    ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>,
-    ty::OutlivesPredicate<ty::Region<'tcx>, ty::Region<'tcx>>
-}
-
-define_print_and_forward_display! {
-    (self, cx):
-
-    &'tcx ty::List<Ty<'tcx>> {
-        p!(write("{{"));
-        let mut tys = self.iter();
-        if let Some(&ty) = tys.next() {
-            p!(print(ty));
-            for &ty in tys {
-                p!(write(", "), print(ty));
-            }
-        }
-        p!(write("}}"))
-    }
-
-    ty::TypeAndMut<'tcx> {
-        p!(write("{}", self.mutbl.prefix_str()), print(self.ty))
-    }
-
-    ty::ExistentialTraitRef<'tcx> {
-        // Use a type that can't appear in defaults of type parameters.
-        let dummy_self = cx.tcx().mk_ty_infer(ty::FreshTy(0));
-        let trait_ref = self.with_self_ty(cx.tcx(), dummy_self);
-        p!(print(trait_ref.print_only_trait_path()))
-    }
-
-    ty::ExistentialProjection<'tcx> {
-        let name = cx.tcx().associated_item(self.item_def_id).ident;
-        p!(write("{} = ", name), print(self.ty))
-    }
-
-    ty::ExistentialPredicate<'tcx> {
-        match *self {
-            ty::ExistentialPredicate::Trait(x) => p!(print(x)),
-            ty::ExistentialPredicate::Projection(x) => p!(print(x)),
-            ty::ExistentialPredicate::AutoTrait(def_id) => {
-                p!(print_def_path(def_id, &[]));
-            }
-        }
-    }
-
-    ty::FnSig<'tcx> {
-        p!(write("{}", self.unsafety.prefix_str()));
-
-        if self.abi != Abi::Rust {
-            p!(write("extern {} ", self.abi));
-        }
-
-        p!(write("fn"), pretty_fn_sig(self.inputs(), self.c_variadic, self.output()));
-    }
-
-    ty::InferTy {
-        if cx.tcx().sess.verbose() {
-            p!(write("{:?}", self));
-            return Ok(cx);
-        }
-        match *self {
-            ty::TyVar(_) => p!(write("_")),
-            ty::IntVar(_) => p!(write("{}", "{integer}")),
-            ty::FloatVar(_) => p!(write("{}", "{float}")),
-            ty::FreshTy(v) => p!(write("FreshTy({})", v)),
-            ty::FreshIntTy(v) => p!(write("FreshIntTy({})", v)),
-            ty::FreshFloatTy(v) => p!(write("FreshFloatTy({})", v))
-        }
-    }
-
-    ty::TraitRef<'tcx> {
-        p!(write("<{} as {}>", self.self_ty(), self.print_only_trait_path()))
-    }
-
-    TraitRefPrintOnlyTraitPath<'tcx> {
-        p!(print_def_path(self.0.def_id, self.0.substs));
-    }
-
-    ty::ParamTy {
-        p!(write("{}", self.name))
-    }
-
-    ty::ParamConst {
-        p!(write("{}", self.name))
-    }
-
-    ty::SubtypePredicate<'tcx> {
-        p!(print(self.a), write(" <: "), print(self.b))
-    }
-
-    ty::TraitPredicate<'tcx> {
-        p!(print(self.trait_ref.self_ty()), write(": "),
-           print(self.trait_ref.print_only_trait_path()))
-    }
-
-    ty::ProjectionPredicate<'tcx> {
-        p!(print(self.projection_ty), write(" == "), print(self.ty))
-    }
-
-    ty::ProjectionTy<'tcx> {
-        p!(print_def_path(self.item_def_id, self.substs));
-    }
-
-    ty::ClosureKind {
-        match *self {
-            ty::ClosureKind::Fn => p!(write("Fn")),
-            ty::ClosureKind::FnMut => p!(write("FnMut")),
-            ty::ClosureKind::FnOnce => p!(write("FnOnce")),
-        }
-    }
-
-    ty::Predicate<'tcx> {
-        match *self {
-            ty::Predicate::Trait(ref data, constness) => {
-                if let hir::Constness::Const = constness {
-                    p!(write("const "));
-                }
-                p!(print(data))
-            }
-            ty::Predicate::Subtype(ref predicate) => p!(print(predicate)),
-            ty::Predicate::RegionOutlives(ref predicate) => p!(print(predicate)),
-            ty::Predicate::TypeOutlives(ref predicate) => p!(print(predicate)),
-            ty::Predicate::Projection(ref predicate) => p!(print(predicate)),
-            ty::Predicate::WellFormed(ty) => p!(print(ty), write(" well-formed")),
-            ty::Predicate::ObjectSafe(trait_def_id) => {
-                p!(write("the trait `"),
-                   print_def_path(trait_def_id, &[]),
-                   write("` is object-safe"))
-            }
-            ty::Predicate::ClosureKind(closure_def_id, _closure_substs, kind) => {
-                p!(write("the closure `"),
-                   print_value_path(closure_def_id, &[]),
-                   write("` implements the trait `{}`", kind))
-            }
-            ty::Predicate::ConstEvaluatable(def_id, substs) => {
-                p!(write("the constant `"),
-                   print_value_path(def_id, substs),
-                   write("` can be evaluated"))
-            }
-        }
-    }
-
-    GenericArg<'tcx> {
-        match self.unpack() {
-            GenericArgKind::Lifetime(lt) => p!(print(lt)),
-            GenericArgKind::Type(ty) => p!(print(ty)),
-            GenericArgKind::Const(ct) => p!(print(ct)),
-        }
-    }
-}
diff --git a/src/librustc/ty/query/README.md b/src/librustc/ty/query/README.md
deleted file mode 100644
index 4b5e08cecd9..00000000000
--- a/src/librustc/ty/query/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-For more information about how the query system works, see the [rustc guide].
-
-[rustc guide]: https://rust-lang.github.io/rustc-guide/query.html
diff --git a/src/librustc/ty/query/caches.rs b/src/librustc/ty/query/caches.rs
deleted file mode 100644
index efc2804bd4d..00000000000
--- a/src/librustc/ty/query/caches.rs
+++ /dev/null
@@ -1,112 +0,0 @@
-use crate::dep_graph::DepNodeIndex;
-use crate::ty::query::config::QueryAccessors;
-use crate::ty::query::plumbing::{QueryLookup, QueryState, QueryStateShard};
-use crate::ty::TyCtxt;
-
-use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::sharded::Sharded;
-use std::default::Default;
-use std::hash::Hash;
-
-pub(crate) trait CacheSelector<K, V> {
-    type Cache: QueryCache<K, V>;
-}
-
-pub(crate) trait QueryCache<K, V>: Default {
-    type Sharded: Default;
-
-    /// Checks if the query is already computed and in the cache.
-    /// It returns the shard index and a lock guard to the shard,
-    /// which will be used if the query is not in the cache and we need
-    /// to compute it.
-    fn lookup<'tcx, R, GetCache, OnHit, OnMiss, Q>(
-        &self,
-        state: &'tcx QueryState<'tcx, Q>,
-        get_cache: GetCache,
-        key: K,
-        // `on_hit` can be called while holding a lock to the query state shard.
-        on_hit: OnHit,
-        on_miss: OnMiss,
-    ) -> R
-    where
-        Q: QueryAccessors<'tcx>,
-        GetCache: for<'a> Fn(&'a mut QueryStateShard<'tcx, Q>) -> &'a mut Self::Sharded,
-        OnHit: FnOnce(&V, DepNodeIndex) -> R,
-        OnMiss: FnOnce(K, QueryLookup<'tcx, Q>) -> R;
-
-    fn complete(
-        &self,
-        tcx: TyCtxt<'tcx>,
-        lock_sharded_storage: &mut Self::Sharded,
-        key: K,
-        value: V,
-        index: DepNodeIndex,
-    );
-
-    fn iter<R, L>(
-        &self,
-        shards: &Sharded<L>,
-        get_shard: impl Fn(&mut L) -> &mut Self::Sharded,
-        f: impl for<'a> FnOnce(Box<dyn Iterator<Item = (&'a K, &'a V, DepNodeIndex)> + 'a>) -> R,
-    ) -> R;
-}
-
-pub struct DefaultCacheSelector;
-
-impl<K: Eq + Hash, V: Clone> CacheSelector<K, V> for DefaultCacheSelector {
-    type Cache = DefaultCache;
-}
-
-#[derive(Default)]
-pub struct DefaultCache;
-
-impl<K: Eq + Hash, V: Clone> QueryCache<K, V> for DefaultCache {
-    type Sharded = FxHashMap<K, (V, DepNodeIndex)>;
-
-    #[inline(always)]
-    fn lookup<'tcx, R, GetCache, OnHit, OnMiss, Q>(
-        &self,
-        state: &'tcx QueryState<'tcx, Q>,
-        get_cache: GetCache,
-        key: K,
-        on_hit: OnHit,
-        on_miss: OnMiss,
-    ) -> R
-    where
-        Q: QueryAccessors<'tcx>,
-        GetCache: for<'a> Fn(&'a mut QueryStateShard<'tcx, Q>) -> &'a mut Self::Sharded,
-        OnHit: FnOnce(&V, DepNodeIndex) -> R,
-        OnMiss: FnOnce(K, QueryLookup<'tcx, Q>) -> R,
-    {
-        let mut lookup = state.get_lookup(&key);
-        let lock = &mut *lookup.lock;
-
-        let result = get_cache(lock).raw_entry().from_key_hashed_nocheck(lookup.key_hash, &key);
-
-        if let Some((_, value)) = result { on_hit(&value.0, value.1) } else { on_miss(key, lookup) }
-    }
-
-    #[inline]
-    fn complete(
-        &self,
-        _: TyCtxt<'tcx>,
-        lock_sharded_storage: &mut Self::Sharded,
-        key: K,
-        value: V,
-        index: DepNodeIndex,
-    ) {
-        lock_sharded_storage.insert(key, (value, index));
-    }
-
-    fn iter<R, L>(
-        &self,
-        shards: &Sharded<L>,
-        get_shard: impl Fn(&mut L) -> &mut Self::Sharded,
-        f: impl for<'a> FnOnce(Box<dyn Iterator<Item = (&'a K, &'a V, DepNodeIndex)> + 'a>) -> R,
-    ) -> R {
-        let mut shards = shards.lock_shards();
-        let mut shards: Vec<_> = shards.iter_mut().map(|shard| get_shard(shard)).collect();
-        let results = shards.iter_mut().flat_map(|shard| shard.iter()).map(|(k, v)| (k, &v.0, v.1));
-        f(Box::new(results))
-    }
-}
diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs
deleted file mode 100644
index e0e1ca374d9..00000000000
--- a/src/librustc/ty/query/config.rs
+++ /dev/null
@@ -1,95 +0,0 @@
-use crate::dep_graph::SerializedDepNodeIndex;
-use crate::dep_graph::{DepKind, DepNode};
-use crate::ty::query::caches::QueryCache;
-use crate::ty::query::plumbing::CycleError;
-use crate::ty::query::queries;
-use crate::ty::query::{Query, QueryState};
-use crate::ty::TyCtxt;
-use rustc_data_structures::profiling::ProfileCategory;
-use rustc_hir::def_id::{CrateNum, DefId};
-
-use crate::ich::StableHashingContext;
-use rustc_data_structures::fingerprint::Fingerprint;
-use std::borrow::Cow;
-use std::fmt::Debug;
-use std::hash::Hash;
-
-// Query configuration and description traits.
-
-// FIXME(eddyb) false positive, the lifetime parameter is used for `Key`/`Value`.
-#[allow(unused_lifetimes)]
-pub trait QueryConfig<'tcx> {
-    const NAME: &'static str;
-    const CATEGORY: ProfileCategory;
-
-    type Key: Eq + Hash + Clone + Debug;
-    type Value: Clone;
-}
-
-pub(crate) trait QueryAccessors<'tcx>: QueryConfig<'tcx> {
-    const ANON: bool;
-    const EVAL_ALWAYS: bool;
-
-    type Cache: QueryCache<Self::Key, Self::Value>;
-
-    fn query(key: Self::Key) -> Query<'tcx>;
-
-    // Don't use this method to access query results, instead use the methods on TyCtxt
-    fn query_state<'a>(tcx: TyCtxt<'tcx>) -> &'a QueryState<'tcx, Self>;
-
-    fn to_dep_node(tcx: TyCtxt<'tcx>, key: &Self::Key) -> DepNode;
-
-    fn dep_kind() -> DepKind;
-
-    // Don't use this method to compute query results, instead use the methods on TyCtxt
-    fn compute(tcx: TyCtxt<'tcx>, key: Self::Key) -> Self::Value;
-
-    fn hash_result(hcx: &mut StableHashingContext<'_>, result: &Self::Value)
-    -> Option<Fingerprint>;
-
-    fn handle_cycle_error(tcx: TyCtxt<'tcx>, error: CycleError<'tcx>) -> Self::Value;
-}
-
-pub(crate) trait QueryDescription<'tcx>: QueryAccessors<'tcx> {
-    fn describe(tcx: TyCtxt<'_>, key: Self::Key) -> Cow<'static, str>;
-
-    #[inline]
-    fn cache_on_disk(_: TyCtxt<'tcx>, _: Self::Key, _: Option<&Self::Value>) -> bool {
-        false
-    }
-
-    fn try_load_from_disk(_: TyCtxt<'tcx>, _: SerializedDepNodeIndex) -> Option<Self::Value> {
-        bug!("QueryDescription::load_from_disk() called for an unsupported query.")
-    }
-}
-
-impl<'tcx, M: QueryAccessors<'tcx, Key = DefId>> QueryDescription<'tcx> for M
-where
-    <M as QueryAccessors<'tcx>>::Cache: QueryCache<DefId, <M as QueryConfig<'tcx>>::Value>,
-{
-    default fn describe(tcx: TyCtxt<'_>, def_id: DefId) -> Cow<'static, str> {
-        if !tcx.sess.verbose() {
-            format!("processing `{}`", tcx.def_path_str(def_id)).into()
-        } else {
-            let name = ::std::any::type_name::<M>();
-            format!("processing {:?} with query `{}`", def_id, name).into()
-        }
-    }
-
-    default fn cache_on_disk(_: TyCtxt<'tcx>, _: Self::Key, _: Option<&Self::Value>) -> bool {
-        false
-    }
-
-    default fn try_load_from_disk(
-        _: TyCtxt<'tcx>,
-        _: SerializedDepNodeIndex,
-    ) -> Option<Self::Value> {
-        bug!("QueryDescription::load_from_disk() called for an unsupported query.")
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::analysis<'tcx> {
-    fn describe(_tcx: TyCtxt<'_>, _: CrateNum) -> Cow<'static, str> {
-        "running analysis passes on this crate".into()
-    }
-}
diff --git a/src/librustc/ty/query/job.rs b/src/librustc/ty/query/job.rs
deleted file mode 100644
index 3394fed8402..00000000000
--- a/src/librustc/ty/query/job.rs
+++ /dev/null
@@ -1,589 +0,0 @@
-use crate::dep_graph::DepKind;
-use crate::ty::context::TyCtxt;
-use crate::ty::query::plumbing::CycleError;
-use crate::ty::query::Query;
-use crate::ty::tls;
-
-use rustc_data_structures::fx::FxHashMap;
-use rustc_span::Span;
-
-use std::convert::TryFrom;
-use std::marker::PhantomData;
-use std::num::NonZeroU32;
-
-#[cfg(parallel_compiler)]
-use {
-    parking_lot::{Condvar, Mutex},
-    rustc_data_structures::fx::FxHashSet,
-    rustc_data_structures::stable_hasher::{HashStable, StableHasher},
-    rustc_data_structures::sync::Lock,
-    rustc_data_structures::sync::Lrc,
-    rustc_data_structures::{jobserver, OnDrop},
-    rustc_rayon_core as rayon_core,
-    rustc_span::DUMMY_SP,
-    std::iter::FromIterator,
-    std::{mem, process, thread},
-};
-
-/// Represents a span and a query key.
-#[derive(Clone, Debug)]
-pub struct QueryInfo<'tcx> {
-    /// The span corresponding to the reason for which this query was required.
-    pub span: Span,
-    pub query: Query<'tcx>,
-}
-
-type QueryMap<'tcx> = FxHashMap<QueryJobId, QueryJobInfo<'tcx>>;
-
-/// A value uniquely identifiying an active query job within a shard in the query cache.
-#[derive(Copy, Clone, Eq, PartialEq, Hash)]
-pub struct QueryShardJobId(pub NonZeroU32);
-
-/// A value uniquely identifiying an active query job.
-#[derive(Copy, Clone, Eq, PartialEq, Hash)]
-pub struct QueryJobId {
-    /// Which job within a shard is this
-    pub job: QueryShardJobId,
-
-    /// In which shard is this job
-    pub shard: u16,
-
-    /// What kind of query this job is
-    pub kind: DepKind,
-}
-
-impl QueryJobId {
-    pub fn new(job: QueryShardJobId, shard: usize, kind: DepKind) -> Self {
-        QueryJobId { job, shard: u16::try_from(shard).unwrap(), kind }
-    }
-
-    fn query<'tcx>(self, map: &QueryMap<'tcx>) -> Query<'tcx> {
-        map.get(&self).unwrap().info.query.clone()
-    }
-
-    #[cfg(parallel_compiler)]
-    fn span(self, map: &QueryMap<'_>) -> Span {
-        map.get(&self).unwrap().job.span
-    }
-
-    #[cfg(parallel_compiler)]
-    fn parent(self, map: &QueryMap<'_>) -> Option<QueryJobId> {
-        map.get(&self).unwrap().job.parent
-    }
-
-    #[cfg(parallel_compiler)]
-    fn latch<'a, 'tcx>(self, map: &'a QueryMap<'tcx>) -> Option<&'a QueryLatch<'tcx>> {
-        map.get(&self).unwrap().job.latch.as_ref()
-    }
-}
-
-pub struct QueryJobInfo<'tcx> {
-    pub info: QueryInfo<'tcx>,
-    pub job: QueryJob<'tcx>,
-}
-
-/// Represents an active query job.
-#[derive(Clone)]
-pub struct QueryJob<'tcx> {
-    pub id: QueryShardJobId,
-
-    /// The span corresponding to the reason for which this query was required.
-    pub span: Span,
-
-    /// The parent query job which created this job and is implicitly waiting on it.
-    pub parent: Option<QueryJobId>,
-
-    /// The latch that is used to wait on this job.
-    #[cfg(parallel_compiler)]
-    latch: Option<QueryLatch<'tcx>>,
-
-    dummy: PhantomData<QueryLatch<'tcx>>,
-}
-
-impl<'tcx> QueryJob<'tcx> {
-    /// Creates a new query job.
-    pub fn new(id: QueryShardJobId, span: Span, parent: Option<QueryJobId>) -> Self {
-        QueryJob {
-            id,
-            span,
-            parent,
-            #[cfg(parallel_compiler)]
-            latch: None,
-            dummy: PhantomData,
-        }
-    }
-
-    #[cfg(parallel_compiler)]
-    pub(super) fn latch(&mut self, _id: QueryJobId) -> QueryLatch<'tcx> {
-        if self.latch.is_none() {
-            self.latch = Some(QueryLatch::new());
-        }
-        self.latch.as_ref().unwrap().clone()
-    }
-
-    #[cfg(not(parallel_compiler))]
-    pub(super) fn latch(&mut self, id: QueryJobId) -> QueryLatch<'tcx> {
-        QueryLatch { id, dummy: PhantomData }
-    }
-
-    /// Signals to waiters that the query is complete.
-    ///
-    /// This does nothing for single threaded rustc,
-    /// as there are no concurrent jobs which could be waiting on us
-    pub fn signal_complete(self) {
-        #[cfg(parallel_compiler)]
-        self.latch.map(|latch| latch.set());
-    }
-}
-
-#[cfg(not(parallel_compiler))]
-#[derive(Clone)]
-pub(super) struct QueryLatch<'tcx> {
-    id: QueryJobId,
-    dummy: PhantomData<&'tcx ()>,
-}
-
-#[cfg(not(parallel_compiler))]
-impl<'tcx> QueryLatch<'tcx> {
-    pub(super) fn find_cycle_in_stack(&self, tcx: TyCtxt<'tcx>, span: Span) -> CycleError<'tcx> {
-        let query_map = tcx.queries.try_collect_active_jobs().unwrap();
-
-        // Get the current executing query (waiter) and find the waitee amongst its parents
-        let mut current_job = tls::with_related_context(tcx, |icx| icx.query);
-        let mut cycle = Vec::new();
-
-        while let Some(job) = current_job {
-            let info = query_map.get(&job).unwrap();
-            cycle.push(info.info.clone());
-
-            if job == self.id {
-                cycle.reverse();
-
-                // This is the end of the cycle
-                // The span entry we included was for the usage
-                // of the cycle itself, and not part of the cycle
-                // Replace it with the span which caused the cycle to form
-                cycle[0].span = span;
-                // Find out why the cycle itself was used
-                let usage = info
-                    .job
-                    .parent
-                    .as_ref()
-                    .map(|parent| (info.info.span, parent.query(&query_map)));
-                return CycleError { usage, cycle };
-            }
-
-            current_job = info.job.parent;
-        }
-
-        panic!("did not find a cycle")
-    }
-}
-
-#[cfg(parallel_compiler)]
-struct QueryWaiter<'tcx> {
-    query: Option<QueryJobId>,
-    condvar: Condvar,
-    span: Span,
-    cycle: Lock<Option<CycleError<'tcx>>>,
-}
-
-#[cfg(parallel_compiler)]
-impl<'tcx> QueryWaiter<'tcx> {
-    fn notify(&self, registry: &rayon_core::Registry) {
-        rayon_core::mark_unblocked(registry);
-        self.condvar.notify_one();
-    }
-}
-
-#[cfg(parallel_compiler)]
-struct QueryLatchInfo<'tcx> {
-    complete: bool,
-    waiters: Vec<Lrc<QueryWaiter<'tcx>>>,
-}
-
-#[cfg(parallel_compiler)]
-#[derive(Clone)]
-pub(super) struct QueryLatch<'tcx> {
-    info: Lrc<Mutex<QueryLatchInfo<'tcx>>>,
-}
-
-#[cfg(parallel_compiler)]
-impl<'tcx> QueryLatch<'tcx> {
-    fn new() -> Self {
-        QueryLatch {
-            info: Lrc::new(Mutex::new(QueryLatchInfo { complete: false, waiters: Vec::new() })),
-        }
-    }
-
-    /// Awaits for the query job to complete.
-    #[cfg(parallel_compiler)]
-    pub(super) fn wait_on(&self, tcx: TyCtxt<'tcx>, span: Span) -> Result<(), CycleError<'tcx>> {
-        tls::with_related_context(tcx, move |icx| {
-            let waiter = Lrc::new(QueryWaiter {
-                query: icx.query,
-                span,
-                cycle: Lock::new(None),
-                condvar: Condvar::new(),
-            });
-            self.wait_on_inner(&waiter);
-            // FIXME: Get rid of this lock. We have ownership of the QueryWaiter
-            // although another thread may still have a Lrc reference so we cannot
-            // use Lrc::get_mut
-            let mut cycle = waiter.cycle.lock();
-            match cycle.take() {
-                None => Ok(()),
-                Some(cycle) => Err(cycle),
-            }
-        })
-    }
-
-    /// Awaits the caller on this latch by blocking the current thread.
-    fn wait_on_inner(&self, waiter: &Lrc<QueryWaiter<'tcx>>) {
-        let mut info = self.info.lock();
-        if !info.complete {
-            // We push the waiter on to the `waiters` list. It can be accessed inside
-            // the `wait` call below, by 1) the `set` method or 2) by deadlock detection.
-            // Both of these will remove it from the `waiters` list before resuming
-            // this thread.
-            info.waiters.push(waiter.clone());
-
-            // If this detects a deadlock and the deadlock handler wants to resume this thread
-            // we have to be in the `wait` call. This is ensured by the deadlock handler
-            // getting the self.info lock.
-            rayon_core::mark_blocked();
-            jobserver::release_thread();
-            waiter.condvar.wait(&mut info);
-            // Release the lock before we potentially block in `acquire_thread`
-            mem::drop(info);
-            jobserver::acquire_thread();
-        }
-    }
-
-    /// Sets the latch and resumes all waiters on it
-    fn set(&self) {
-        let mut info = self.info.lock();
-        debug_assert!(!info.complete);
-        info.complete = true;
-        let registry = rayon_core::Registry::current();
-        for waiter in info.waiters.drain(..) {
-            waiter.notify(&registry);
-        }
-    }
-
-    /// Removes a single waiter from the list of waiters.
-    /// This is used to break query cycles.
-    fn extract_waiter(&self, waiter: usize) -> Lrc<QueryWaiter<'tcx>> {
-        let mut info = self.info.lock();
-        debug_assert!(!info.complete);
-        // Remove the waiter from the list of waiters
-        info.waiters.remove(waiter)
-    }
-}
-
-/// A resumable waiter of a query. The usize is the index into waiters in the query's latch
-#[cfg(parallel_compiler)]
-type Waiter = (QueryJobId, usize);
-
-/// Visits all the non-resumable and resumable waiters of a query.
-/// Only waiters in a query are visited.
-/// `visit` is called for every waiter and is passed a query waiting on `query_ref`
-/// and a span indicating the reason the query waited on `query_ref`.
-/// If `visit` returns Some, this function returns.
-/// For visits of non-resumable waiters it returns the return value of `visit`.
-/// For visits of resumable waiters it returns Some(Some(Waiter)) which has the
-/// required information to resume the waiter.
-/// If all `visit` calls returns None, this function also returns None.
-#[cfg(parallel_compiler)]
-fn visit_waiters<'tcx, F>(
-    query_map: &QueryMap<'tcx>,
-    query: QueryJobId,
-    mut visit: F,
-) -> Option<Option<Waiter>>
-where
-    F: FnMut(Span, QueryJobId) -> Option<Option<Waiter>>,
-{
-    // Visit the parent query which is a non-resumable waiter since it's on the same stack
-    if let Some(parent) = query.parent(query_map) {
-        if let Some(cycle) = visit(query.span(query_map), parent) {
-            return Some(cycle);
-        }
-    }
-
-    // Visit the explicit waiters which use condvars and are resumable
-    if let Some(latch) = query.latch(query_map) {
-        for (i, waiter) in latch.info.lock().waiters.iter().enumerate() {
-            if let Some(waiter_query) = waiter.query {
-                if visit(waiter.span, waiter_query).is_some() {
-                    // Return a value which indicates that this waiter can be resumed
-                    return Some(Some((query, i)));
-                }
-            }
-        }
-    }
-
-    None
-}
-
-/// Look for query cycles by doing a depth first search starting at `query`.
-/// `span` is the reason for the `query` to execute. This is initially DUMMY_SP.
-/// If a cycle is detected, this initial value is replaced with the span causing
-/// the cycle.
-#[cfg(parallel_compiler)]
-fn cycle_check<'tcx>(
-    query_map: &QueryMap<'tcx>,
-    query: QueryJobId,
-    span: Span,
-    stack: &mut Vec<(Span, QueryJobId)>,
-    visited: &mut FxHashSet<QueryJobId>,
-) -> Option<Option<Waiter>> {
-    if !visited.insert(query) {
-        return if let Some(p) = stack.iter().position(|q| q.1 == query) {
-            // We detected a query cycle, fix up the initial span and return Some
-
-            // Remove previous stack entries
-            stack.drain(0..p);
-            // Replace the span for the first query with the cycle cause
-            stack[0].0 = span;
-            Some(None)
-        } else {
-            None
-        };
-    }
-
-    // Query marked as visited is added it to the stack
-    stack.push((span, query));
-
-    // Visit all the waiters
-    let r = visit_waiters(query_map, query, |span, successor| {
-        cycle_check(query_map, successor, span, stack, visited)
-    });
-
-    // Remove the entry in our stack if we didn't find a cycle
-    if r.is_none() {
-        stack.pop();
-    }
-
-    r
-}
-
-/// Finds out if there's a path to the compiler root (aka. code which isn't in a query)
-/// from `query` without going through any of the queries in `visited`.
-/// This is achieved with a depth first search.
-#[cfg(parallel_compiler)]
-fn connected_to_root<'tcx>(
-    query_map: &QueryMap<'tcx>,
-    query: QueryJobId,
-    visited: &mut FxHashSet<QueryJobId>,
-) -> bool {
-    // We already visited this or we're deliberately ignoring it
-    if !visited.insert(query) {
-        return false;
-    }
-
-    // This query is connected to the root (it has no query parent), return true
-    if query.parent(query_map).is_none() {
-        return true;
-    }
-
-    visit_waiters(query_map, query, |_, successor| {
-        connected_to_root(query_map, successor, visited).then_some(None)
-    })
-    .is_some()
-}
-
-// Deterministically pick an query from a list
-#[cfg(parallel_compiler)]
-fn pick_query<'a, 'tcx, T, F: Fn(&T) -> (Span, QueryJobId)>(
-    query_map: &QueryMap<'tcx>,
-    tcx: TyCtxt<'tcx>,
-    queries: &'a [T],
-    f: F,
-) -> &'a T {
-    // Deterministically pick an entry point
-    // FIXME: Sort this instead
-    let mut hcx = tcx.create_stable_hashing_context();
-    queries
-        .iter()
-        .min_by_key(|v| {
-            let (span, query) = f(v);
-            let mut stable_hasher = StableHasher::new();
-            query.query(query_map).hash_stable(&mut hcx, &mut stable_hasher);
-            // Prefer entry points which have valid spans for nicer error messages
-            // We add an integer to the tuple ensuring that entry points
-            // with valid spans are picked first
-            let span_cmp = if span == DUMMY_SP { 1 } else { 0 };
-            (span_cmp, stable_hasher.finish::<u64>())
-        })
-        .unwrap()
-}
-
-/// Looks for query cycles starting from the last query in `jobs`.
-/// If a cycle is found, all queries in the cycle is removed from `jobs` and
-/// the function return true.
-/// If a cycle was not found, the starting query is removed from `jobs` and
-/// the function returns false.
-#[cfg(parallel_compiler)]
-fn remove_cycle<'tcx>(
-    query_map: &QueryMap<'tcx>,
-    jobs: &mut Vec<QueryJobId>,
-    wakelist: &mut Vec<Lrc<QueryWaiter<'tcx>>>,
-    tcx: TyCtxt<'tcx>,
-) -> bool {
-    let mut visited = FxHashSet::default();
-    let mut stack = Vec::new();
-    // Look for a cycle starting with the last query in `jobs`
-    if let Some(waiter) =
-        cycle_check(query_map, jobs.pop().unwrap(), DUMMY_SP, &mut stack, &mut visited)
-    {
-        // The stack is a vector of pairs of spans and queries; reverse it so that
-        // the earlier entries require later entries
-        let (mut spans, queries): (Vec<_>, Vec<_>) = stack.into_iter().rev().unzip();
-
-        // Shift the spans so that queries are matched with the span for their waitee
-        spans.rotate_right(1);
-
-        // Zip them back together
-        let mut stack: Vec<_> = spans.into_iter().zip(queries).collect();
-
-        // Remove the queries in our cycle from the list of jobs to look at
-        for r in &stack {
-            jobs.remove_item(&r.1);
-        }
-
-        // Find the queries in the cycle which are
-        // connected to queries outside the cycle
-        let entry_points = stack
-            .iter()
-            .filter_map(|&(span, query)| {
-                if query.parent(query_map).is_none() {
-                    // This query is connected to the root (it has no query parent)
-                    Some((span, query, None))
-                } else {
-                    let mut waiters = Vec::new();
-                    // Find all the direct waiters who lead to the root
-                    visit_waiters(query_map, query, |span, waiter| {
-                        // Mark all the other queries in the cycle as already visited
-                        let mut visited = FxHashSet::from_iter(stack.iter().map(|q| q.1));
-
-                        if connected_to_root(query_map, waiter, &mut visited) {
-                            waiters.push((span, waiter));
-                        }
-
-                        None
-                    });
-                    if waiters.is_empty() {
-                        None
-                    } else {
-                        // Deterministically pick one of the waiters to show to the user
-                        let waiter = *pick_query(query_map, tcx, &waiters, |s| *s);
-                        Some((span, query, Some(waiter)))
-                    }
-                }
-            })
-            .collect::<Vec<(Span, QueryJobId, Option<(Span, QueryJobId)>)>>();
-
-        // Deterministically pick an entry point
-        let (_, entry_point, usage) = pick_query(query_map, tcx, &entry_points, |e| (e.0, e.1));
-
-        // Shift the stack so that our entry point is first
-        let entry_point_pos = stack.iter().position(|(_, query)| query == entry_point);
-        if let Some(pos) = entry_point_pos {
-            stack.rotate_left(pos);
-        }
-
-        let usage = usage.as_ref().map(|(span, query)| (*span, query.query(query_map)));
-
-        // Create the cycle error
-        let error = CycleError {
-            usage,
-            cycle: stack
-                .iter()
-                .map(|&(s, ref q)| QueryInfo { span: s, query: q.query(query_map) })
-                .collect(),
-        };
-
-        // We unwrap `waiter` here since there must always be one
-        // edge which is resumeable / waited using a query latch
-        let (waitee_query, waiter_idx) = waiter.unwrap();
-
-        // Extract the waiter we want to resume
-        let waiter = waitee_query.latch(query_map).unwrap().extract_waiter(waiter_idx);
-
-        // Set the cycle error so it will be picked up when resumed
-        *waiter.cycle.lock() = Some(error);
-
-        // Put the waiter on the list of things to resume
-        wakelist.push(waiter);
-
-        true
-    } else {
-        false
-    }
-}
-
-/// Creates a new thread and forwards information in thread locals to it.
-/// The new thread runs the deadlock handler.
-/// Must only be called when a deadlock is about to happen.
-#[cfg(parallel_compiler)]
-pub unsafe fn handle_deadlock() {
-    let registry = rayon_core::Registry::current();
-
-    let gcx_ptr = tls::GCX_PTR.with(|gcx_ptr| gcx_ptr as *const _);
-    let gcx_ptr = &*gcx_ptr;
-
-    let rustc_span_globals =
-        rustc_span::GLOBALS.with(|rustc_span_globals| rustc_span_globals as *const _);
-    let rustc_span_globals = &*rustc_span_globals;
-    let syntax_globals = syntax::attr::GLOBALS.with(|syntax_globals| syntax_globals as *const _);
-    let syntax_globals = &*syntax_globals;
-    thread::spawn(move || {
-        tls::GCX_PTR.set(gcx_ptr, || {
-            syntax::attr::GLOBALS.set(syntax_globals, || {
-                rustc_span::GLOBALS
-                    .set(rustc_span_globals, || tls::with_global(|tcx| deadlock(tcx, &registry)))
-            });
-        })
-    });
-}
-
-/// Detects query cycles by using depth first search over all active query jobs.
-/// If a query cycle is found it will break the cycle by finding an edge which
-/// uses a query latch and then resuming that waiter.
-/// There may be multiple cycles involved in a deadlock, so this searches
-/// all active queries for cycles before finally resuming all the waiters at once.
-#[cfg(parallel_compiler)]
-fn deadlock(tcx: TyCtxt<'_>, registry: &rayon_core::Registry) {
-    let on_panic = OnDrop(|| {
-        eprintln!("deadlock handler panicked, aborting process");
-        process::abort();
-    });
-
-    let mut wakelist = Vec::new();
-    let query_map = tcx.queries.try_collect_active_jobs().unwrap();
-    let mut jobs: Vec<QueryJobId> = query_map.keys().cloned().collect();
-
-    let mut found_cycle = false;
-
-    while jobs.len() > 0 {
-        if remove_cycle(&query_map, &mut jobs, &mut wakelist, tcx) {
-            found_cycle = true;
-        }
-    }
-
-    // Check that a cycle was found. It is possible for a deadlock to occur without
-    // a query cycle if a query which can be waited on uses Rayon to do multithreading
-    // internally. Such a query (X) may be executing on 2 threads (A and B) and A may
-    // wait using Rayon on B. Rayon may then switch to executing another query (Y)
-    // which in turn will wait on X causing a deadlock. We have a false dependency from
-    // X to Y due to Rayon waiting and a true dependency from Y to X. The algorithm here
-    // only considers the true dependency and won't detect a cycle.
-    assert!(found_cycle);
-
-    // FIXME: Ensure this won't cause a deadlock before we return
-    for waiter in wakelist.into_iter() {
-        waiter.notify(registry);
-    }
-
-    on_panic.disable();
-}
diff --git a/src/librustc/ty/query/keys.rs b/src/librustc/ty/query/keys.rs
deleted file mode 100644
index 09fb307a1ce..00000000000
--- a/src/librustc/ty/query/keys.rs
+++ /dev/null
@@ -1,287 +0,0 @@
-//! Defines the set of legal keys that can be used in queries.
-
-use crate::infer::canonical::Canonical;
-use crate::mir;
-use crate::traits;
-use crate::ty::fast_reject::SimplifiedType;
-use crate::ty::query::caches::DefaultCacheSelector;
-use crate::ty::subst::SubstsRef;
-use crate::ty::{self, Ty, TyCtxt};
-use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE};
-use rustc_span::symbol::Symbol;
-use rustc_span::{Span, DUMMY_SP};
-
-/// The `Key` trait controls what types can legally be used as the key
-/// for a query.
-pub trait Key {
-    type CacheSelector;
-
-    /// Given an instance of this key, what crate is it referring to?
-    /// This is used to find the provider.
-    fn query_crate(&self) -> CrateNum;
-
-    /// In the event that a cycle occurs, if no explicit span has been
-    /// given for a query with key `self`, what span should we use?
-    fn default_span(&self, tcx: TyCtxt<'_>) -> Span;
-}
-
-impl<'tcx> Key for ty::InstanceDef<'tcx> {
-    type CacheSelector = DefaultCacheSelector;
-
-    fn query_crate(&self) -> CrateNum {
-        LOCAL_CRATE
-    }
-
-    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
-        tcx.def_span(self.def_id())
-    }
-}
-
-impl<'tcx> Key for ty::Instance<'tcx> {
-    type CacheSelector = DefaultCacheSelector;
-
-    fn query_crate(&self) -> CrateNum {
-        LOCAL_CRATE
-    }
-
-    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
-        tcx.def_span(self.def_id())
-    }
-}
-
-impl<'tcx> Key for mir::interpret::GlobalId<'tcx> {
-    type CacheSelector = DefaultCacheSelector;
-
-    fn query_crate(&self) -> CrateNum {
-        self.instance.query_crate()
-    }
-
-    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
-        self.instance.default_span(tcx)
-    }
-}
-
-impl<'tcx> Key for mir::interpret::LitToConstInput<'tcx> {
-    type CacheSelector = DefaultCacheSelector;
-
-    fn query_crate(&self) -> CrateNum {
-        LOCAL_CRATE
-    }
-
-    fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
-        DUMMY_SP
-    }
-}
-
-impl Key for CrateNum {
-    type CacheSelector = DefaultCacheSelector;
-
-    fn query_crate(&self) -> CrateNum {
-        *self
-    }
-    fn default_span(&self, _: TyCtxt<'_>) -> Span {
-        DUMMY_SP
-    }
-}
-
-impl Key for DefIndex {
-    type CacheSelector = DefaultCacheSelector;
-
-    fn query_crate(&self) -> CrateNum {
-        LOCAL_CRATE
-    }
-    fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
-        DUMMY_SP
-    }
-}
-
-impl Key for DefId {
-    type CacheSelector = DefaultCacheSelector;
-
-    fn query_crate(&self) -> CrateNum {
-        self.krate
-    }
-    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
-        tcx.def_span(*self)
-    }
-}
-
-impl Key for (DefId, DefId) {
-    type CacheSelector = DefaultCacheSelector;
-
-    fn query_crate(&self) -> CrateNum {
-        self.0.krate
-    }
-    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
-        self.1.default_span(tcx)
-    }
-}
-
-impl Key for (CrateNum, DefId) {
-    type CacheSelector = DefaultCacheSelector;
-
-    fn query_crate(&self) -> CrateNum {
-        self.0
-    }
-    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
-        self.1.default_span(tcx)
-    }
-}
-
-impl Key for (DefId, SimplifiedType) {
-    type CacheSelector = DefaultCacheSelector;
-
-    fn query_crate(&self) -> CrateNum {
-        self.0.krate
-    }
-    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
-        self.0.default_span(tcx)
-    }
-}
-
-impl<'tcx> Key for SubstsRef<'tcx> {
-    type CacheSelector = DefaultCacheSelector;
-
-    fn query_crate(&self) -> CrateNum {
-        LOCAL_CRATE
-    }
-    fn default_span(&self, _: TyCtxt<'_>) -> Span {
-        DUMMY_SP
-    }
-}
-
-impl<'tcx> Key for (DefId, SubstsRef<'tcx>) {
-    type CacheSelector = DefaultCacheSelector;
-
-    fn query_crate(&self) -> CrateNum {
-        self.0.krate
-    }
-    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
-        self.0.default_span(tcx)
-    }
-}
-
-impl<'tcx> Key for (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>) {
-    type CacheSelector = DefaultCacheSelector;
-
-    fn query_crate(&self) -> CrateNum {
-        self.1.def_id().krate
-    }
-    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
-        tcx.def_span(self.1.def_id())
-    }
-}
-
-impl<'tcx> Key for (&'tcx ty::Const<'tcx>, mir::Field) {
-    type CacheSelector = DefaultCacheSelector;
-
-    fn query_crate(&self) -> CrateNum {
-        LOCAL_CRATE
-    }
-    fn default_span(&self, _: TyCtxt<'_>) -> Span {
-        DUMMY_SP
-    }
-}
-
-impl<'tcx> Key for ty::PolyTraitRef<'tcx> {
-    type CacheSelector = DefaultCacheSelector;
-
-    fn query_crate(&self) -> CrateNum {
-        self.def_id().krate
-    }
-    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
-        tcx.def_span(self.def_id())
-    }
-}
-
-impl<'tcx> Key for &'tcx ty::Const<'tcx> {
-    type CacheSelector = DefaultCacheSelector;
-
-    fn query_crate(&self) -> CrateNum {
-        LOCAL_CRATE
-    }
-    fn default_span(&self, _: TyCtxt<'_>) -> Span {
-        DUMMY_SP
-    }
-}
-
-impl<'tcx> Key for Ty<'tcx> {
-    type CacheSelector = DefaultCacheSelector;
-
-    fn query_crate(&self) -> CrateNum {
-        LOCAL_CRATE
-    }
-    fn default_span(&self, _: TyCtxt<'_>) -> Span {
-        DUMMY_SP
-    }
-}
-
-impl<'tcx> Key for ty::ParamEnv<'tcx> {
-    type CacheSelector = DefaultCacheSelector;
-
-    fn query_crate(&self) -> CrateNum {
-        LOCAL_CRATE
-    }
-    fn default_span(&self, _: TyCtxt<'_>) -> Span {
-        DUMMY_SP
-    }
-}
-
-impl<'tcx, T: Key> Key for ty::ParamEnvAnd<'tcx, T> {
-    type CacheSelector = DefaultCacheSelector;
-
-    fn query_crate(&self) -> CrateNum {
-        self.value.query_crate()
-    }
-    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
-        self.value.default_span(tcx)
-    }
-}
-
-impl<'tcx> Key for traits::Environment<'tcx> {
-    type CacheSelector = DefaultCacheSelector;
-
-    fn query_crate(&self) -> CrateNum {
-        LOCAL_CRATE
-    }
-    fn default_span(&self, _: TyCtxt<'_>) -> Span {
-        DUMMY_SP
-    }
-}
-
-impl Key for Symbol {
-    type CacheSelector = DefaultCacheSelector;
-
-    fn query_crate(&self) -> CrateNum {
-        LOCAL_CRATE
-    }
-    fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
-        DUMMY_SP
-    }
-}
-
-/// Canonical query goals correspond to abstract trait operations that
-/// are not tied to any crate in particular.
-impl<'tcx, T> Key for Canonical<'tcx, T> {
-    type CacheSelector = DefaultCacheSelector;
-
-    fn query_crate(&self) -> CrateNum {
-        LOCAL_CRATE
-    }
-
-    fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
-        DUMMY_SP
-    }
-}
-
-impl Key for (Symbol, u32, u32) {
-    type CacheSelector = DefaultCacheSelector;
-
-    fn query_crate(&self) -> CrateNum {
-        LOCAL_CRATE
-    }
-
-    fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
-        DUMMY_SP
-    }
-}
diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs
deleted file mode 100644
index 381a7b1f03f..00000000000
--- a/src/librustc/ty/query/mod.rs
+++ /dev/null
@@ -1,112 +0,0 @@
-use crate::dep_graph::{self, DepConstructor, DepNode};
-use crate::hir::exports::Export;
-use crate::infer::canonical::{self, Canonical};
-use crate::lint::LintLevelMap;
-use crate::middle::codegen_fn_attrs::CodegenFnAttrs;
-use crate::middle::cstore::{CrateSource, DepKind, NativeLibraryKind};
-use crate::middle::cstore::{ExternCrate, ForeignModule, LinkagePreference, NativeLibrary};
-use crate::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel};
-use crate::middle::lang_items::{LangItem, LanguageItems};
-use crate::middle::lib_features::LibFeatures;
-use crate::middle::privacy::AccessLevels;
-use crate::middle::region;
-use crate::middle::resolve_lifetime::{ObjectLifetimeDefault, Region, ResolveLifetimes};
-use crate::middle::stability::{self, DeprecationEntry};
-use crate::mir;
-use crate::mir::interpret::GlobalId;
-use crate::mir::interpret::{ConstEvalRawResult, ConstEvalResult, ConstValue};
-use crate::mir::interpret::{LitToConstError, LitToConstInput};
-use crate::mir::mono::CodegenUnit;
-use crate::session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion};
-use crate::session::CrateDisambiguator;
-use crate::traits::query::{
-    CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal,
-    CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpEqGoal, CanonicalTypeOpNormalizeGoal,
-    CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpSubtypeGoal, NoSolution,
-};
-use crate::traits::query::{
-    DropckOutlivesResult, DtorckConstraint, MethodAutoderefStepsResult, NormalizationResult,
-    OutlivesBound,
-};
-use crate::traits::specialization_graph;
-use crate::traits::Clauses;
-use crate::traits::{self, Vtable};
-use crate::ty::steal::Steal;
-use crate::ty::subst::SubstsRef;
-use crate::ty::util::AlwaysRequiresDrop;
-use crate::ty::{self, AdtSizedConstraint, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt};
-use crate::util::common::ErrorReported;
-use rustc_data_structures::fingerprint::Fingerprint;
-use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
-use rustc_data_structures::profiling::ProfileCategory::*;
-use rustc_data_structures::stable_hasher::StableVec;
-use rustc_data_structures::svh::Svh;
-use rustc_data_structures::sync::Lrc;
-use rustc_hir as hir;
-use rustc_hir::def::DefKind;
-use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, DefIndex};
-use rustc_hir::{Crate, HirIdSet, ItemLocalId, TraitCandidate};
-use rustc_index::vec::IndexVec;
-use rustc_target::spec::PanicStrategy;
-
-use rustc_attr as attr;
-use rustc_span::symbol::Symbol;
-use rustc_span::{Span, DUMMY_SP};
-use std::borrow::Cow;
-use std::convert::TryFrom;
-use std::ops::Deref;
-use std::sync::Arc;
-use syntax::ast;
-
-#[macro_use]
-mod plumbing;
-use self::plumbing::*;
-pub use self::plumbing::{force_from_dep_node, CycleError};
-
-mod stats;
-pub use self::stats::print_stats;
-
-mod job;
-#[cfg(parallel_compiler)]
-pub use self::job::handle_deadlock;
-use self::job::QueryJobInfo;
-pub use self::job::{QueryInfo, QueryJob, QueryJobId};
-
-mod keys;
-use self::keys::Key;
-
-mod values;
-use self::values::Value;
-
-mod caches;
-use self::caches::CacheSelector;
-
-mod config;
-use self::config::QueryAccessors;
-pub use self::config::QueryConfig;
-pub(crate) use self::config::QueryDescription;
-
-mod on_disk_cache;
-pub use self::on_disk_cache::OnDiskCache;
-
-mod profiling_support;
-pub use self::profiling_support::{IntoSelfProfilingString, QueryKeyStringBuilder};
-
-// Each of these queries corresponds to a function pointer field in the
-// `Providers` struct for requesting a value of that type, and a method
-// on `tcx: TyCtxt` (and `tcx.at(span)`) for doing that request in a way
-// which memoizes and does dep-graph tracking, wrapping around the actual
-// `Providers` that the driver creates (using several `rustc_*` crates).
-//
-// The result type of each query must implement `Clone`, and additionally
-// `ty::query::values::Value`, which produces an appropriate placeholder
-// (error) value if the query resulted in a query cycle.
-// Queries marked with `fatal_cycle` do not need the latter implementation,
-// as they will raise an fatal error on query cycles instead.
-
-rustc_query_append! { [define_queries!][ <'tcx>
-    Other {
-        /// Runs analysis passes on the crate.
-        [eval_always] fn analysis: Analysis(CrateNum) -> Result<(), ErrorReported>,
-    },
-]}
diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs
deleted file mode 100644
index f96bf6c110c..00000000000
--- a/src/librustc/ty/query/on_disk_cache.rs
+++ /dev/null
@@ -1,1057 +0,0 @@
-use crate::dep_graph::{DepNodeIndex, SerializedDepNodeIndex};
-use crate::hir::map::definitions::DefPathHash;
-use crate::ich::{CachingSourceMapView, Fingerprint};
-use crate::mir::interpret::{AllocDecodingSession, AllocDecodingState};
-use crate::mir::{self, interpret};
-use crate::session::{CrateDisambiguator, Session};
-use crate::ty::codec::{self as ty_codec, TyDecoder, TyEncoder};
-use crate::ty::context::TyCtxt;
-use crate::ty::{self, Ty};
-use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::sync::{HashMapExt, Lock, Lrc, Once};
-use rustc_data_structures::thin_vec::ThinVec;
-use rustc_errors::Diagnostic;
-use rustc_hir as hir;
-use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, LOCAL_CRATE};
-use rustc_index::vec::{Idx, IndexVec};
-use rustc_serialize::{
-    opaque, Decodable, Decoder, Encodable, Encoder, SpecializedDecoder, SpecializedEncoder,
-    UseSpecializedDecodable, UseSpecializedEncodable,
-};
-use rustc_span::hygiene::{ExpnId, SyntaxContext};
-use rustc_span::source_map::{SourceMap, StableSourceFileId};
-use rustc_span::{BytePos, SourceFile, Span, DUMMY_SP};
-use std::mem;
-use syntax::ast::Ident;
-
-const TAG_FILE_FOOTER: u128 = 0xC0FFEE_C0FFEE_C0FFEE_C0FFEE_C0FFEE;
-
-const TAG_CLEAR_CROSS_CRATE_CLEAR: u8 = 0;
-const TAG_CLEAR_CROSS_CRATE_SET: u8 = 1;
-
-const TAG_NO_EXPN_DATA: u8 = 0;
-const TAG_EXPN_DATA_SHORTHAND: u8 = 1;
-const TAG_EXPN_DATA_INLINE: u8 = 2;
-
-const TAG_VALID_SPAN: u8 = 0;
-const TAG_INVALID_SPAN: u8 = 1;
-
-/// Provides an interface to incremental compilation data cached from the
-/// previous compilation session. This data will eventually include the results
-/// of a few selected queries (like `typeck_tables_of` and `mir_optimized`) and
-/// any diagnostics that have been emitted during a query.
-pub struct OnDiskCache<'sess> {
-    // The complete cache data in serialized form.
-    serialized_data: Vec<u8>,
-
-    // Collects all `Diagnostic`s emitted during the current compilation
-    // session.
-    current_diagnostics: Lock<FxHashMap<DepNodeIndex, Vec<Diagnostic>>>,
-
-    prev_cnums: Vec<(u32, String, CrateDisambiguator)>,
-    cnum_map: Once<IndexVec<CrateNum, Option<CrateNum>>>,
-
-    source_map: &'sess SourceMap,
-    file_index_to_stable_id: FxHashMap<SourceFileIndex, StableSourceFileId>,
-
-    // Caches that are populated lazily during decoding.
-    file_index_to_file: Lock<FxHashMap<SourceFileIndex, Lrc<SourceFile>>>,
-    synthetic_syntax_contexts: Lock<FxHashMap<AbsoluteBytePos, SyntaxContext>>,
-
-    // A map from dep-node to the position of the cached query result in
-    // `serialized_data`.
-    query_result_index: FxHashMap<SerializedDepNodeIndex, AbsoluteBytePos>,
-
-    // A map from dep-node to the position of any associated diagnostics in
-    // `serialized_data`.
-    prev_diagnostics_index: FxHashMap<SerializedDepNodeIndex, AbsoluteBytePos>,
-
-    alloc_decoding_state: AllocDecodingState,
-}
-
-// This type is used only for (de-)serialization.
-#[derive(RustcEncodable, RustcDecodable)]
-struct Footer {
-    file_index_to_stable_id: FxHashMap<SourceFileIndex, StableSourceFileId>,
-    prev_cnums: Vec<(u32, String, CrateDisambiguator)>,
-    query_result_index: EncodedQueryResultIndex,
-    diagnostics_index: EncodedQueryResultIndex,
-    // The location of all allocations.
-    interpret_alloc_index: Vec<u32>,
-}
-
-type EncodedQueryResultIndex = Vec<(SerializedDepNodeIndex, AbsoluteBytePos)>;
-type EncodedDiagnosticsIndex = Vec<(SerializedDepNodeIndex, AbsoluteBytePos)>;
-type EncodedDiagnostics = Vec<Diagnostic>;
-
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
-struct SourceFileIndex(u32);
-
-#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, RustcEncodable, RustcDecodable)]
-struct AbsoluteBytePos(u32);
-
-impl AbsoluteBytePos {
-    fn new(pos: usize) -> AbsoluteBytePos {
-        debug_assert!(pos <= ::std::u32::MAX as usize);
-        AbsoluteBytePos(pos as u32)
-    }
-
-    fn to_usize(self) -> usize {
-        self.0 as usize
-    }
-}
-
-impl<'sess> OnDiskCache<'sess> {
-    /// Creates a new `OnDiskCache` instance from the serialized data in `data`.
-    pub fn new(sess: &'sess Session, data: Vec<u8>, start_pos: usize) -> Self {
-        debug_assert!(sess.opts.incremental.is_some());
-
-        // Wrap in a scope so we can borrow `data`.
-        let footer: Footer = {
-            let mut decoder = opaque::Decoder::new(&data[..], start_pos);
-
-            // Decode the *position* of the footer, which can be found in the
-            // last 8 bytes of the file.
-            decoder.set_position(data.len() - IntEncodedWithFixedSize::ENCODED_SIZE);
-            let footer_pos = IntEncodedWithFixedSize::decode(&mut decoder)
-                .expect("error while trying to decode footer position")
-                .0 as usize;
-
-            // Decode the file footer, which contains all the lookup tables, etc.
-            decoder.set_position(footer_pos);
-            decode_tagged(&mut decoder, TAG_FILE_FOOTER)
-                .expect("error while trying to decode footer position")
-        };
-
-        Self {
-            serialized_data: data,
-            file_index_to_stable_id: footer.file_index_to_stable_id,
-            file_index_to_file: Default::default(),
-            prev_cnums: footer.prev_cnums,
-            cnum_map: Once::new(),
-            source_map: sess.source_map(),
-            current_diagnostics: Default::default(),
-            query_result_index: footer.query_result_index.into_iter().collect(),
-            prev_diagnostics_index: footer.diagnostics_index.into_iter().collect(),
-            synthetic_syntax_contexts: Default::default(),
-            alloc_decoding_state: AllocDecodingState::new(footer.interpret_alloc_index),
-        }
-    }
-
-    pub fn new_empty(source_map: &'sess SourceMap) -> Self {
-        Self {
-            serialized_data: Vec::new(),
-            file_index_to_stable_id: Default::default(),
-            file_index_to_file: Default::default(),
-            prev_cnums: vec![],
-            cnum_map: Once::new(),
-            source_map,
-            current_diagnostics: Default::default(),
-            query_result_index: Default::default(),
-            prev_diagnostics_index: Default::default(),
-            synthetic_syntax_contexts: Default::default(),
-            alloc_decoding_state: AllocDecodingState::new(Vec::new()),
-        }
-    }
-
-    pub fn serialize<'tcx, E>(&self, tcx: TyCtxt<'tcx>, encoder: &mut E) -> Result<(), E::Error>
-    where
-        E: TyEncoder,
-    {
-        // Serializing the `DepGraph` should not modify it.
-        tcx.dep_graph.with_ignore(|| {
-            // Allocate `SourceFileIndex`es.
-            let (file_to_file_index, file_index_to_stable_id) = {
-                let files = tcx.sess.source_map().files();
-                let mut file_to_file_index =
-                    FxHashMap::with_capacity_and_hasher(files.len(), Default::default());
-                let mut file_index_to_stable_id =
-                    FxHashMap::with_capacity_and_hasher(files.len(), Default::default());
-
-                for (index, file) in files.iter().enumerate() {
-                    let index = SourceFileIndex(index as u32);
-                    let file_ptr: *const SourceFile = &**file as *const _;
-                    file_to_file_index.insert(file_ptr, index);
-                    file_index_to_stable_id.insert(index, StableSourceFileId::new(&file));
-                }
-
-                (file_to_file_index, file_index_to_stable_id)
-            };
-
-            let mut encoder = CacheEncoder {
-                tcx,
-                encoder,
-                type_shorthands: Default::default(),
-                predicate_shorthands: Default::default(),
-                expn_data_shorthands: Default::default(),
-                interpret_allocs: Default::default(),
-                interpret_allocs_inverse: Vec::new(),
-                source_map: CachingSourceMapView::new(tcx.sess.source_map()),
-                file_to_file_index,
-            };
-
-            // Load everything into memory so we can write it out to the on-disk
-            // cache. The vast majority of cacheable query results should already
-            // be in memory, so this should be a cheap operation.
-            tcx.dep_graph.exec_cache_promotions(tcx);
-
-            // Encode query results.
-            let mut query_result_index = EncodedQueryResultIndex::new();
-
-            tcx.sess.time("encode_query_results", || {
-                let enc = &mut encoder;
-                let qri = &mut query_result_index;
-
-                macro_rules! encode_queries {
-                    ($($query:ident,)*) => {
-                        $(
-                            encode_query_results::<ty::query::queries::$query<'_>, _>(
-                                tcx,
-                                enc,
-                                qri
-                            )?;
-                        )*
-                    }
-                }
-
-                rustc_cached_queries!(encode_queries!);
-
-                Ok(())
-            })?;
-
-            // Encode diagnostics.
-            let diagnostics_index: EncodedDiagnosticsIndex = self
-                .current_diagnostics
-                .borrow()
-                .iter()
-                .map(|(dep_node_index, diagnostics)| {
-                    let pos = AbsoluteBytePos::new(encoder.position());
-                    // Let's make sure we get the expected type here.
-                    let diagnostics: &EncodedDiagnostics = diagnostics;
-                    let dep_node_index = SerializedDepNodeIndex::new(dep_node_index.index());
-                    encoder.encode_tagged(dep_node_index, diagnostics)?;
-
-                    Ok((dep_node_index, pos))
-                })
-                .collect::<Result<_, _>>()?;
-
-            let interpret_alloc_index = {
-                let mut interpret_alloc_index = Vec::new();
-                let mut n = 0;
-                loop {
-                    let new_n = encoder.interpret_allocs_inverse.len();
-                    // If we have found new IDs, serialize those too.
-                    if n == new_n {
-                        // Otherwise, abort.
-                        break;
-                    }
-                    interpret_alloc_index.reserve(new_n - n);
-                    for idx in n..new_n {
-                        let id = encoder.interpret_allocs_inverse[idx];
-                        let pos = encoder.position() as u32;
-                        interpret_alloc_index.push(pos);
-                        interpret::specialized_encode_alloc_id(&mut encoder, tcx, id)?;
-                    }
-                    n = new_n;
-                }
-                interpret_alloc_index
-            };
-
-            let sorted_cnums = sorted_cnums_including_local_crate(tcx);
-            let prev_cnums: Vec<_> = sorted_cnums
-                .iter()
-                .map(|&cnum| {
-                    let crate_name = tcx.original_crate_name(cnum).to_string();
-                    let crate_disambiguator = tcx.crate_disambiguator(cnum);
-                    (cnum.as_u32(), crate_name, crate_disambiguator)
-                })
-                .collect();
-
-            // Encode the file footer.
-            let footer_pos = encoder.position() as u64;
-            encoder.encode_tagged(
-                TAG_FILE_FOOTER,
-                &Footer {
-                    file_index_to_stable_id,
-                    prev_cnums,
-                    query_result_index,
-                    diagnostics_index,
-                    interpret_alloc_index,
-                },
-            )?;
-
-            // Encode the position of the footer as the last 8 bytes of the
-            // file so we know where to look for it.
-            IntEncodedWithFixedSize(footer_pos).encode(encoder.encoder)?;
-
-            // DO NOT WRITE ANYTHING TO THE ENCODER AFTER THIS POINT! The address
-            // of the footer must be the last thing in the data stream.
-
-            return Ok(());
-
-            fn sorted_cnums_including_local_crate(tcx: TyCtxt<'_>) -> Vec<CrateNum> {
-                let mut cnums = vec![LOCAL_CRATE];
-                cnums.extend_from_slice(&tcx.crates()[..]);
-                cnums.sort_unstable();
-                // Just to be sure...
-                cnums.dedup();
-                cnums
-            }
-        })
-    }
-
-    /// Loads a diagnostic emitted during the previous compilation session.
-    pub fn load_diagnostics(
-        &self,
-        tcx: TyCtxt<'_>,
-        dep_node_index: SerializedDepNodeIndex,
-    ) -> Vec<Diagnostic> {
-        let diagnostics: Option<EncodedDiagnostics> =
-            self.load_indexed(tcx, dep_node_index, &self.prev_diagnostics_index, "diagnostics");
-
-        diagnostics.unwrap_or_default()
-    }
-
-    /// Stores a diagnostic emitted during the current compilation session.
-    /// Anything stored like this will be available via `load_diagnostics` in
-    /// the next compilation session.
-    #[inline(never)]
-    #[cold]
-    pub fn store_diagnostics(
-        &self,
-        dep_node_index: DepNodeIndex,
-        diagnostics: ThinVec<Diagnostic>,
-    ) {
-        let mut current_diagnostics = self.current_diagnostics.borrow_mut();
-        let prev = current_diagnostics.insert(dep_node_index, diagnostics.into());
-        debug_assert!(prev.is_none());
-    }
-
-    /// Returns the cached query result if there is something in the cache for
-    /// the given `SerializedDepNodeIndex`; otherwise returns `None`.
-    pub fn try_load_query_result<T>(
-        &self,
-        tcx: TyCtxt<'_>,
-        dep_node_index: SerializedDepNodeIndex,
-    ) -> Option<T>
-    where
-        T: Decodable,
-    {
-        self.load_indexed(tcx, dep_node_index, &self.query_result_index, "query result")
-    }
-
-    /// Stores a diagnostic emitted during computation of an anonymous query.
-    /// Since many anonymous queries can share the same `DepNode`, we aggregate
-    /// them -- as opposed to regular queries where we assume that there is a
-    /// 1:1 relationship between query-key and `DepNode`.
-    #[inline(never)]
-    #[cold]
-    pub fn store_diagnostics_for_anon_node(
-        &self,
-        dep_node_index: DepNodeIndex,
-        diagnostics: ThinVec<Diagnostic>,
-    ) {
-        let mut current_diagnostics = self.current_diagnostics.borrow_mut();
-
-        let x = current_diagnostics.entry(dep_node_index).or_insert(Vec::new());
-
-        x.extend(Into::<Vec<_>>::into(diagnostics));
-    }
-
-    fn load_indexed<'tcx, T>(
-        &self,
-        tcx: TyCtxt<'tcx>,
-        dep_node_index: SerializedDepNodeIndex,
-        index: &FxHashMap<SerializedDepNodeIndex, AbsoluteBytePos>,
-        debug_tag: &'static str,
-    ) -> Option<T>
-    where
-        T: Decodable,
-    {
-        let pos = index.get(&dep_node_index).cloned()?;
-
-        // Initialize `cnum_map` using the value from the thread that finishes the closure first.
-        self.cnum_map.init_nonlocking_same(|| Self::compute_cnum_map(tcx, &self.prev_cnums[..]));
-
-        let mut decoder = CacheDecoder {
-            tcx,
-            opaque: opaque::Decoder::new(&self.serialized_data[..], pos.to_usize()),
-            source_map: self.source_map,
-            cnum_map: self.cnum_map.get(),
-            synthetic_syntax_contexts: &self.synthetic_syntax_contexts,
-            file_index_to_file: &self.file_index_to_file,
-            file_index_to_stable_id: &self.file_index_to_stable_id,
-            alloc_decoding_session: self.alloc_decoding_state.new_decoding_session(),
-        };
-
-        match decode_tagged(&mut decoder, dep_node_index) {
-            Ok(v) => Some(v),
-            Err(e) => bug!("could not decode cached {}: {}", debug_tag, e),
-        }
-    }
-
-    // This function builds mapping from previous-session-`CrateNum` to
-    // current-session-`CrateNum`. There might be `CrateNum`s from the previous
-    // `Session` that don't occur in the current one. For these, the mapping
-    // maps to None.
-    fn compute_cnum_map(
-        tcx: TyCtxt<'_>,
-        prev_cnums: &[(u32, String, CrateDisambiguator)],
-    ) -> IndexVec<CrateNum, Option<CrateNum>> {
-        tcx.dep_graph.with_ignore(|| {
-            let current_cnums = tcx
-                .all_crate_nums(LOCAL_CRATE)
-                .iter()
-                .map(|&cnum| {
-                    let crate_name = tcx.original_crate_name(cnum).to_string();
-                    let crate_disambiguator = tcx.crate_disambiguator(cnum);
-                    ((crate_name, crate_disambiguator), cnum)
-                })
-                .collect::<FxHashMap<_, _>>();
-
-            let map_size = prev_cnums.iter().map(|&(cnum, ..)| cnum).max().unwrap_or(0) + 1;
-            let mut map = IndexVec::from_elem_n(None, map_size as usize);
-
-            for &(prev_cnum, ref crate_name, crate_disambiguator) in prev_cnums {
-                let key = (crate_name.clone(), crate_disambiguator);
-                map[CrateNum::from_u32(prev_cnum)] = current_cnums.get(&key).cloned();
-            }
-
-            map[LOCAL_CRATE] = Some(LOCAL_CRATE);
-            map
-        })
-    }
-}
-
-//- DECODING -------------------------------------------------------------------
-
-/// A decoder that can read fro the incr. comp. cache. It is similar to the one
-/// we use for crate metadata decoding in that it can rebase spans and eventually
-/// will also handle things that contain `Ty` instances.
-struct CacheDecoder<'a, 'tcx> {
-    tcx: TyCtxt<'tcx>,
-    opaque: opaque::Decoder<'a>,
-    source_map: &'a SourceMap,
-    cnum_map: &'a IndexVec<CrateNum, Option<CrateNum>>,
-    synthetic_syntax_contexts: &'a Lock<FxHashMap<AbsoluteBytePos, SyntaxContext>>,
-    file_index_to_file: &'a Lock<FxHashMap<SourceFileIndex, Lrc<SourceFile>>>,
-    file_index_to_stable_id: &'a FxHashMap<SourceFileIndex, StableSourceFileId>,
-    alloc_decoding_session: AllocDecodingSession<'a>,
-}
-
-impl<'a, 'tcx> CacheDecoder<'a, 'tcx> {
-    fn file_index_to_file(&self, index: SourceFileIndex) -> Lrc<SourceFile> {
-        let CacheDecoder {
-            ref file_index_to_file,
-            ref file_index_to_stable_id,
-            ref source_map,
-            ..
-        } = *self;
-
-        file_index_to_file
-            .borrow_mut()
-            .entry(index)
-            .or_insert_with(|| {
-                let stable_id = file_index_to_stable_id[&index];
-                source_map
-                    .source_file_by_stable_id(stable_id)
-                    .expect("failed to lookup `SourceFile` in new context")
-            })
-            .clone()
-    }
-}
-
-trait DecoderWithPosition: Decoder {
-    fn position(&self) -> usize;
-}
-
-impl<'a> DecoderWithPosition for opaque::Decoder<'a> {
-    fn position(&self) -> usize {
-        self.position()
-    }
-}
-
-impl<'a, 'tcx> DecoderWithPosition for CacheDecoder<'a, 'tcx> {
-    fn position(&self) -> usize {
-        self.opaque.position()
-    }
-}
-
-// Decodes something that was encoded with `encode_tagged()` and verify that the
-// tag matches and the correct amount of bytes was read.
-fn decode_tagged<D, T, V>(decoder: &mut D, expected_tag: T) -> Result<V, D::Error>
-where
-    T: Decodable + Eq + ::std::fmt::Debug,
-    V: Decodable,
-    D: DecoderWithPosition,
-{
-    let start_pos = decoder.position();
-
-    let actual_tag = T::decode(decoder)?;
-    assert_eq!(actual_tag, expected_tag);
-    let value = V::decode(decoder)?;
-    let end_pos = decoder.position();
-
-    let expected_len: u64 = Decodable::decode(decoder)?;
-    assert_eq!((end_pos - start_pos) as u64, expected_len);
-
-    Ok(value)
-}
-
-impl<'a, 'tcx> TyDecoder<'tcx> for CacheDecoder<'a, 'tcx> {
-    #[inline]
-    fn tcx(&self) -> TyCtxt<'tcx> {
-        self.tcx
-    }
-
-    #[inline]
-    fn position(&self) -> usize {
-        self.opaque.position()
-    }
-
-    #[inline]
-    fn peek_byte(&self) -> u8 {
-        self.opaque.data[self.opaque.position()]
-    }
-
-    fn cached_ty_for_shorthand<F>(
-        &mut self,
-        shorthand: usize,
-        or_insert_with: F,
-    ) -> Result<Ty<'tcx>, Self::Error>
-    where
-        F: FnOnce(&mut Self) -> Result<Ty<'tcx>, Self::Error>,
-    {
-        let tcx = self.tcx();
-
-        let cache_key =
-            ty::CReaderCacheKey { cnum: CrateNum::ReservedForIncrCompCache, pos: shorthand };
-
-        if let Some(&ty) = tcx.rcache.borrow().get(&cache_key) {
-            return Ok(ty);
-        }
-
-        let ty = or_insert_with(self)?;
-        // This may overwrite the entry, but it should overwrite with the same value.
-        tcx.rcache.borrow_mut().insert_same(cache_key, ty);
-        Ok(ty)
-    }
-
-    fn with_position<F, R>(&mut self, pos: usize, f: F) -> R
-    where
-        F: FnOnce(&mut Self) -> R,
-    {
-        debug_assert!(pos < self.opaque.data.len());
-
-        let new_opaque = opaque::Decoder::new(self.opaque.data, pos);
-        let old_opaque = mem::replace(&mut self.opaque, new_opaque);
-        let r = f(self);
-        self.opaque = old_opaque;
-        r
-    }
-
-    fn map_encoded_cnum_to_current(&self, cnum: CrateNum) -> CrateNum {
-        self.cnum_map[cnum].unwrap_or_else(|| bug!("could not find new `CrateNum` for {:?}", cnum))
-    }
-}
-
-implement_ty_decoder!(CacheDecoder<'a, 'tcx>);
-
-impl<'a, 'tcx> SpecializedDecoder<interpret::AllocId> for CacheDecoder<'a, 'tcx> {
-    fn specialized_decode(&mut self) -> Result<interpret::AllocId, Self::Error> {
-        let alloc_decoding_session = self.alloc_decoding_session;
-        alloc_decoding_session.decode_alloc_id(self)
-    }
-}
-
-impl<'a, 'tcx> SpecializedDecoder<Span> for CacheDecoder<'a, 'tcx> {
-    fn specialized_decode(&mut self) -> Result<Span, Self::Error> {
-        let tag: u8 = Decodable::decode(self)?;
-
-        if tag == TAG_INVALID_SPAN {
-            return Ok(DUMMY_SP);
-        } else {
-            debug_assert_eq!(tag, TAG_VALID_SPAN);
-        }
-
-        let file_lo_index = SourceFileIndex::decode(self)?;
-        let line_lo = usize::decode(self)?;
-        let col_lo = BytePos::decode(self)?;
-        let len = BytePos::decode(self)?;
-
-        let file_lo = self.file_index_to_file(file_lo_index);
-        let lo = file_lo.lines[line_lo - 1] + col_lo;
-        let hi = lo + len;
-
-        let expn_data_tag = u8::decode(self)?;
-
-        // FIXME(mw): This method does not restore `ExpnData::parent` or
-        // `SyntaxContextData::prev_ctxt` or `SyntaxContextData::opaque`. These things
-        // don't seem to be used after HIR lowering, so everything should be fine
-        // until we want incremental compilation to serialize Spans that we need
-        // full hygiene information for.
-        let location = || Span::with_root_ctxt(lo, hi);
-        let recover_from_expn_data = |this: &Self, expn_data, transparency, pos| {
-            let span = location().fresh_expansion_with_transparency(expn_data, transparency);
-            this.synthetic_syntax_contexts.borrow_mut().insert(pos, span.ctxt());
-            span
-        };
-        Ok(match expn_data_tag {
-            TAG_NO_EXPN_DATA => location(),
-            TAG_EXPN_DATA_INLINE => {
-                let (expn_data, transparency) = Decodable::decode(self)?;
-                recover_from_expn_data(
-                    self,
-                    expn_data,
-                    transparency,
-                    AbsoluteBytePos::new(self.opaque.position()),
-                )
-            }
-            TAG_EXPN_DATA_SHORTHAND => {
-                let pos = AbsoluteBytePos::decode(self)?;
-                let cached_ctxt = self.synthetic_syntax_contexts.borrow().get(&pos).cloned();
-                if let Some(ctxt) = cached_ctxt {
-                    Span::new(lo, hi, ctxt)
-                } else {
-                    let (expn_data, transparency) =
-                        self.with_position(pos.to_usize(), |this| Decodable::decode(this))?;
-                    recover_from_expn_data(self, expn_data, transparency, pos)
-                }
-            }
-            _ => unreachable!(),
-        })
-    }
-}
-
-impl<'a, 'tcx> SpecializedDecoder<Ident> for CacheDecoder<'a, 'tcx> {
-    fn specialized_decode(&mut self) -> Result<Ident, Self::Error> {
-        // FIXME: Handle hygiene in incremental
-        bug!("Trying to decode Ident for incremental");
-    }
-}
-
-// This impl makes sure that we get a runtime error when we try decode a
-// `DefIndex` that is not contained in a `DefId`. Such a case would be problematic
-// because we would not know how to transform the `DefIndex` to the current
-// context.
-impl<'a, 'tcx> SpecializedDecoder<DefIndex> for CacheDecoder<'a, 'tcx> {
-    fn specialized_decode(&mut self) -> Result<DefIndex, Self::Error> {
-        bug!("trying to decode `DefIndex` outside the context of a `DefId`")
-    }
-}
-
-// Both the `CrateNum` and the `DefIndex` of a `DefId` can change in between two
-// compilation sessions. We use the `DefPathHash`, which is stable across
-// sessions, to map the old `DefId` to the new one.
-impl<'a, 'tcx> SpecializedDecoder<DefId> for CacheDecoder<'a, 'tcx> {
-    #[inline]
-    fn specialized_decode(&mut self) -> Result<DefId, Self::Error> {
-        // Load the `DefPathHash` which is was we encoded the `DefId` as.
-        let def_path_hash = DefPathHash::decode(self)?;
-
-        // Using the `DefPathHash`, we can lookup the new `DefId`.
-        Ok(self.tcx().def_path_hash_to_def_id.as_ref().unwrap()[&def_path_hash])
-    }
-}
-
-impl<'a, 'tcx> SpecializedDecoder<LocalDefId> for CacheDecoder<'a, 'tcx> {
-    #[inline]
-    fn specialized_decode(&mut self) -> Result<LocalDefId, Self::Error> {
-        Ok(LocalDefId::from_def_id(DefId::decode(self)?))
-    }
-}
-
-impl<'a, 'tcx> SpecializedDecoder<hir::HirId> for CacheDecoder<'a, 'tcx> {
-    fn specialized_decode(&mut self) -> Result<hir::HirId, Self::Error> {
-        // Load the `DefPathHash` which is what we encoded the `DefIndex` as.
-        let def_path_hash = DefPathHash::decode(self)?;
-
-        // Use the `DefPathHash` to map to the current `DefId`.
-        let def_id = self.tcx().def_path_hash_to_def_id.as_ref().unwrap()[&def_path_hash];
-
-        debug_assert!(def_id.is_local());
-
-        // The `ItemLocalId` needs no remapping.
-        let local_id = hir::ItemLocalId::decode(self)?;
-
-        // Reconstruct the `HirId` and look up the corresponding `NodeId` in the
-        // context of the current session.
-        Ok(hir::HirId { owner: def_id.index, local_id })
-    }
-}
-
-impl<'a, 'tcx> SpecializedDecoder<Fingerprint> for CacheDecoder<'a, 'tcx> {
-    fn specialized_decode(&mut self) -> Result<Fingerprint, Self::Error> {
-        Fingerprint::decode_opaque(&mut self.opaque)
-    }
-}
-
-impl<'a, 'tcx, T: Decodable> SpecializedDecoder<mir::ClearCrossCrate<T>>
-    for CacheDecoder<'a, 'tcx>
-{
-    #[inline]
-    fn specialized_decode(&mut self) -> Result<mir::ClearCrossCrate<T>, Self::Error> {
-        let discr = u8::decode(self)?;
-
-        match discr {
-            TAG_CLEAR_CROSS_CRATE_CLEAR => Ok(mir::ClearCrossCrate::Clear),
-            TAG_CLEAR_CROSS_CRATE_SET => {
-                let val = T::decode(self)?;
-                Ok(mir::ClearCrossCrate::Set(val))
-            }
-            _ => unreachable!(),
-        }
-    }
-}
-
-//- ENCODING -------------------------------------------------------------------
-
-/// An encoder that can write the incr. comp. cache.
-struct CacheEncoder<'a, 'tcx, E: ty_codec::TyEncoder> {
-    tcx: TyCtxt<'tcx>,
-    encoder: &'a mut E,
-    type_shorthands: FxHashMap<Ty<'tcx>, usize>,
-    predicate_shorthands: FxHashMap<ty::Predicate<'tcx>, usize>,
-    expn_data_shorthands: FxHashMap<ExpnId, AbsoluteBytePos>,
-    interpret_allocs: FxHashMap<interpret::AllocId, usize>,
-    interpret_allocs_inverse: Vec<interpret::AllocId>,
-    source_map: CachingSourceMapView<'tcx>,
-    file_to_file_index: FxHashMap<*const SourceFile, SourceFileIndex>,
-}
-
-impl<'a, 'tcx, E> CacheEncoder<'a, 'tcx, E>
-where
-    E: 'a + TyEncoder,
-{
-    fn source_file_index(&mut self, source_file: Lrc<SourceFile>) -> SourceFileIndex {
-        self.file_to_file_index[&(&*source_file as *const SourceFile)]
-    }
-
-    /// Encode something with additional information that allows to do some
-    /// sanity checks when decoding the data again. This method will first
-    /// encode the specified tag, then the given value, then the number of
-    /// bytes taken up by tag and value. On decoding, we can then verify that
-    /// we get the expected tag and read the expected number of bytes.
-    fn encode_tagged<T: Encodable, V: Encodable>(
-        &mut self,
-        tag: T,
-        value: &V,
-    ) -> Result<(), E::Error> {
-        let start_pos = self.position();
-
-        tag.encode(self)?;
-        value.encode(self)?;
-
-        let end_pos = self.position();
-        ((end_pos - start_pos) as u64).encode(self)
-    }
-}
-
-impl<'a, 'tcx, E> SpecializedEncoder<interpret::AllocId> for CacheEncoder<'a, 'tcx, E>
-where
-    E: 'a + TyEncoder,
-{
-    fn specialized_encode(&mut self, alloc_id: &interpret::AllocId) -> Result<(), Self::Error> {
-        use std::collections::hash_map::Entry;
-        let index = match self.interpret_allocs.entry(*alloc_id) {
-            Entry::Occupied(e) => *e.get(),
-            Entry::Vacant(e) => {
-                let idx = self.interpret_allocs_inverse.len();
-                self.interpret_allocs_inverse.push(*alloc_id);
-                e.insert(idx);
-                idx
-            }
-        };
-
-        index.encode(self)
-    }
-}
-
-impl<'a, 'tcx, E> SpecializedEncoder<Span> for CacheEncoder<'a, 'tcx, E>
-where
-    E: 'a + TyEncoder,
-{
-    fn specialized_encode(&mut self, span: &Span) -> Result<(), Self::Error> {
-        if *span == DUMMY_SP {
-            return TAG_INVALID_SPAN.encode(self);
-        }
-
-        let span_data = span.data();
-        let (file_lo, line_lo, col_lo) =
-            match self.source_map.byte_pos_to_line_and_col(span_data.lo) {
-                Some(pos) => pos,
-                None => return TAG_INVALID_SPAN.encode(self),
-            };
-
-        if !file_lo.contains(span_data.hi) {
-            return TAG_INVALID_SPAN.encode(self);
-        }
-
-        let len = span_data.hi - span_data.lo;
-
-        let source_file_index = self.source_file_index(file_lo);
-
-        TAG_VALID_SPAN.encode(self)?;
-        source_file_index.encode(self)?;
-        line_lo.encode(self)?;
-        col_lo.encode(self)?;
-        len.encode(self)?;
-
-        if span_data.ctxt == SyntaxContext::root() {
-            TAG_NO_EXPN_DATA.encode(self)
-        } else {
-            let (expn_id, transparency, expn_data) = span_data.ctxt.outer_mark_with_data();
-            if let Some(pos) = self.expn_data_shorthands.get(&expn_id).cloned() {
-                TAG_EXPN_DATA_SHORTHAND.encode(self)?;
-                pos.encode(self)
-            } else {
-                TAG_EXPN_DATA_INLINE.encode(self)?;
-                let pos = AbsoluteBytePos::new(self.position());
-                self.expn_data_shorthands.insert(expn_id, pos);
-                (expn_data, transparency).encode(self)
-            }
-        }
-    }
-}
-
-impl<'a, 'tcx, E> SpecializedEncoder<Ident> for CacheEncoder<'a, 'tcx, E>
-where
-    E: 'a + ty_codec::TyEncoder,
-{
-    fn specialized_encode(&mut self, _: &Ident) -> Result<(), Self::Error> {
-        // We don't currently encode enough information to ensure hygiene works
-        // with incremental, so panic rather than risk incremental bugs.
-
-        // FIXME: handle hygiene in incremental.
-        bug!("trying to encode `Ident` for incremental");
-    }
-}
-
-impl<'a, 'tcx, E> ty_codec::TyEncoder for CacheEncoder<'a, 'tcx, E>
-where
-    E: 'a + TyEncoder,
-{
-    #[inline]
-    fn position(&self) -> usize {
-        self.encoder.position()
-    }
-}
-
-impl<'a, 'tcx, E> SpecializedEncoder<CrateNum> for CacheEncoder<'a, 'tcx, E>
-where
-    E: 'a + TyEncoder,
-{
-    #[inline]
-    fn specialized_encode(&mut self, cnum: &CrateNum) -> Result<(), Self::Error> {
-        self.emit_u32(cnum.as_u32())
-    }
-}
-
-impl<'a, 'tcx, E> SpecializedEncoder<Ty<'tcx>> for CacheEncoder<'a, 'tcx, E>
-where
-    E: 'a + TyEncoder,
-{
-    #[inline]
-    fn specialized_encode(&mut self, ty: &Ty<'tcx>) -> Result<(), Self::Error> {
-        ty_codec::encode_with_shorthand(self, ty, |encoder| &mut encoder.type_shorthands)
-    }
-}
-
-impl<'a, 'tcx, E> SpecializedEncoder<&'tcx [(ty::Predicate<'tcx>, Span)]>
-    for CacheEncoder<'a, 'tcx, E>
-where
-    E: 'a + TyEncoder,
-{
-    #[inline]
-    fn specialized_encode(
-        &mut self,
-        predicates: &&'tcx [(ty::Predicate<'tcx>, Span)],
-    ) -> Result<(), Self::Error> {
-        ty_codec::encode_spanned_predicates(self, predicates, |encoder| {
-            &mut encoder.predicate_shorthands
-        })
-    }
-}
-
-impl<'a, 'tcx, E> SpecializedEncoder<hir::HirId> for CacheEncoder<'a, 'tcx, E>
-where
-    E: 'a + TyEncoder,
-{
-    #[inline]
-    fn specialized_encode(&mut self, id: &hir::HirId) -> Result<(), Self::Error> {
-        let hir::HirId { owner, local_id } = *id;
-
-        let def_path_hash = self.tcx.hir().definitions().def_path_hash(owner);
-
-        def_path_hash.encode(self)?;
-        local_id.encode(self)
-    }
-}
-
-impl<'a, 'tcx, E> SpecializedEncoder<DefId> for CacheEncoder<'a, 'tcx, E>
-where
-    E: 'a + TyEncoder,
-{
-    #[inline]
-    fn specialized_encode(&mut self, id: &DefId) -> Result<(), Self::Error> {
-        let def_path_hash = self.tcx.def_path_hash(*id);
-        def_path_hash.encode(self)
-    }
-}
-
-impl<'a, 'tcx, E> SpecializedEncoder<LocalDefId> for CacheEncoder<'a, 'tcx, E>
-where
-    E: 'a + TyEncoder,
-{
-    #[inline]
-    fn specialized_encode(&mut self, id: &LocalDefId) -> Result<(), Self::Error> {
-        id.to_def_id().encode(self)
-    }
-}
-
-impl<'a, 'tcx, E> SpecializedEncoder<DefIndex> for CacheEncoder<'a, 'tcx, E>
-where
-    E: 'a + TyEncoder,
-{
-    fn specialized_encode(&mut self, _: &DefIndex) -> Result<(), Self::Error> {
-        bug!("encoding `DefIndex` without context");
-    }
-}
-
-impl<'a, 'tcx> SpecializedEncoder<Fingerprint> for CacheEncoder<'a, 'tcx, opaque::Encoder> {
-    fn specialized_encode(&mut self, f: &Fingerprint) -> Result<(), Self::Error> {
-        f.encode_opaque(&mut self.encoder)
-    }
-}
-
-impl<'a, 'tcx, E, T> SpecializedEncoder<mir::ClearCrossCrate<T>> for CacheEncoder<'a, 'tcx, E>
-where
-    E: 'a + TyEncoder,
-    T: Encodable,
-{
-    #[inline]
-    fn specialized_encode(&mut self, val: &mir::ClearCrossCrate<T>) -> Result<(), Self::Error> {
-        match *val {
-            mir::ClearCrossCrate::Clear => TAG_CLEAR_CROSS_CRATE_CLEAR.encode(self),
-            mir::ClearCrossCrate::Set(ref val) => {
-                TAG_CLEAR_CROSS_CRATE_SET.encode(self)?;
-                val.encode(self)
-            }
-        }
-    }
-}
-
-macro_rules! encoder_methods {
-    ($($name:ident($ty:ty);)*) => {
-        #[inline]
-        $(fn $name(&mut self, value: $ty) -> Result<(), Self::Error> {
-            self.encoder.$name(value)
-        })*
-    }
-}
-
-impl<'a, 'tcx, E> Encoder for CacheEncoder<'a, 'tcx, E>
-where
-    E: 'a + TyEncoder,
-{
-    type Error = E::Error;
-
-    fn emit_unit(&mut self) -> Result<(), Self::Error> {
-        Ok(())
-    }
-
-    encoder_methods! {
-        emit_usize(usize);
-        emit_u128(u128);
-        emit_u64(u64);
-        emit_u32(u32);
-        emit_u16(u16);
-        emit_u8(u8);
-
-        emit_isize(isize);
-        emit_i128(i128);
-        emit_i64(i64);
-        emit_i32(i32);
-        emit_i16(i16);
-        emit_i8(i8);
-
-        emit_bool(bool);
-        emit_f64(f64);
-        emit_f32(f32);
-        emit_char(char);
-        emit_str(&str);
-    }
-}
-
-// An integer that will always encode to 8 bytes.
-struct IntEncodedWithFixedSize(u64);
-
-impl IntEncodedWithFixedSize {
-    pub const ENCODED_SIZE: usize = 8;
-}
-
-impl UseSpecializedEncodable for IntEncodedWithFixedSize {}
-impl UseSpecializedDecodable for IntEncodedWithFixedSize {}
-
-impl SpecializedEncoder<IntEncodedWithFixedSize> for opaque::Encoder {
-    fn specialized_encode(&mut self, x: &IntEncodedWithFixedSize) -> Result<(), Self::Error> {
-        let start_pos = self.position();
-        for i in 0..IntEncodedWithFixedSize::ENCODED_SIZE {
-            ((x.0 >> (i * 8)) as u8).encode(self)?;
-        }
-        let end_pos = self.position();
-        assert_eq!((end_pos - start_pos), IntEncodedWithFixedSize::ENCODED_SIZE);
-        Ok(())
-    }
-}
-
-impl<'a> SpecializedDecoder<IntEncodedWithFixedSize> for opaque::Decoder<'a> {
-    fn specialized_decode(&mut self) -> Result<IntEncodedWithFixedSize, Self::Error> {
-        let mut value: u64 = 0;
-        let start_pos = self.position();
-
-        for i in 0..IntEncodedWithFixedSize::ENCODED_SIZE {
-            let byte: u8 = Decodable::decode(self)?;
-            value |= (byte as u64) << (i * 8);
-        }
-
-        let end_pos = self.position();
-        assert_eq!((end_pos - start_pos), IntEncodedWithFixedSize::ENCODED_SIZE);
-
-        Ok(IntEncodedWithFixedSize(value))
-    }
-}
-
-fn encode_query_results<'a, 'tcx, Q, E>(
-    tcx: TyCtxt<'tcx>,
-    encoder: &mut CacheEncoder<'a, 'tcx, E>,
-    query_result_index: &mut EncodedQueryResultIndex,
-) -> Result<(), E::Error>
-where
-    Q: super::config::QueryDescription<'tcx, Value: Encodable>,
-    E: 'a + TyEncoder,
-{
-    let _timer = tcx
-        .sess
-        .prof
-        .extra_verbose_generic_activity("encode_query_results_for", ::std::any::type_name::<Q>());
-
-    let state = Q::query_state(tcx);
-    assert!(state.all_inactive());
-
-    state.iter_results(|results| {
-        for (key, value, dep_node) in results {
-            if Q::cache_on_disk(tcx, key.clone(), Some(&value)) {
-                let dep_node = SerializedDepNodeIndex::new(dep_node.index());
-
-                // Record position of the cache entry.
-                query_result_index.push((dep_node, AbsoluteBytePos::new(encoder.position())));
-
-                // Encode the type check tables with the `SerializedDepNodeIndex`
-                // as tag.
-                encoder.encode_tagged(dep_node, &value)?;
-            }
-        }
-        Ok(())
-    })
-}
diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs
deleted file mode 100644
index a61256b9fcb..00000000000
--- a/src/librustc/ty/query/plumbing.rs
+++ /dev/null
@@ -1,1266 +0,0 @@
-//! The implementation of the query system itself. This defines the macros that
-//! generate the actual methods on tcx which find and execute the provider,
-//! manage the caches, and so forth.
-
-use crate::dep_graph::{DepKind, DepNode, DepNodeIndex, SerializedDepNodeIndex};
-use crate::ty::query::caches::QueryCache;
-use crate::ty::query::config::{QueryAccessors, QueryDescription};
-use crate::ty::query::job::{QueryInfo, QueryJob, QueryJobId, QueryShardJobId};
-use crate::ty::query::Query;
-use crate::ty::tls;
-use crate::ty::{self, TyCtxt};
-
-#[cfg(not(parallel_compiler))]
-use rustc_data_structures::cold_path;
-use rustc_data_structures::fx::{FxHashMap, FxHasher};
-use rustc_data_structures::sharded::Sharded;
-use rustc_data_structures::sync::{Lock, LockGuard};
-use rustc_data_structures::thin_vec::ThinVec;
-use rustc_errors::{struct_span_err, Diagnostic, DiagnosticBuilder, FatalError, Handler, Level};
-use rustc_span::source_map::DUMMY_SP;
-use rustc_span::Span;
-use std::collections::hash_map::Entry;
-use std::hash::{Hash, Hasher};
-use std::mem;
-use std::num::NonZeroU32;
-use std::ptr;
-#[cfg(debug_assertions)]
-use std::sync::atomic::{AtomicUsize, Ordering};
-
-pub(crate) struct QueryStateShard<'tcx, D: QueryAccessors<'tcx> + ?Sized> {
-    pub(super) cache: <<D as QueryAccessors<'tcx>>::Cache as QueryCache<D::Key, D::Value>>::Sharded,
-    pub(super) active: FxHashMap<D::Key, QueryResult<'tcx>>,
-
-    /// Used to generate unique ids for active jobs.
-    pub(super) jobs: u32,
-}
-
-impl<'tcx, Q: QueryAccessors<'tcx>> QueryStateShard<'tcx, Q> {
-    fn get_cache(
-        &mut self,
-    ) -> &mut <<Q as QueryAccessors<'tcx>>::Cache as QueryCache<Q::Key, Q::Value>>::Sharded {
-        &mut self.cache
-    }
-}
-
-impl<'tcx, Q: QueryAccessors<'tcx>> Default for QueryStateShard<'tcx, Q> {
-    fn default() -> QueryStateShard<'tcx, Q> {
-        QueryStateShard { cache: Default::default(), active: Default::default(), jobs: 0 }
-    }
-}
-
-pub(crate) struct QueryState<'tcx, D: QueryAccessors<'tcx> + ?Sized> {
-    pub(super) cache: D::Cache,
-    pub(super) shards: Sharded<QueryStateShard<'tcx, D>>,
-    #[cfg(debug_assertions)]
-    pub(super) cache_hits: AtomicUsize,
-}
-
-impl<'tcx, Q: QueryAccessors<'tcx>> QueryState<'tcx, Q> {
-    pub(super) fn get_lookup<K: Hash>(&'tcx self, key: &K) -> QueryLookup<'tcx, Q> {
-        // We compute the key's hash once and then use it for both the
-        // shard lookup and the hashmap lookup. This relies on the fact
-        // that both of them use `FxHasher`.
-        let mut hasher = FxHasher::default();
-        key.hash(&mut hasher);
-        let key_hash = hasher.finish();
-
-        let shard = self.shards.get_shard_index_by_hash(key_hash);
-        let lock = self.shards.get_shard_by_index(shard).lock();
-        QueryLookup { key_hash, shard, lock }
-    }
-}
-
-/// Indicates the state of a query for a given key in a query map.
-pub(super) enum QueryResult<'tcx> {
-    /// An already executing query. The query job can be used to await for its completion.
-    Started(QueryJob<'tcx>),
-
-    /// The query panicked. Queries trying to wait on this will raise a fatal error which will
-    /// silently panic.
-    Poisoned,
-}
-
-impl<'tcx, M: QueryAccessors<'tcx>> QueryState<'tcx, M> {
-    pub fn iter_results<R>(
-        &self,
-        f: impl for<'a> FnOnce(
-            Box<dyn Iterator<Item = (&'a M::Key, &'a M::Value, DepNodeIndex)> + 'a>,
-        ) -> R,
-    ) -> R {
-        self.cache.iter(&self.shards, |shard| &mut shard.cache, f)
-    }
-    pub fn all_inactive(&self) -> bool {
-        let shards = self.shards.lock_shards();
-        shards.iter().all(|shard| shard.active.is_empty())
-    }
-}
-
-impl<'tcx, M: QueryAccessors<'tcx>> Default for QueryState<'tcx, M> {
-    fn default() -> QueryState<'tcx, M> {
-        QueryState {
-            cache: M::Cache::default(),
-            shards: Default::default(),
-            #[cfg(debug_assertions)]
-            cache_hits: AtomicUsize::new(0),
-        }
-    }
-}
-
-/// Values used when checking a query cache which can be reused on a cache-miss to execute the query.
-pub(crate) struct QueryLookup<'tcx, Q: QueryAccessors<'tcx>> {
-    pub(super) key_hash: u64,
-    pub(super) shard: usize,
-    pub(super) lock: LockGuard<'tcx, QueryStateShard<'tcx, Q>>,
-}
-
-/// A type representing the responsibility to execute the job in the `job` field.
-/// This will poison the relevant query if dropped.
-pub(super) struct JobOwner<'tcx, Q: QueryDescription<'tcx>> {
-    tcx: TyCtxt<'tcx>,
-    key: Q::Key,
-    id: QueryJobId,
-}
-
-impl<'tcx, Q: QueryDescription<'tcx>> JobOwner<'tcx, Q> {
-    /// Either gets a `JobOwner` corresponding the query, allowing us to
-    /// start executing the query, or returns with the result of the query.
-    /// This function assumes that `try_get_cached` is already called and returned `lookup`.
-    /// If the query is executing elsewhere, this will wait for it and return the result.
-    /// If the query panicked, this will silently panic.
-    ///
-    /// This function is inlined because that results in a noticeable speed-up
-    /// for some compile-time benchmarks.
-    #[inline(always)]
-    pub(super) fn try_start(
-        tcx: TyCtxt<'tcx>,
-        span: Span,
-        key: &Q::Key,
-        mut lookup: QueryLookup<'tcx, Q>,
-    ) -> TryGetJob<'tcx, Q> {
-        let lock = &mut *lookup.lock;
-
-        let (latch, mut _query_blocked_prof_timer) = match lock.active.entry((*key).clone()) {
-            Entry::Occupied(mut entry) => {
-                match entry.get_mut() {
-                    QueryResult::Started(job) => {
-                        // For parallel queries, we'll block and wait until the query running
-                        // in another thread has completed. Record how long we wait in the
-                        // self-profiler.
-                        let _query_blocked_prof_timer = if cfg!(parallel_compiler) {
-                            Some(tcx.prof.query_blocked())
-                        } else {
-                            None
-                        };
-
-                        // Create the id of the job we're waiting for
-                        let id = QueryJobId::new(job.id, lookup.shard, Q::dep_kind());
-
-                        (job.latch(id), _query_blocked_prof_timer)
-                    }
-                    QueryResult::Poisoned => FatalError.raise(),
-                }
-            }
-            Entry::Vacant(entry) => {
-                // No job entry for this query. Return a new one to be started later.
-
-                // Generate an id unique within this shard.
-                let id = lock.jobs.checked_add(1).unwrap();
-                lock.jobs = id;
-                let id = QueryShardJobId(NonZeroU32::new(id).unwrap());
-
-                let global_id = QueryJobId::new(id, lookup.shard, Q::dep_kind());
-
-                let job = tls::with_related_context(tcx, |icx| QueryJob::new(id, span, icx.query));
-
-                entry.insert(QueryResult::Started(job));
-
-                let owner = JobOwner { tcx, id: global_id, key: (*key).clone() };
-                return TryGetJob::NotYetStarted(owner);
-            }
-        };
-        mem::drop(lookup.lock);
-
-        // If we are single-threaded we know that we have cycle error,
-        // so we just return the error.
-        #[cfg(not(parallel_compiler))]
-        return TryGetJob::Cycle(cold_path(|| {
-            Q::handle_cycle_error(tcx, latch.find_cycle_in_stack(tcx, span))
-        }));
-
-        // With parallel queries we might just have to wait on some other
-        // thread.
-        #[cfg(parallel_compiler)]
-        {
-            let result = latch.wait_on(tcx, span);
-
-            if let Err(cycle) = result {
-                return TryGetJob::Cycle(Q::handle_cycle_error(tcx, cycle));
-            }
-
-            let cached = tcx.try_get_cached::<Q, _, _, _>(
-                (*key).clone(),
-                |value, index| (value.clone(), index),
-                |_, _| panic!("value must be in cache after waiting"),
-            );
-
-            if let Some(prof_timer) = _query_blocked_prof_timer.take() {
-                prof_timer.finish_with_query_invocation_id(cached.1.into());
-            }
-
-            return TryGetJob::JobCompleted(cached);
-        }
-    }
-
-    /// Completes the query by updating the query cache with the `result`,
-    /// signals the waiter and forgets the JobOwner, so it won't poison the query
-    #[inline(always)]
-    pub(super) fn complete(self, result: &Q::Value, dep_node_index: DepNodeIndex) {
-        // We can move out of `self` here because we `mem::forget` it below
-        let key = unsafe { ptr::read(&self.key) };
-        let tcx = self.tcx;
-
-        // Forget ourself so our destructor won't poison the query
-        mem::forget(self);
-
-        let job = {
-            let state = Q::query_state(tcx);
-            let result = result.clone();
-            let mut lock = state.shards.get_shard_by_value(&key).lock();
-            let job = match lock.active.remove(&key).unwrap() {
-                QueryResult::Started(job) => job,
-                QueryResult::Poisoned => panic!(),
-            };
-            state.cache.complete(tcx, &mut lock.cache, key, result, dep_node_index);
-            job
-        };
-
-        job.signal_complete();
-    }
-}
-
-#[inline(always)]
-fn with_diagnostics<F, R>(f: F) -> (R, ThinVec<Diagnostic>)
-where
-    F: FnOnce(Option<&Lock<ThinVec<Diagnostic>>>) -> R,
-{
-    let diagnostics = Lock::new(ThinVec::new());
-    let result = f(Some(&diagnostics));
-    (result, diagnostics.into_inner())
-}
-
-impl<'tcx, Q: QueryDescription<'tcx>> Drop for JobOwner<'tcx, Q> {
-    #[inline(never)]
-    #[cold]
-    fn drop(&mut self) {
-        // Poison the query so jobs waiting on it panic.
-        let state = Q::query_state(self.tcx);
-        let shard = state.shards.get_shard_by_value(&self.key);
-        let job = {
-            let mut shard = shard.lock();
-            let job = match shard.active.remove(&self.key).unwrap() {
-                QueryResult::Started(job) => job,
-                QueryResult::Poisoned => panic!(),
-            };
-            shard.active.insert(self.key.clone(), QueryResult::Poisoned);
-            job
-        };
-        // Also signal the completion of the job, so waiters
-        // will continue execution.
-        job.signal_complete();
-    }
-}
-
-#[derive(Clone)]
-pub struct CycleError<'tcx> {
-    /// The query and related span that uses the cycle.
-    pub(super) usage: Option<(Span, Query<'tcx>)>,
-    pub(super) cycle: Vec<QueryInfo<'tcx>>,
-}
-
-/// The result of `try_start`.
-pub(super) enum TryGetJob<'tcx, D: QueryDescription<'tcx>> {
-    /// The query is not yet started. Contains a guard to the cache eventually used to start it.
-    NotYetStarted(JobOwner<'tcx, D>),
-
-    /// The query was already completed.
-    /// Returns the result of the query and its dep-node index
-    /// if it succeeded or a cycle error if it failed.
-    #[cfg(parallel_compiler)]
-    JobCompleted((D::Value, DepNodeIndex)),
-
-    /// Trying to execute the query resulted in a cycle.
-    Cycle(D::Value),
-}
-
-impl<'tcx> TyCtxt<'tcx> {
-    /// Executes a job by changing the `ImplicitCtxt` to point to the
-    /// new query job while it executes. It returns the diagnostics
-    /// captured during execution and the actual result.
-    #[inline(always)]
-    pub(super) fn start_query<F, R>(
-        self,
-        token: QueryJobId,
-        diagnostics: Option<&Lock<ThinVec<Diagnostic>>>,
-        compute: F,
-    ) -> R
-    where
-        F: FnOnce(TyCtxt<'tcx>) -> R,
-    {
-        // The `TyCtxt` stored in TLS has the same global interner lifetime
-        // as `self`, so we use `with_related_context` to relate the 'tcx lifetimes
-        // when accessing the `ImplicitCtxt`.
-        tls::with_related_context(self, move |current_icx| {
-            // Update the `ImplicitCtxt` to point to our new query job.
-            let new_icx = tls::ImplicitCtxt {
-                tcx: self,
-                query: Some(token),
-                diagnostics,
-                layout_depth: current_icx.layout_depth,
-                task_deps: current_icx.task_deps,
-            };
-
-            // Use the `ImplicitCtxt` while we execute the query.
-            tls::enter_context(&new_icx, |_| compute(self))
-        })
-    }
-
-    #[inline(never)]
-    #[cold]
-    pub(super) fn report_cycle(
-        self,
-        CycleError { usage, cycle: stack }: CycleError<'tcx>,
-    ) -> DiagnosticBuilder<'tcx> {
-        assert!(!stack.is_empty());
-
-        let fix_span = |span: Span, query: &Query<'tcx>| {
-            self.sess.source_map().def_span(query.default_span(self, span))
-        };
-
-        // Disable naming impls with types in this path, since that
-        // sometimes cycles itself, leading to extra cycle errors.
-        // (And cycle errors around impls tend to occur during the
-        // collect/coherence phases anyhow.)
-        ty::print::with_forced_impl_filename_line(|| {
-            let span = fix_span(stack[1 % stack.len()].span, &stack[0].query);
-            let mut err = struct_span_err!(
-                self.sess,
-                span,
-                E0391,
-                "cycle detected when {}",
-                stack[0].query.describe(self)
-            );
-
-            for i in 1..stack.len() {
-                let query = &stack[i].query;
-                let span = fix_span(stack[(i + 1) % stack.len()].span, query);
-                err.span_note(span, &format!("...which requires {}...", query.describe(self)));
-            }
-
-            err.note(&format!(
-                "...which again requires {}, completing the cycle",
-                stack[0].query.describe(self)
-            ));
-
-            if let Some((span, query)) = usage {
-                err.span_note(
-                    fix_span(span, &query),
-                    &format!("cycle used when {}", query.describe(self)),
-                );
-            }
-
-            err
-        })
-    }
-
-    pub fn try_print_query_stack(handler: &Handler) {
-        eprintln!("query stack during panic:");
-
-        // Be careful reyling on global state here: this code is called from
-        // a panic hook, which means that the global `Handler` may be in a weird
-        // state if it was responsible for triggering the panic.
-        tls::with_context_opt(|icx| {
-            if let Some(icx) = icx {
-                let query_map = icx.tcx.queries.try_collect_active_jobs();
-
-                let mut current_query = icx.query;
-                let mut i = 0;
-
-                while let Some(query) = current_query {
-                    let query_info =
-                        if let Some(info) = query_map.as_ref().and_then(|map| map.get(&query)) {
-                            info
-                        } else {
-                            break;
-                        };
-                    let mut diag = Diagnostic::new(
-                        Level::FailureNote,
-                        &format!(
-                            "#{} [{}] {}",
-                            i,
-                            query_info.info.query.name(),
-                            query_info.info.query.describe(icx.tcx)
-                        ),
-                    );
-                    diag.span = icx.tcx.sess.source_map().def_span(query_info.info.span).into();
-                    handler.force_print_diagnostic(diag);
-
-                    current_query = query_info.job.parent;
-                    i += 1;
-                }
-            }
-        });
-
-        eprintln!("end of query stack");
-    }
-
-    /// Checks if the query is already computed and in the cache.
-    /// It returns the shard index and a lock guard to the shard,
-    /// which will be used if the query is not in the cache and we need
-    /// to compute it.
-    #[inline(always)]
-    fn try_get_cached<Q, R, OnHit, OnMiss>(
-        self,
-        key: Q::Key,
-        // `on_hit` can be called while holding a lock to the query cache
-        on_hit: OnHit,
-        on_miss: OnMiss,
-    ) -> R
-    where
-        Q: QueryDescription<'tcx> + 'tcx,
-        OnHit: FnOnce(&Q::Value, DepNodeIndex) -> R,
-        OnMiss: FnOnce(Q::Key, QueryLookup<'tcx, Q>) -> R,
-    {
-        let state = Q::query_state(self);
-
-        state.cache.lookup(
-            state,
-            QueryStateShard::<Q>::get_cache,
-            key,
-            |value, index| {
-                if unlikely!(self.prof.enabled()) {
-                    self.prof.query_cache_hit(index.into());
-                }
-                #[cfg(debug_assertions)]
-                {
-                    state.cache_hits.fetch_add(1, Ordering::Relaxed);
-                }
-                on_hit(value, index)
-            },
-            on_miss,
-        )
-    }
-
-    #[inline(never)]
-    pub(super) fn get_query<Q: QueryDescription<'tcx> + 'tcx>(
-        self,
-        span: Span,
-        key: Q::Key,
-    ) -> Q::Value {
-        debug!("ty::query::get_query<{}>(key={:?}, span={:?})", Q::NAME, key, span);
-
-        self.try_get_cached::<Q, _, _, _>(
-            key,
-            |value, index| {
-                self.dep_graph.read_index(index);
-                value.clone()
-            },
-            |key, lookup| self.try_execute_query::<Q>(span, key, lookup),
-        )
-    }
-
-    #[inline(always)]
-    pub(super) fn try_execute_query<Q: QueryDescription<'tcx>>(
-        self,
-        span: Span,
-        key: Q::Key,
-        lookup: QueryLookup<'tcx, Q>,
-    ) -> Q::Value {
-        let job = match JobOwner::try_start(self, span, &key, lookup) {
-            TryGetJob::NotYetStarted(job) => job,
-            TryGetJob::Cycle(result) => return result,
-            #[cfg(parallel_compiler)]
-            TryGetJob::JobCompleted((v, index)) => {
-                self.dep_graph.read_index(index);
-                return v;
-            }
-        };
-
-        // Fast path for when incr. comp. is off. `to_dep_node` is
-        // expensive for some `DepKind`s.
-        if !self.dep_graph.is_fully_enabled() {
-            let null_dep_node = DepNode::new_no_params(crate::dep_graph::DepKind::Null);
-            return self.force_query_with_job::<Q>(key, job, null_dep_node).0;
-        }
-
-        if Q::ANON {
-            let prof_timer = self.prof.query_provider();
-
-            let ((result, dep_node_index), diagnostics) = with_diagnostics(|diagnostics| {
-                self.start_query(job.id, diagnostics, |tcx| {
-                    tcx.dep_graph.with_anon_task(Q::dep_kind(), || Q::compute(tcx, key))
-                })
-            });
-
-            prof_timer.finish_with_query_invocation_id(dep_node_index.into());
-
-            self.dep_graph.read_index(dep_node_index);
-
-            if unlikely!(!diagnostics.is_empty()) {
-                self.queries
-                    .on_disk_cache
-                    .store_diagnostics_for_anon_node(dep_node_index, diagnostics);
-            }
-
-            job.complete(&result, dep_node_index);
-
-            return result;
-        }
-
-        let dep_node = Q::to_dep_node(self, &key);
-
-        if !Q::EVAL_ALWAYS {
-            // The diagnostics for this query will be
-            // promoted to the current session during
-            // `try_mark_green()`, so we can ignore them here.
-            let loaded = self.start_query(job.id, None, |tcx| {
-                let marked = tcx.dep_graph.try_mark_green_and_read(tcx, &dep_node);
-                marked.map(|(prev_dep_node_index, dep_node_index)| {
-                    (
-                        tcx.load_from_disk_and_cache_in_memory::<Q>(
-                            key.clone(),
-                            prev_dep_node_index,
-                            dep_node_index,
-                            &dep_node,
-                        ),
-                        dep_node_index,
-                    )
-                })
-            });
-            if let Some((result, dep_node_index)) = loaded {
-                job.complete(&result, dep_node_index);
-                return result;
-            }
-        }
-
-        let (result, dep_node_index) = self.force_query_with_job::<Q>(key, job, dep_node);
-        self.dep_graph.read_index(dep_node_index);
-        result
-    }
-
-    fn load_from_disk_and_cache_in_memory<Q: QueryDescription<'tcx>>(
-        self,
-        key: Q::Key,
-        prev_dep_node_index: SerializedDepNodeIndex,
-        dep_node_index: DepNodeIndex,
-        dep_node: &DepNode,
-    ) -> Q::Value {
-        // Note this function can be called concurrently from the same query
-        // We must ensure that this is handled correctly.
-
-        debug_assert!(self.dep_graph.is_green(dep_node));
-
-        // First we try to load the result from the on-disk cache.
-        let result = if Q::cache_on_disk(self, key.clone(), None)
-            && self.sess.opts.debugging_opts.incremental_queries
-        {
-            let prof_timer = self.prof.incr_cache_loading();
-            let result = Q::try_load_from_disk(self, prev_dep_node_index);
-            prof_timer.finish_with_query_invocation_id(dep_node_index.into());
-
-            // We always expect to find a cached result for things that
-            // can be forced from `DepNode`.
-            debug_assert!(
-                !dep_node.kind.can_reconstruct_query_key() || result.is_some(),
-                "missing on-disk cache entry for {:?}",
-                dep_node
-            );
-            result
-        } else {
-            // Some things are never cached on disk.
-            None
-        };
-
-        let result = if let Some(result) = result {
-            result
-        } else {
-            // We could not load a result from the on-disk cache, so
-            // recompute.
-            let prof_timer = self.prof.query_provider();
-
-            // The dep-graph for this computation is already in-place.
-            let result = self.dep_graph.with_ignore(|| Q::compute(self, key));
-
-            prof_timer.finish_with_query_invocation_id(dep_node_index.into());
-
-            result
-        };
-
-        // If `-Zincremental-verify-ich` is specified, re-hash results from
-        // the cache and make sure that they have the expected fingerprint.
-        if unlikely!(self.sess.opts.debugging_opts.incremental_verify_ich) {
-            self.incremental_verify_ich::<Q>(&result, dep_node, dep_node_index);
-        }
-
-        result
-    }
-
-    #[inline(never)]
-    #[cold]
-    fn incremental_verify_ich<Q: QueryDescription<'tcx>>(
-        self,
-        result: &Q::Value,
-        dep_node: &DepNode,
-        dep_node_index: DepNodeIndex,
-    ) {
-        use crate::ich::Fingerprint;
-
-        assert!(
-            Some(self.dep_graph.fingerprint_of(dep_node_index))
-                == self.dep_graph.prev_fingerprint_of(dep_node),
-            "fingerprint for green query instance not loaded from cache: {:?}",
-            dep_node,
-        );
-
-        debug!("BEGIN verify_ich({:?})", dep_node);
-        let mut hcx = self.create_stable_hashing_context();
-
-        let new_hash = Q::hash_result(&mut hcx, result).unwrap_or(Fingerprint::ZERO);
-        debug!("END verify_ich({:?})", dep_node);
-
-        let old_hash = self.dep_graph.fingerprint_of(dep_node_index);
-
-        assert!(new_hash == old_hash, "found unstable fingerprints for {:?}", dep_node,);
-    }
-
-    #[inline(always)]
-    fn force_query_with_job<Q: QueryDescription<'tcx>>(
-        self,
-        key: Q::Key,
-        job: JobOwner<'tcx, Q>,
-        dep_node: DepNode,
-    ) -> (Q::Value, DepNodeIndex) {
-        // If the following assertion triggers, it can have two reasons:
-        // 1. Something is wrong with DepNode creation, either here or
-        //    in `DepGraph::try_mark_green()`.
-        // 2. Two distinct query keys get mapped to the same `DepNode`
-        //    (see for example #48923).
-        assert!(
-            !self.dep_graph.dep_node_exists(&dep_node),
-            "forcing query with already existing `DepNode`\n\
-                 - query-key: {:?}\n\
-                 - dep-node: {:?}",
-            key,
-            dep_node
-        );
-
-        let prof_timer = self.prof.query_provider();
-
-        let ((result, dep_node_index), diagnostics) = with_diagnostics(|diagnostics| {
-            self.start_query(job.id, diagnostics, |tcx| {
-                if Q::EVAL_ALWAYS {
-                    tcx.dep_graph.with_eval_always_task(
-                        dep_node,
-                        tcx,
-                        key,
-                        Q::compute,
-                        Q::hash_result,
-                    )
-                } else {
-                    tcx.dep_graph.with_task(dep_node, tcx, key, Q::compute, Q::hash_result)
-                }
-            })
-        });
-
-        prof_timer.finish_with_query_invocation_id(dep_node_index.into());
-
-        if unlikely!(!diagnostics.is_empty()) {
-            if dep_node.kind != crate::dep_graph::DepKind::Null {
-                self.queries.on_disk_cache.store_diagnostics(dep_node_index, diagnostics);
-            }
-        }
-
-        job.complete(&result, dep_node_index);
-
-        (result, dep_node_index)
-    }
-
-    /// Ensure that either this query has all green inputs or been executed.
-    /// Executing `query::ensure(D)` is considered a read of the dep-node `D`.
-    ///
-    /// This function is particularly useful when executing passes for their
-    /// side-effects -- e.g., in order to report errors for erroneous programs.
-    ///
-    /// Note: The optimization is only available during incr. comp.
-    pub(super) fn ensure_query<Q: QueryDescription<'tcx> + 'tcx>(self, key: Q::Key) -> () {
-        if Q::EVAL_ALWAYS {
-            let _ = self.get_query::<Q>(DUMMY_SP, key);
-            return;
-        }
-
-        // Ensuring an anonymous query makes no sense
-        assert!(!Q::ANON);
-
-        let dep_node = Q::to_dep_node(self, &key);
-
-        match self.dep_graph.try_mark_green_and_read(self, &dep_node) {
-            None => {
-                // A None return from `try_mark_green_and_read` means that this is either
-                // a new dep node or that the dep node has already been marked red.
-                // Either way, we can't call `dep_graph.read()` as we don't have the
-                // DepNodeIndex. We must invoke the query itself. The performance cost
-                // this introduces should be negligible as we'll immediately hit the
-                // in-memory cache, or another query down the line will.
-                let _ = self.get_query::<Q>(DUMMY_SP, key);
-            }
-            Some((_, dep_node_index)) => {
-                self.prof.query_cache_hit(dep_node_index.into());
-            }
-        }
-    }
-
-    #[allow(dead_code)]
-    fn force_query<Q: QueryDescription<'tcx> + 'tcx>(
-        self,
-        key: Q::Key,
-        span: Span,
-        dep_node: DepNode,
-    ) {
-        // We may be concurrently trying both execute and force a query.
-        // Ensure that only one of them runs the query.
-
-        self.try_get_cached::<Q, _, _, _>(
-            key,
-            |_, _| {
-                // Cache hit, do nothing
-            },
-            |key, lookup| {
-                let job = match JobOwner::try_start(self, span, &key, lookup) {
-                    TryGetJob::NotYetStarted(job) => job,
-                    TryGetJob::Cycle(_) => return,
-                    #[cfg(parallel_compiler)]
-                    TryGetJob::JobCompleted(_) => return,
-                };
-                self.force_query_with_job::<Q>(key, job, dep_node);
-            },
-        );
-    }
-}
-
-macro_rules! handle_cycle_error {
-    ([][$tcx: expr, $error:expr]) => {{
-        $tcx.report_cycle($error).emit();
-        Value::from_cycle_error($tcx)
-    }};
-    ([fatal_cycle $($rest:tt)*][$tcx:expr, $error:expr]) => {{
-        $tcx.report_cycle($error).emit();
-        $tcx.sess.abort_if_errors();
-        unreachable!()
-    }};
-    ([cycle_delay_bug $($rest:tt)*][$tcx:expr, $error:expr]) => {{
-        $tcx.report_cycle($error).delay_as_bug();
-        Value::from_cycle_error($tcx)
-    }};
-    ([$other:ident $(($($other_args:tt)*))* $(, $($modifiers:tt)*)*][$($args:tt)*]) => {
-        handle_cycle_error!([$($($modifiers)*)*][$($args)*])
-    };
-}
-
-macro_rules! is_anon {
-    ([]) => {{
-        false
-    }};
-    ([anon $($rest:tt)*]) => {{
-        true
-    }};
-    ([$other:ident $(($($other_args:tt)*))* $(, $($modifiers:tt)*)*]) => {
-        is_anon!([$($($modifiers)*)*])
-    };
-}
-
-macro_rules! is_eval_always {
-    ([]) => {{
-        false
-    }};
-    ([eval_always $($rest:tt)*]) => {{
-        true
-    }};
-    ([$other:ident $(($($other_args:tt)*))* $(, $($modifiers:tt)*)*]) => {
-        is_eval_always!([$($($modifiers)*)*])
-    };
-}
-
-macro_rules! query_storage {
-    ([][$K:ty, $V:ty]) => {
-        <<$K as Key>::CacheSelector as CacheSelector<$K, $V>>::Cache
-    };
-    ([storage($ty:ty) $($rest:tt)*][$K:ty, $V:ty]) => {
-        $ty
-    };
-    ([$other:ident $(($($other_args:tt)*))* $(, $($modifiers:tt)*)*][$($args:tt)*]) => {
-        query_storage!([$($($modifiers)*)*][$($args)*])
-    };
-}
-
-macro_rules! hash_result {
-    ([][$hcx:expr, $result:expr]) => {{
-        dep_graph::hash_result($hcx, &$result)
-    }};
-    ([no_hash $($rest:tt)*][$hcx:expr, $result:expr]) => {{
-        None
-    }};
-    ([$other:ident $(($($other_args:tt)*))* $(, $($modifiers:tt)*)*][$($args:tt)*]) => {
-        hash_result!([$($($modifiers)*)*][$($args)*])
-    };
-}
-
-macro_rules! define_queries {
-    (<$tcx:tt> $($category:tt {
-        $($(#[$attr:meta])* [$($modifiers:tt)*] fn $name:ident: $node:ident($K:ty) -> $V:ty,)*
-    },)*) => {
-        define_queries_inner! { <$tcx>
-            $($( $(#[$attr])* category<$category> [$($modifiers)*] fn $name: $node($K) -> $V,)*)*
-        }
-    }
-}
-
-macro_rules! define_queries_inner {
-    (<$tcx:tt>
-     $($(#[$attr:meta])* category<$category:tt>
-        [$($modifiers:tt)*] fn $name:ident: $node:ident($K:ty) -> $V:ty,)*) => {
-
-        use std::mem;
-        use crate::{
-            rustc_data_structures::stable_hasher::HashStable,
-            rustc_data_structures::stable_hasher::StableHasher,
-            ich::StableHashingContext
-        };
-        use rustc_data_structures::profiling::ProfileCategory;
-
-        define_queries_struct! {
-            tcx: $tcx,
-            input: ($(([$($modifiers)*] [$($attr)*] [$name]))*)
-        }
-
-        impl<$tcx> Queries<$tcx> {
-            pub fn new(
-                providers: IndexVec<CrateNum, Providers<$tcx>>,
-                fallback_extern_providers: Providers<$tcx>,
-                on_disk_cache: OnDiskCache<'tcx>,
-            ) -> Self {
-                Queries {
-                    providers,
-                    fallback_extern_providers: Box::new(fallback_extern_providers),
-                    on_disk_cache,
-                    $($name: Default::default()),*
-                }
-            }
-
-            pub fn try_collect_active_jobs(
-                &self
-            ) -> Option<FxHashMap<QueryJobId, QueryJobInfo<'tcx>>> {
-                let mut jobs = FxHashMap::default();
-
-                $(
-                    // We use try_lock_shards here since we are called from the
-                    // deadlock handler, and this shouldn't be locked.
-                    let shards = self.$name.shards.try_lock_shards()?;
-                    let shards = shards.iter().enumerate();
-                    jobs.extend(shards.flat_map(|(shard_id, shard)| {
-                        shard.active.iter().filter_map(move |(k, v)| {
-                        if let QueryResult::Started(ref job) = *v {
-                                let id = QueryJobId {
-                                    job: job.id,
-                                    shard:  u16::try_from(shard_id).unwrap(),
-                                    kind:
-                                        <queries::$name<'tcx> as QueryAccessors<'tcx>>::dep_kind(),
-                                };
-                                let info = QueryInfo {
-                                    span: job.span,
-                                    query: queries::$name::query(k.clone())
-                                };
-                                Some((id, QueryJobInfo { info,  job: job.clone() }))
-                        } else {
-                            None
-                        }
-                        })
-                    }));
-                )*
-
-                Some(jobs)
-            }
-        }
-
-        #[allow(nonstandard_style)]
-        #[derive(Clone, Debug)]
-        pub enum Query<$tcx> {
-            $($(#[$attr])* $name($K)),*
-        }
-
-        impl<$tcx> Query<$tcx> {
-            pub fn name(&self) -> &'static str {
-                match *self {
-                    $(Query::$name(_) => stringify!($name),)*
-                }
-            }
-
-            pub fn describe(&self, tcx: TyCtxt<'_>) -> Cow<'static, str> {
-                let (r, name) = match *self {
-                    $(Query::$name(key) => {
-                        (queries::$name::describe(tcx, key), stringify!($name))
-                    })*
-                };
-                if tcx.sess.verbose() {
-                    format!("{} [{}]", r, name).into()
-                } else {
-                    r
-                }
-            }
-
-            // FIXME(eddyb) Get more valid `Span`s on queries.
-            pub fn default_span(&self, tcx: TyCtxt<$tcx>, span: Span) -> Span {
-                if !span.is_dummy() {
-                    return span;
-                }
-                // The `def_span` query is used to calculate `default_span`,
-                // so exit to avoid infinite recursion.
-                if let Query::def_span(..) = *self {
-                    return span
-                }
-                match *self {
-                    $(Query::$name(key) => key.default_span(tcx),)*
-                }
-            }
-        }
-
-        impl<'a, $tcx> HashStable<StableHashingContext<'a>> for Query<$tcx> {
-            fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-                mem::discriminant(self).hash_stable(hcx, hasher);
-                match *self {
-                    $(Query::$name(key) => key.hash_stable(hcx, hasher),)*
-                }
-            }
-        }
-
-        pub mod queries {
-            use std::marker::PhantomData;
-
-            $(#[allow(nonstandard_style)]
-            pub struct $name<$tcx> {
-                data: PhantomData<&$tcx ()>
-            })*
-        }
-
-        // This module and the functions in it exist only to provide a
-        // predictable symbol name prefix for query providers. This is helpful
-        // for analyzing queries in profilers.
-        pub(super) mod __query_compute {
-            $(#[inline(never)]
-            pub fn $name<F: FnOnce() -> R, R>(f: F) -> R {
-                f()
-            })*
-        }
-
-        $(impl<$tcx> QueryConfig<$tcx> for queries::$name<$tcx> {
-            type Key = $K;
-            type Value = $V;
-            const NAME: &'static str = stringify!($name);
-            const CATEGORY: ProfileCategory = $category;
-        }
-
-        impl<$tcx> QueryAccessors<$tcx> for queries::$name<$tcx> {
-            const ANON: bool = is_anon!([$($modifiers)*]);
-            const EVAL_ALWAYS: bool = is_eval_always!([$($modifiers)*]);
-
-            type Cache = query_storage!([$($modifiers)*][$K, $V]);
-
-            #[inline(always)]
-            fn query(key: Self::Key) -> Query<'tcx> {
-                Query::$name(key)
-            }
-
-            #[inline(always)]
-            fn query_state<'a>(tcx: TyCtxt<$tcx>) -> &'a QueryState<$tcx, Self> {
-                &tcx.queries.$name
-            }
-
-            #[allow(unused)]
-            #[inline(always)]
-            fn to_dep_node(tcx: TyCtxt<$tcx>, key: &Self::Key) -> DepNode {
-                DepConstructor::$node(tcx, *key)
-            }
-
-            #[inline(always)]
-            fn dep_kind() -> dep_graph::DepKind {
-                dep_graph::DepKind::$node
-            }
-
-            #[inline]
-            fn compute(tcx: TyCtxt<'tcx>, key: Self::Key) -> Self::Value {
-                __query_compute::$name(move || {
-                    let provider = tcx.queries.providers.get(key.query_crate())
-                        // HACK(eddyb) it's possible crates may be loaded after
-                        // the query engine is created, and because crate loading
-                        // is not yet integrated with the query engine, such crates
-                        // would be missing appropriate entries in `providers`.
-                        .unwrap_or(&tcx.queries.fallback_extern_providers)
-                        .$name;
-                    provider(tcx, key)
-                })
-            }
-
-            fn hash_result(
-                _hcx: &mut StableHashingContext<'_>,
-                _result: &Self::Value
-            ) -> Option<Fingerprint> {
-                hash_result!([$($modifiers)*][_hcx, _result])
-            }
-
-            fn handle_cycle_error(
-                tcx: TyCtxt<'tcx>,
-                error: CycleError<'tcx>
-            ) -> Self::Value {
-                handle_cycle_error!([$($modifiers)*][tcx, error])
-            }
-        })*
-
-        #[derive(Copy, Clone)]
-        pub struct TyCtxtEnsure<'tcx> {
-            pub tcx: TyCtxt<'tcx>,
-        }
-
-        impl TyCtxtEnsure<$tcx> {
-            $($(#[$attr])*
-            #[inline(always)]
-            pub fn $name(self, key: $K) {
-                self.tcx.ensure_query::<queries::$name<'_>>(key)
-            })*
-        }
-
-        #[derive(Copy, Clone)]
-        pub struct TyCtxtAt<'tcx> {
-            pub tcx: TyCtxt<'tcx>,
-            pub span: Span,
-        }
-
-        impl Deref for TyCtxtAt<'tcx> {
-            type Target = TyCtxt<'tcx>;
-            #[inline(always)]
-            fn deref(&self) -> &Self::Target {
-                &self.tcx
-            }
-        }
-
-        impl TyCtxt<$tcx> {
-            /// Returns a transparent wrapper for `TyCtxt`, which ensures queries
-            /// are executed instead of just returing their results.
-            #[inline(always)]
-            pub fn ensure(self) -> TyCtxtEnsure<$tcx> {
-                TyCtxtEnsure {
-                    tcx: self,
-                }
-            }
-
-            /// Returns a transparent wrapper for `TyCtxt` which uses
-            /// `span` as the location of queries performed through it.
-            #[inline(always)]
-            pub fn at(self, span: Span) -> TyCtxtAt<$tcx> {
-                TyCtxtAt {
-                    tcx: self,
-                    span
-                }
-            }
-
-            $($(#[$attr])*
-            #[inline(always)]
-            pub fn $name(self, key: $K) -> $V {
-                self.at(DUMMY_SP).$name(key)
-            })*
-
-            /// All self-profiling events generated by the query engine use
-            /// virtual `StringId`s for their `event_id`. This method makes all
-            /// those virtual `StringId`s point to actual strings.
-            ///
-            /// If we are recording only summary data, the ids will point to
-            /// just the query names. If we are recording query keys too, we
-            /// allocate the corresponding strings here.
-            pub fn alloc_self_profile_query_strings(self) {
-                use crate::ty::query::profiling_support::{
-                    alloc_self_profile_query_strings_for_query_cache,
-                    QueryKeyStringCache,
-                };
-
-                if !self.prof.enabled() {
-                    return;
-                }
-
-                let mut string_cache = QueryKeyStringCache::new();
-
-                $({
-                    alloc_self_profile_query_strings_for_query_cache(
-                        self,
-                        stringify!($name),
-                        &self.queries.$name,
-                        &mut string_cache,
-                    );
-                })*
-            }
-        }
-
-        impl TyCtxtAt<$tcx> {
-            $($(#[$attr])*
-            #[inline(always)]
-            pub fn $name(self, key: $K) -> $V {
-                self.tcx.get_query::<queries::$name<'_>>(self.span, key)
-            })*
-        }
-
-        define_provider_struct! {
-            tcx: $tcx,
-            input: ($(([$($modifiers)*] [$name] [$K] [$V]))*)
-        }
-
-        impl<$tcx> Copy for Providers<$tcx> {}
-        impl<$tcx> Clone for Providers<$tcx> {
-            fn clone(&self) -> Self { *self }
-        }
-    }
-}
-
-macro_rules! define_queries_struct {
-    (tcx: $tcx:tt,
-     input: ($(([$($modifiers:tt)*] [$($attr:tt)*] [$name:ident]))*)) => {
-        pub struct Queries<$tcx> {
-            /// This provides access to the incrimental comilation on-disk cache for query results.
-            /// Do not access this directly. It is only meant to be used by
-            /// `DepGraph::try_mark_green()` and the query infrastructure.
-            pub(crate) on_disk_cache: OnDiskCache<'tcx>,
-
-            providers: IndexVec<CrateNum, Providers<$tcx>>,
-            fallback_extern_providers: Box<Providers<$tcx>>,
-
-            $($(#[$attr])*  $name: QueryState<$tcx, queries::$name<$tcx>>,)*
-        }
-    };
-}
-
-macro_rules! define_provider_struct {
-    (tcx: $tcx:tt,
-     input: ($(([$($modifiers:tt)*] [$name:ident] [$K:ty] [$R:ty]))*)) => {
-        pub struct Providers<$tcx> {
-            $(pub $name: fn(TyCtxt<$tcx>, $K) -> $R,)*
-        }
-
-        impl<$tcx> Default for Providers<$tcx> {
-            fn default() -> Self {
-                $(fn $name<$tcx>(_: TyCtxt<$tcx>, key: $K) -> $R {
-                    bug!("`tcx.{}({:?})` unsupported by its crate",
-                         stringify!($name), key);
-                })*
-                Providers { $($name),* }
-            }
-        }
-    };
-}
-
-/// The red/green evaluation system will try to mark a specific DepNode in the
-/// dependency graph as green by recursively trying to mark the dependencies of
-/// that `DepNode` as green. While doing so, it will sometimes encounter a `DepNode`
-/// where we don't know if it is red or green and we therefore actually have
-/// to recompute its value in order to find out. Since the only piece of
-/// information that we have at that point is the `DepNode` we are trying to
-/// re-evaluate, we need some way to re-run a query from just that. This is what
-/// `force_from_dep_node()` implements.
-///
-/// In the general case, a `DepNode` consists of a `DepKind` and an opaque
-/// GUID/fingerprint that will uniquely identify the node. This GUID/fingerprint
-/// is usually constructed by computing a stable hash of the query-key that the
-/// `DepNode` corresponds to. Consequently, it is not in general possible to go
-/// back from hash to query-key (since hash functions are not reversible). For
-/// this reason `force_from_dep_node()` is expected to fail from time to time
-/// because we just cannot find out, from the `DepNode` alone, what the
-/// corresponding query-key is and therefore cannot re-run the query.
-///
-/// The system deals with this case letting `try_mark_green` fail which forces
-/// the root query to be re-evaluated.
-///
-/// Now, if `force_from_dep_node()` would always fail, it would be pretty useless.
-/// Fortunately, we can use some contextual information that will allow us to
-/// reconstruct query-keys for certain kinds of `DepNode`s. In particular, we
-/// enforce by construction that the GUID/fingerprint of certain `DepNode`s is a
-/// valid `DefPathHash`. Since we also always build a huge table that maps every
-/// `DefPathHash` in the current codebase to the corresponding `DefId`, we have
-/// everything we need to re-run the query.
-///
-/// Take the `mir_validated` query as an example. Like many other queries, it
-/// just has a single parameter: the `DefId` of the item it will compute the
-/// validated MIR for. Now, when we call `force_from_dep_node()` on a `DepNode`
-/// with kind `MirValidated`, we know that the GUID/fingerprint of the `DepNode`
-/// is actually a `DefPathHash`, and can therefore just look up the corresponding
-/// `DefId` in `tcx.def_path_hash_to_def_id`.
-///
-/// When you implement a new query, it will likely have a corresponding new
-/// `DepKind`, and you'll have to support it here in `force_from_dep_node()`. As
-/// a rule of thumb, if your query takes a `DefId` or `DefIndex` as sole parameter,
-/// then `force_from_dep_node()` should not fail for it. Otherwise, you can just
-/// add it to the "We don't have enough information to reconstruct..." group in
-/// the match below.
-pub fn force_from_dep_node(tcx: TyCtxt<'_>, dep_node: &DepNode) -> bool {
-    use crate::dep_graph::RecoverKey;
-
-    // We must avoid ever having to call `force_from_dep_node()` for a
-    // `DepNode::codegen_unit`:
-    // Since we cannot reconstruct the query key of a `DepNode::codegen_unit`, we
-    // would always end up having to evaluate the first caller of the
-    // `codegen_unit` query that *is* reconstructible. This might very well be
-    // the `compile_codegen_unit` query, thus re-codegenning the whole CGU just
-    // to re-trigger calling the `codegen_unit` query with the right key. At
-    // that point we would already have re-done all the work we are trying to
-    // avoid doing in the first place.
-    // The solution is simple: Just explicitly call the `codegen_unit` query for
-    // each CGU, right after partitioning. This way `try_mark_green` will always
-    // hit the cache instead of having to go through `force_from_dep_node`.
-    // This assertion makes sure, we actually keep applying the solution above.
-    debug_assert!(
-        dep_node.kind != DepKind::codegen_unit,
-        "calling force_from_dep_node() on DepKind::codegen_unit"
-    );
-
-    if !dep_node.kind.can_reconstruct_query_key() {
-        return false;
-    }
-
-    rustc_dep_node_force!([dep_node, tcx]
-        // These are inputs that are expected to be pre-allocated and that
-        // should therefore always be red or green already.
-        DepKind::AllLocalTraitImpls |
-        DepKind::CrateMetadata |
-        DepKind::HirBody |
-        DepKind::Hir |
-
-        // These are anonymous nodes.
-        DepKind::TraitSelect |
-
-        // We don't have enough information to reconstruct the query key of
-        // these.
-        DepKind::CompileCodegenUnit => {
-            bug!("force_from_dep_node: encountered {:?}", dep_node)
-        }
-
-        DepKind::Analysis => {
-            let def_id = if let Some(def_id) = dep_node.extract_def_id(tcx) {
-                def_id
-            } else {
-                // Return from the whole function.
-                return false
-            };
-            tcx.force_query::<crate::ty::query::queries::analysis<'_>>(
-                def_id.krate,
-                DUMMY_SP,
-                *dep_node
-            );
-        }
-    );
-
-    true
-}
diff --git a/src/librustc/ty/query/profiling_support.rs b/src/librustc/ty/query/profiling_support.rs
deleted file mode 100644
index 99ada34d59e..00000000000
--- a/src/librustc/ty/query/profiling_support.rs
+++ /dev/null
@@ -1,218 +0,0 @@
-use crate::hir::map::definitions::DefPathData;
-use crate::ty::context::TyCtxt;
-use crate::ty::query::config::QueryAccessors;
-use crate::ty::query::plumbing::QueryState;
-use measureme::{StringComponent, StringId};
-use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::profiling::SelfProfiler;
-use rustc_hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
-use std::fmt::Debug;
-use std::io::Write;
-
-pub struct QueryKeyStringCache {
-    def_id_cache: FxHashMap<DefId, StringId>,
-}
-
-impl QueryKeyStringCache {
-    pub fn new() -> QueryKeyStringCache {
-        QueryKeyStringCache { def_id_cache: Default::default() }
-    }
-}
-
-pub struct QueryKeyStringBuilder<'p, 'c, 'tcx> {
-    profiler: &'p SelfProfiler,
-    tcx: TyCtxt<'tcx>,
-    string_cache: &'c mut QueryKeyStringCache,
-}
-
-impl<'p, 'c, 'tcx> QueryKeyStringBuilder<'p, 'c, 'tcx> {
-    pub fn new(
-        profiler: &'p SelfProfiler,
-        tcx: TyCtxt<'tcx>,
-        string_cache: &'c mut QueryKeyStringCache,
-    ) -> QueryKeyStringBuilder<'p, 'c, 'tcx> {
-        QueryKeyStringBuilder { profiler, tcx, string_cache }
-    }
-
-    // The current implementation is rather crude. In the future it might be a
-    // good idea to base this on `ty::print` in order to get nicer and more
-    // efficient query keys.
-    fn def_id_to_string_id(&mut self, def_id: DefId) -> StringId {
-        if let Some(&string_id) = self.string_cache.def_id_cache.get(&def_id) {
-            return string_id;
-        }
-
-        let def_key = self.tcx.def_key(def_id);
-
-        let (parent_string_id, start_index) = match def_key.parent {
-            Some(parent_index) => {
-                let parent_def_id = DefId { index: parent_index, krate: def_id.krate };
-
-                (self.def_id_to_string_id(parent_def_id), 0)
-            }
-            None => (StringId::INVALID, 2),
-        };
-
-        let dis_buffer = &mut [0u8; 16];
-        let name;
-        let dis;
-        let end_index;
-
-        match def_key.disambiguated_data.data {
-            DefPathData::CrateRoot => {
-                name = self.tcx.original_crate_name(def_id.krate).as_str();
-                dis = "";
-                end_index = 3;
-            }
-            other => {
-                name = other.as_symbol().as_str();
-                if def_key.disambiguated_data.disambiguator == 0 {
-                    dis = "";
-                    end_index = 3;
-                } else {
-                    write!(&mut dis_buffer[..], "[{}]", def_key.disambiguated_data.disambiguator)
-                        .unwrap();
-                    let end_of_dis = dis_buffer.iter().position(|&c| c == b']').unwrap();
-                    dis = std::str::from_utf8(&dis_buffer[..end_of_dis + 1]).unwrap();
-                    end_index = 4;
-                }
-            }
-        }
-
-        let components = [
-            StringComponent::Ref(parent_string_id),
-            StringComponent::Value("::"),
-            StringComponent::Value(&name[..]),
-            StringComponent::Value(dis),
-        ];
-
-        let string_id = self.profiler.alloc_string(&components[start_index..end_index]);
-
-        self.string_cache.def_id_cache.insert(def_id, string_id);
-
-        string_id
-    }
-}
-
-pub trait IntoSelfProfilingString {
-    fn to_self_profile_string(&self, builder: &mut QueryKeyStringBuilder<'_, '_, '_>) -> StringId;
-}
-
-// The default implementation of `IntoSelfProfilingString` just uses `Debug`
-// which is slow and causes lots of duplication of string data.
-// The specialized impls below take care of making the `DefId` case more
-// efficient.
-impl<T: Debug> IntoSelfProfilingString for T {
-    default fn to_self_profile_string(
-        &self,
-        builder: &mut QueryKeyStringBuilder<'_, '_, '_>,
-    ) -> StringId {
-        let s = format!("{:?}", self);
-        builder.profiler.alloc_string(&s[..])
-    }
-}
-
-impl IntoSelfProfilingString for DefId {
-    fn to_self_profile_string(&self, builder: &mut QueryKeyStringBuilder<'_, '_, '_>) -> StringId {
-        builder.def_id_to_string_id(*self)
-    }
-}
-
-impl IntoSelfProfilingString for CrateNum {
-    fn to_self_profile_string(&self, builder: &mut QueryKeyStringBuilder<'_, '_, '_>) -> StringId {
-        builder.def_id_to_string_id(DefId { krate: *self, index: CRATE_DEF_INDEX })
-    }
-}
-
-impl IntoSelfProfilingString for DefIndex {
-    fn to_self_profile_string(&self, builder: &mut QueryKeyStringBuilder<'_, '_, '_>) -> StringId {
-        builder.def_id_to_string_id(DefId { krate: LOCAL_CRATE, index: *self })
-    }
-}
-
-impl<T0, T1> IntoSelfProfilingString for (T0, T1)
-where
-    T0: IntoSelfProfilingString + Debug,
-    T1: IntoSelfProfilingString + Debug,
-{
-    default fn to_self_profile_string(
-        &self,
-        builder: &mut QueryKeyStringBuilder<'_, '_, '_>,
-    ) -> StringId {
-        let val0 = self.0.to_self_profile_string(builder);
-        let val1 = self.1.to_self_profile_string(builder);
-
-        let components = &[
-            StringComponent::Value("("),
-            StringComponent::Ref(val0),
-            StringComponent::Value(","),
-            StringComponent::Ref(val1),
-            StringComponent::Value(")"),
-        ];
-
-        builder.profiler.alloc_string(components)
-    }
-}
-
-/// Allocate the self-profiling query strings for a single query cache. This
-/// method is called from `alloc_self_profile_query_strings` which knows all
-/// the queries via macro magic.
-pub(super) fn alloc_self_profile_query_strings_for_query_cache<'tcx, Q>(
-    tcx: TyCtxt<'tcx>,
-    query_name: &'static str,
-    query_state: &QueryState<'tcx, Q>,
-    string_cache: &mut QueryKeyStringCache,
-) where
-    Q: QueryAccessors<'tcx>,
-{
-    tcx.prof.with_profiler(|profiler| {
-        let event_id_builder = profiler.event_id_builder();
-
-        // Walk the entire query cache and allocate the appropriate
-        // string representations. Each cache entry is uniquely
-        // identified by its dep_node_index.
-        if profiler.query_key_recording_enabled() {
-            let mut query_string_builder = QueryKeyStringBuilder::new(profiler, tcx, string_cache);
-
-            let query_name = profiler.get_or_alloc_cached_string(query_name);
-
-            // Since building the string representation of query keys might
-            // need to invoke queries itself, we cannot keep the query caches
-            // locked while doing so. Instead we copy out the
-            // `(query_key, dep_node_index)` pairs and release the lock again.
-            let query_keys_and_indices: Vec<_> = query_state
-                .iter_results(|results| results.map(|(k, _, i)| (k.clone(), i)).collect());
-
-            // Now actually allocate the strings. If allocating the strings
-            // generates new entries in the query cache, we'll miss them but
-            // we don't actually care.
-            for (query_key, dep_node_index) in query_keys_and_indices {
-                // Translate the DepNodeIndex into a QueryInvocationId
-                let query_invocation_id = dep_node_index.into();
-
-                // Create the string version of the query-key
-                let query_key = query_key.to_self_profile_string(&mut query_string_builder);
-                let event_id = event_id_builder.from_label_and_arg(query_name, query_key);
-
-                // Doing this in bulk might be a good idea:
-                profiler.map_query_invocation_id_to_string(
-                    query_invocation_id,
-                    event_id.to_string_id(),
-                );
-            }
-        } else {
-            // In this branch we don't allocate query keys
-            let query_name = profiler.get_or_alloc_cached_string(query_name);
-            let event_id = event_id_builder.from_label(query_name).to_string_id();
-
-            query_state.iter_results(|results| {
-                let query_invocation_ids: Vec<_> = results.map(|v| v.2.into()).collect();
-
-                profiler.bulk_map_query_invocation_id_to_single_string(
-                    query_invocation_ids.into_iter(),
-                    event_id,
-                );
-            });
-        }
-    });
-}
diff --git a/src/librustc/ty/query/stats.rs b/src/librustc/ty/query/stats.rs
deleted file mode 100644
index d257320d4ea..00000000000
--- a/src/librustc/ty/query/stats.rs
+++ /dev/null
@@ -1,139 +0,0 @@
-use crate::ty::query::config::QueryAccessors;
-use crate::ty::query::plumbing::QueryState;
-use crate::ty::query::queries;
-use crate::ty::TyCtxt;
-use rustc_hir::def_id::{DefId, LOCAL_CRATE};
-
-use std::any::type_name;
-use std::mem;
-#[cfg(debug_assertions)]
-use std::sync::atomic::Ordering;
-
-trait KeyStats {
-    fn key_stats(&self, stats: &mut QueryStats);
-}
-
-impl<T> KeyStats for T {
-    default fn key_stats(&self, _: &mut QueryStats) {}
-}
-
-impl KeyStats for DefId {
-    fn key_stats(&self, stats: &mut QueryStats) {
-        if self.krate == LOCAL_CRATE {
-            stats.local_def_id_keys = Some(stats.local_def_id_keys.unwrap_or(0) + 1);
-        }
-    }
-}
-
-#[derive(Clone)]
-struct QueryStats {
-    name: &'static str,
-    cache_hits: usize,
-    key_size: usize,
-    key_type: &'static str,
-    value_size: usize,
-    value_type: &'static str,
-    entry_count: usize,
-    local_def_id_keys: Option<usize>,
-}
-
-fn stats<'tcx, Q: QueryAccessors<'tcx>>(
-    name: &'static str,
-    map: &QueryState<'tcx, Q>,
-) -> QueryStats {
-    let mut stats = QueryStats {
-        name,
-        #[cfg(debug_assertions)]
-        cache_hits: map.cache_hits.load(Ordering::Relaxed),
-        #[cfg(not(debug_assertions))]
-        cache_hits: 0,
-        key_size: mem::size_of::<Q::Key>(),
-        key_type: type_name::<Q::Key>(),
-        value_size: mem::size_of::<Q::Value>(),
-        value_type: type_name::<Q::Value>(),
-        entry_count: map.iter_results(|results| results.count()),
-        local_def_id_keys: None,
-    };
-    map.iter_results(|results| {
-        for (key, _, _) in results {
-            key.key_stats(&mut stats)
-        }
-    });
-    stats
-}
-
-pub fn print_stats(tcx: TyCtxt<'_>) {
-    let queries = query_stats(tcx);
-
-    if cfg!(debug_assertions) {
-        let hits: usize = queries.iter().map(|s| s.cache_hits).sum();
-        let results: usize = queries.iter().map(|s| s.entry_count).sum();
-        println!("\nQuery cache hit rate: {}", hits as f64 / (hits + results) as f64);
-    }
-
-    let mut query_key_sizes = queries.clone();
-    query_key_sizes.sort_by_key(|q| q.key_size);
-    println!("\nLarge query keys:");
-    for q in query_key_sizes.iter().rev().filter(|q| q.key_size > 8) {
-        println!("   {} - {} x {} - {}", q.name, q.key_size, q.entry_count, q.key_type);
-    }
-
-    let mut query_value_sizes = queries.clone();
-    query_value_sizes.sort_by_key(|q| q.value_size);
-    println!("\nLarge query values:");
-    for q in query_value_sizes.iter().rev().filter(|q| q.value_size > 8) {
-        println!("   {} - {} x {} - {}", q.name, q.value_size, q.entry_count, q.value_type);
-    }
-
-    if cfg!(debug_assertions) {
-        let mut query_cache_hits = queries.clone();
-        query_cache_hits.sort_by_key(|q| q.cache_hits);
-        println!("\nQuery cache hits:");
-        for q in query_cache_hits.iter().rev() {
-            println!(
-                "   {} - {} ({}%)",
-                q.name,
-                q.cache_hits,
-                q.cache_hits as f64 / (q.cache_hits + q.entry_count) as f64
-            );
-        }
-    }
-
-    let mut query_value_count = queries.clone();
-    query_value_count.sort_by_key(|q| q.entry_count);
-    println!("\nQuery value count:");
-    for q in query_value_count.iter().rev() {
-        println!("   {} - {}", q.name, q.entry_count);
-    }
-
-    let mut def_id_density: Vec<_> =
-        queries.iter().filter(|q| q.local_def_id_keys.is_some()).collect();
-    def_id_density.sort_by_key(|q| q.local_def_id_keys.unwrap());
-    println!("\nLocal DefId density:");
-    let total = tcx.hir().definitions().def_index_count() as f64;
-    for q in def_id_density.iter().rev() {
-        let local = q.local_def_id_keys.unwrap();
-        println!("   {} - {} = ({}%)", q.name, local, (local as f64 * 100.0) / total);
-    }
-}
-
-macro_rules! print_stats {
-    (<$tcx:tt> $($category:tt {
-        $($(#[$attr:meta])* [$($modifiers:tt)*] fn $name:ident: $node:ident($K:ty) -> $V:ty,)*
-    },)*) => {
-        fn query_stats(tcx: TyCtxt<'_>) -> Vec<QueryStats> {
-            let mut queries = Vec::new();
-
-            $($(
-                queries.push(stats::<queries::$name<'_>>(
-                    stringify!($name),
-                    &tcx.queries.$name,
-                ));
-            )*)*
-
-            queries
-        }
-    }
-}
-
-rustc_query_append! { [print_stats!][<'tcx>] }
diff --git a/src/librustc/ty/query/values.rs b/src/librustc/ty/query/values.rs
deleted file mode 100644
index b01d15c29b2..00000000000
--- a/src/librustc/ty/query/values.rs
+++ /dev/null
@@ -1,32 +0,0 @@
-use crate::ty::{self, AdtSizedConstraint, Ty, TyCtxt};
-
-use rustc_span::symbol::Symbol;
-
-pub(super) trait Value<'tcx>: Sized {
-    fn from_cycle_error(tcx: TyCtxt<'tcx>) -> Self;
-}
-
-impl<'tcx, T> Value<'tcx> for T {
-    default fn from_cycle_error(tcx: TyCtxt<'tcx>) -> T {
-        tcx.sess.abort_if_errors();
-        bug!("Value::from_cycle_error called without errors");
-    }
-}
-
-impl<'tcx> Value<'tcx> for Ty<'tcx> {
-    fn from_cycle_error(tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
-        tcx.types.err
-    }
-}
-
-impl<'tcx> Value<'tcx> for ty::SymbolName {
-    fn from_cycle_error(_: TyCtxt<'tcx>) -> Self {
-        ty::SymbolName { name: Symbol::intern("<error>") }
-    }
-}
-
-impl<'tcx> Value<'tcx> for AdtSizedConstraint<'tcx> {
-    fn from_cycle_error(tcx: TyCtxt<'tcx>) -> Self {
-        AdtSizedConstraint(tcx.intern_type_list(&[tcx.types.err]))
-    }
-}
diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs
deleted file mode 100644
index 3b9df72266f..00000000000
--- a/src/librustc/ty/relate.rs
+++ /dev/null
@@ -1,990 +0,0 @@
-//! Generalized type relating mechanism.
-//!
-//! A type relation `R` relates a pair of values `(A, B)`. `A and B` are usually
-//! types or regions but can be other things. Examples of type relations are
-//! subtyping, type equality, etc.
-
-use crate::mir::interpret::{get_slice_bytes, ConstValue};
-use crate::traits;
-use crate::ty::error::{ExpectedFound, TypeError};
-use crate::ty::subst::{GenericArg, GenericArgKind, SubstsRef};
-use crate::ty::{self, Ty, TyCtxt, TypeFoldable};
-use rustc_hir as ast;
-use rustc_hir::def_id::DefId;
-use rustc_target::spec::abi;
-use std::iter;
-use std::rc::Rc;
-
-pub type RelateResult<'tcx, T> = Result<T, TypeError<'tcx>>;
-
-#[derive(Clone, Debug)]
-pub enum Cause {
-    ExistentialRegionBound, // relating an existential region bound
-}
-
-pub trait TypeRelation<'tcx>: Sized {
-    fn tcx(&self) -> TyCtxt<'tcx>;
-
-    fn param_env(&self) -> ty::ParamEnv<'tcx>;
-
-    /// Returns a static string we can use for printouts.
-    fn tag(&self) -> &'static str;
-
-    /// Returns `true` if the value `a` is the "expected" type in the
-    /// relation. Just affects error messages.
-    fn a_is_expected(&self) -> bool;
-
-    fn with_cause<F, R>(&mut self, _cause: Cause, f: F) -> R
-    where
-        F: FnOnce(&mut Self) -> R,
-    {
-        f(self)
-    }
-
-    /// Generic relation routine suitable for most anything.
-    fn relate<T: Relate<'tcx>>(&mut self, a: &T, b: &T) -> RelateResult<'tcx, T> {
-        Relate::relate(self, a, b)
-    }
-
-    /// Relate the two substitutions for the given item. The default
-    /// is to look up the variance for the item and proceed
-    /// accordingly.
-    fn relate_item_substs(
-        &mut self,
-        item_def_id: DefId,
-        a_subst: SubstsRef<'tcx>,
-        b_subst: SubstsRef<'tcx>,
-    ) -> RelateResult<'tcx, SubstsRef<'tcx>> {
-        debug!(
-            "relate_item_substs(item_def_id={:?}, a_subst={:?}, b_subst={:?})",
-            item_def_id, a_subst, b_subst
-        );
-
-        let opt_variances = self.tcx().variances_of(item_def_id);
-        relate_substs(self, Some(opt_variances), a_subst, b_subst)
-    }
-
-    /// Switch variance for the purpose of relating `a` and `b`.
-    fn relate_with_variance<T: Relate<'tcx>>(
-        &mut self,
-        variance: ty::Variance,
-        a: &T,
-        b: &T,
-    ) -> RelateResult<'tcx, T>;
-
-    // Overrideable relations. You shouldn't typically call these
-    // directly, instead call `relate()`, which in turn calls
-    // these. This is both more uniform but also allows us to add
-    // additional hooks for other types in the future if needed
-    // without making older code, which called `relate`, obsolete.
-
-    fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>>;
-
-    fn regions(
-        &mut self,
-        a: ty::Region<'tcx>,
-        b: ty::Region<'tcx>,
-    ) -> RelateResult<'tcx, ty::Region<'tcx>>;
-
-    fn consts(
-        &mut self,
-        a: &'tcx ty::Const<'tcx>,
-        b: &'tcx ty::Const<'tcx>,
-    ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>>;
-
-    fn binders<T>(
-        &mut self,
-        a: &ty::Binder<T>,
-        b: &ty::Binder<T>,
-    ) -> RelateResult<'tcx, ty::Binder<T>>
-    where
-        T: Relate<'tcx>;
-}
-
-pub trait Relate<'tcx>: TypeFoldable<'tcx> {
-    fn relate<R: TypeRelation<'tcx>>(
-        relation: &mut R,
-        a: &Self,
-        b: &Self,
-    ) -> RelateResult<'tcx, Self>;
-}
-
-///////////////////////////////////////////////////////////////////////////
-// Relate impls
-
-impl<'tcx> Relate<'tcx> for ty::TypeAndMut<'tcx> {
-    fn relate<R: TypeRelation<'tcx>>(
-        relation: &mut R,
-        a: &ty::TypeAndMut<'tcx>,
-        b: &ty::TypeAndMut<'tcx>,
-    ) -> RelateResult<'tcx, ty::TypeAndMut<'tcx>> {
-        debug!("{}.mts({:?}, {:?})", relation.tag(), a, b);
-        if a.mutbl != b.mutbl {
-            Err(TypeError::Mutability)
-        } else {
-            let mutbl = a.mutbl;
-            let variance = match mutbl {
-                ast::Mutability::Not => ty::Covariant,
-                ast::Mutability::Mut => ty::Invariant,
-            };
-            let ty = relation.relate_with_variance(variance, &a.ty, &b.ty)?;
-            Ok(ty::TypeAndMut { ty, mutbl })
-        }
-    }
-}
-
-pub fn relate_substs<R: TypeRelation<'tcx>>(
-    relation: &mut R,
-    variances: Option<&[ty::Variance]>,
-    a_subst: SubstsRef<'tcx>,
-    b_subst: SubstsRef<'tcx>,
-) -> RelateResult<'tcx, SubstsRef<'tcx>> {
-    let tcx = relation.tcx();
-
-    let params = a_subst.iter().zip(b_subst).enumerate().map(|(i, (a, b))| {
-        let variance = variances.map_or(ty::Invariant, |v| v[i]);
-        relation.relate_with_variance(variance, a, b)
-    });
-
-    Ok(tcx.mk_substs(params)?)
-}
-
-impl<'tcx> Relate<'tcx> for ty::FnSig<'tcx> {
-    fn relate<R: TypeRelation<'tcx>>(
-        relation: &mut R,
-        a: &ty::FnSig<'tcx>,
-        b: &ty::FnSig<'tcx>,
-    ) -> RelateResult<'tcx, ty::FnSig<'tcx>> {
-        let tcx = relation.tcx();
-
-        if a.c_variadic != b.c_variadic {
-            return Err(TypeError::VariadicMismatch(expected_found(
-                relation,
-                &a.c_variadic,
-                &b.c_variadic,
-            )));
-        }
-        let unsafety = relation.relate(&a.unsafety, &b.unsafety)?;
-        let abi = relation.relate(&a.abi, &b.abi)?;
-
-        if a.inputs().len() != b.inputs().len() {
-            return Err(TypeError::ArgCount);
-        }
-
-        let inputs_and_output = a
-            .inputs()
-            .iter()
-            .cloned()
-            .zip(b.inputs().iter().cloned())
-            .map(|x| (x, false))
-            .chain(iter::once(((a.output(), b.output()), true)))
-            .map(|((a, b), is_output)| {
-                if is_output {
-                    relation.relate(&a, &b)
-                } else {
-                    relation.relate_with_variance(ty::Contravariant, &a, &b)
-                }
-            });
-        Ok(ty::FnSig {
-            inputs_and_output: tcx.mk_type_list(inputs_and_output)?,
-            c_variadic: a.c_variadic,
-            unsafety,
-            abi,
-        })
-    }
-}
-
-impl<'tcx> Relate<'tcx> for ast::Unsafety {
-    fn relate<R: TypeRelation<'tcx>>(
-        relation: &mut R,
-        a: &ast::Unsafety,
-        b: &ast::Unsafety,
-    ) -> RelateResult<'tcx, ast::Unsafety> {
-        if a != b {
-            Err(TypeError::UnsafetyMismatch(expected_found(relation, a, b)))
-        } else {
-            Ok(*a)
-        }
-    }
-}
-
-impl<'tcx> Relate<'tcx> for abi::Abi {
-    fn relate<R: TypeRelation<'tcx>>(
-        relation: &mut R,
-        a: &abi::Abi,
-        b: &abi::Abi,
-    ) -> RelateResult<'tcx, abi::Abi> {
-        if a == b { Ok(*a) } else { Err(TypeError::AbiMismatch(expected_found(relation, a, b))) }
-    }
-}
-
-impl<'tcx> Relate<'tcx> for ty::ProjectionTy<'tcx> {
-    fn relate<R: TypeRelation<'tcx>>(
-        relation: &mut R,
-        a: &ty::ProjectionTy<'tcx>,
-        b: &ty::ProjectionTy<'tcx>,
-    ) -> RelateResult<'tcx, ty::ProjectionTy<'tcx>> {
-        if a.item_def_id != b.item_def_id {
-            Err(TypeError::ProjectionMismatched(expected_found(
-                relation,
-                &a.item_def_id,
-                &b.item_def_id,
-            )))
-        } else {
-            let substs = relation.relate(&a.substs, &b.substs)?;
-            Ok(ty::ProjectionTy { item_def_id: a.item_def_id, substs: &substs })
-        }
-    }
-}
-
-impl<'tcx> Relate<'tcx> for ty::ExistentialProjection<'tcx> {
-    fn relate<R: TypeRelation<'tcx>>(
-        relation: &mut R,
-        a: &ty::ExistentialProjection<'tcx>,
-        b: &ty::ExistentialProjection<'tcx>,
-    ) -> RelateResult<'tcx, ty::ExistentialProjection<'tcx>> {
-        if a.item_def_id != b.item_def_id {
-            Err(TypeError::ProjectionMismatched(expected_found(
-                relation,
-                &a.item_def_id,
-                &b.item_def_id,
-            )))
-        } else {
-            let ty = relation.relate(&a.ty, &b.ty)?;
-            let substs = relation.relate(&a.substs, &b.substs)?;
-            Ok(ty::ExistentialProjection { item_def_id: a.item_def_id, substs, ty })
-        }
-    }
-}
-
-impl<'tcx> Relate<'tcx> for Vec<ty::PolyExistentialProjection<'tcx>> {
-    fn relate<R: TypeRelation<'tcx>>(
-        relation: &mut R,
-        a: &Vec<ty::PolyExistentialProjection<'tcx>>,
-        b: &Vec<ty::PolyExistentialProjection<'tcx>>,
-    ) -> RelateResult<'tcx, Vec<ty::PolyExistentialProjection<'tcx>>> {
-        // To be compatible, `a` and `b` must be for precisely the
-        // same set of traits and item names. We always require that
-        // projection bounds lists are sorted by trait-def-id and item-name,
-        // so we can just iterate through the lists pairwise, so long as they are the
-        // same length.
-        if a.len() != b.len() {
-            Err(TypeError::ProjectionBoundsLength(expected_found(relation, &a.len(), &b.len())))
-        } else {
-            a.iter().zip(b).map(|(a, b)| relation.relate(a, b)).collect()
-        }
-    }
-}
-
-impl<'tcx> Relate<'tcx> for ty::TraitRef<'tcx> {
-    fn relate<R: TypeRelation<'tcx>>(
-        relation: &mut R,
-        a: &ty::TraitRef<'tcx>,
-        b: &ty::TraitRef<'tcx>,
-    ) -> RelateResult<'tcx, ty::TraitRef<'tcx>> {
-        // Different traits cannot be related.
-        if a.def_id != b.def_id {
-            Err(TypeError::Traits(expected_found(relation, &a.def_id, &b.def_id)))
-        } else {
-            let substs = relate_substs(relation, None, a.substs, b.substs)?;
-            Ok(ty::TraitRef { def_id: a.def_id, substs: substs })
-        }
-    }
-}
-
-impl<'tcx> Relate<'tcx> for ty::ExistentialTraitRef<'tcx> {
-    fn relate<R: TypeRelation<'tcx>>(
-        relation: &mut R,
-        a: &ty::ExistentialTraitRef<'tcx>,
-        b: &ty::ExistentialTraitRef<'tcx>,
-    ) -> RelateResult<'tcx, ty::ExistentialTraitRef<'tcx>> {
-        // Different traits cannot be related.
-        if a.def_id != b.def_id {
-            Err(TypeError::Traits(expected_found(relation, &a.def_id, &b.def_id)))
-        } else {
-            let substs = relate_substs(relation, None, a.substs, b.substs)?;
-            Ok(ty::ExistentialTraitRef { def_id: a.def_id, substs: substs })
-        }
-    }
-}
-
-#[derive(Debug, Clone, TypeFoldable)]
-struct GeneratorWitness<'tcx>(&'tcx ty::List<Ty<'tcx>>);
-
-impl<'tcx> Relate<'tcx> for GeneratorWitness<'tcx> {
-    fn relate<R: TypeRelation<'tcx>>(
-        relation: &mut R,
-        a: &GeneratorWitness<'tcx>,
-        b: &GeneratorWitness<'tcx>,
-    ) -> RelateResult<'tcx, GeneratorWitness<'tcx>> {
-        assert_eq!(a.0.len(), b.0.len());
-        let tcx = relation.tcx();
-        let types = tcx.mk_type_list(a.0.iter().zip(b.0).map(|(a, b)| relation.relate(a, b)))?;
-        Ok(GeneratorWitness(types))
-    }
-}
-
-impl<'tcx> Relate<'tcx> for Ty<'tcx> {
-    fn relate<R: TypeRelation<'tcx>>(
-        relation: &mut R,
-        a: &Ty<'tcx>,
-        b: &Ty<'tcx>,
-    ) -> RelateResult<'tcx, Ty<'tcx>> {
-        relation.tys(a, b)
-    }
-}
-
-/// The main "type relation" routine. Note that this does not handle
-/// inference artifacts, so you should filter those out before calling
-/// it.
-pub fn super_relate_tys<R: TypeRelation<'tcx>>(
-    relation: &mut R,
-    a: Ty<'tcx>,
-    b: Ty<'tcx>,
-) -> RelateResult<'tcx, Ty<'tcx>> {
-    let tcx = relation.tcx();
-    debug!("super_relate_tys: a={:?} b={:?}", a, b);
-    match (&a.kind, &b.kind) {
-        (&ty::Infer(_), _) | (_, &ty::Infer(_)) => {
-            // The caller should handle these cases!
-            bug!("var types encountered in super_relate_tys")
-        }
-
-        (ty::Bound(..), _) | (_, ty::Bound(..)) => {
-            bug!("bound types encountered in super_relate_tys")
-        }
-
-        (&ty::Error, _) | (_, &ty::Error) => Ok(tcx.types.err),
-
-        (&ty::Never, _)
-        | (&ty::Char, _)
-        | (&ty::Bool, _)
-        | (&ty::Int(_), _)
-        | (&ty::Uint(_), _)
-        | (&ty::Float(_), _)
-        | (&ty::Str, _)
-            if a == b =>
-        {
-            Ok(a)
-        }
-
-        (&ty::Param(ref a_p), &ty::Param(ref b_p)) if a_p.index == b_p.index => Ok(a),
-
-        (ty::Placeholder(p1), ty::Placeholder(p2)) if p1 == p2 => Ok(a),
-
-        (&ty::Adt(a_def, a_substs), &ty::Adt(b_def, b_substs)) if a_def == b_def => {
-            let substs = relation.relate_item_substs(a_def.did, a_substs, b_substs)?;
-            Ok(tcx.mk_adt(a_def, substs))
-        }
-
-        (&ty::Foreign(a_id), &ty::Foreign(b_id)) if a_id == b_id => Ok(tcx.mk_foreign(a_id)),
-
-        (&ty::Dynamic(ref a_obj, ref a_region), &ty::Dynamic(ref b_obj, ref b_region)) => {
-            let region_bound = relation.with_cause(Cause::ExistentialRegionBound, |relation| {
-                relation.relate_with_variance(ty::Contravariant, a_region, b_region)
-            })?;
-            Ok(tcx.mk_dynamic(relation.relate(a_obj, b_obj)?, region_bound))
-        }
-
-        (&ty::Generator(a_id, a_substs, movability), &ty::Generator(b_id, b_substs, _))
-            if a_id == b_id =>
-        {
-            // All Generator types with the same id represent
-            // the (anonymous) type of the same generator expression. So
-            // all of their regions should be equated.
-            let substs = relation.relate(&a_substs, &b_substs)?;
-            Ok(tcx.mk_generator(a_id, substs, movability))
-        }
-
-        (&ty::GeneratorWitness(a_types), &ty::GeneratorWitness(b_types)) => {
-            // Wrap our types with a temporary GeneratorWitness struct
-            // inside the binder so we can related them
-            let a_types = a_types.map_bound(GeneratorWitness);
-            let b_types = b_types.map_bound(GeneratorWitness);
-            // Then remove the GeneratorWitness for the result
-            let types = relation.relate(&a_types, &b_types)?.map_bound(|witness| witness.0);
-            Ok(tcx.mk_generator_witness(types))
-        }
-
-        (&ty::Closure(a_id, a_substs), &ty::Closure(b_id, b_substs)) if a_id == b_id => {
-            // All Closure types with the same id represent
-            // the (anonymous) type of the same closure expression. So
-            // all of their regions should be equated.
-            let substs = relation.relate(&a_substs, &b_substs)?;
-            Ok(tcx.mk_closure(a_id, &substs))
-        }
-
-        (&ty::RawPtr(ref a_mt), &ty::RawPtr(ref b_mt)) => {
-            let mt = relation.relate(a_mt, b_mt)?;
-            Ok(tcx.mk_ptr(mt))
-        }
-
-        (&ty::Ref(a_r, a_ty, a_mutbl), &ty::Ref(b_r, b_ty, b_mutbl)) => {
-            let r = relation.relate_with_variance(ty::Contravariant, &a_r, &b_r)?;
-            let a_mt = ty::TypeAndMut { ty: a_ty, mutbl: a_mutbl };
-            let b_mt = ty::TypeAndMut { ty: b_ty, mutbl: b_mutbl };
-            let mt = relation.relate(&a_mt, &b_mt)?;
-            Ok(tcx.mk_ref(r, mt))
-        }
-
-        (&ty::Array(a_t, sz_a), &ty::Array(b_t, sz_b)) => {
-            let t = relation.relate(&a_t, &b_t)?;
-            match relation.relate(&sz_a, &sz_b) {
-                Ok(sz) => Ok(tcx.mk_ty(ty::Array(t, sz))),
-                Err(err) => {
-                    // Check whether the lengths are both concrete/known values,
-                    // but are unequal, for better diagnostics.
-                    let sz_a = sz_a.try_eval_usize(tcx, relation.param_env());
-                    let sz_b = sz_b.try_eval_usize(tcx, relation.param_env());
-                    match (sz_a, sz_b) {
-                        (Some(sz_a_val), Some(sz_b_val)) => Err(TypeError::FixedArraySize(
-                            expected_found(relation, &sz_a_val, &sz_b_val),
-                        )),
-                        _ => return Err(err),
-                    }
-                }
-            }
-        }
-
-        (&ty::Slice(a_t), &ty::Slice(b_t)) => {
-            let t = relation.relate(&a_t, &b_t)?;
-            Ok(tcx.mk_slice(t))
-        }
-
-        (&ty::Tuple(as_), &ty::Tuple(bs)) => {
-            if as_.len() == bs.len() {
-                Ok(tcx.mk_tup(
-                    as_.iter()
-                        .zip(bs)
-                        .map(|(a, b)| relation.relate(&a.expect_ty(), &b.expect_ty())),
-                )?)
-            } else if !(as_.is_empty() || bs.is_empty()) {
-                Err(TypeError::TupleSize(expected_found(relation, &as_.len(), &bs.len())))
-            } else {
-                Err(TypeError::Sorts(expected_found(relation, &a, &b)))
-            }
-        }
-
-        (&ty::FnDef(a_def_id, a_substs), &ty::FnDef(b_def_id, b_substs))
-            if a_def_id == b_def_id =>
-        {
-            let substs = relation.relate_item_substs(a_def_id, a_substs, b_substs)?;
-            Ok(tcx.mk_fn_def(a_def_id, substs))
-        }
-
-        (&ty::FnPtr(a_fty), &ty::FnPtr(b_fty)) => {
-            let fty = relation.relate(&a_fty, &b_fty)?;
-            Ok(tcx.mk_fn_ptr(fty))
-        }
-
-        (ty::UnnormalizedProjection(a_data), ty::UnnormalizedProjection(b_data)) => {
-            let projection_ty = relation.relate(a_data, b_data)?;
-            Ok(tcx.mk_ty(ty::UnnormalizedProjection(projection_ty)))
-        }
-
-        // these two are already handled downstream in case of lazy normalization
-        (ty::Projection(a_data), ty::Projection(b_data)) => {
-            let projection_ty = relation.relate(a_data, b_data)?;
-            Ok(tcx.mk_projection(projection_ty.item_def_id, projection_ty.substs))
-        }
-
-        (&ty::Opaque(a_def_id, a_substs), &ty::Opaque(b_def_id, b_substs))
-            if a_def_id == b_def_id =>
-        {
-            let substs = relate_substs(relation, None, a_substs, b_substs)?;
-            Ok(tcx.mk_opaque(a_def_id, substs))
-        }
-
-        _ => Err(TypeError::Sorts(expected_found(relation, &a, &b))),
-    }
-}
-
-/// The main "const relation" routine. Note that this does not handle
-/// inference artifacts, so you should filter those out before calling
-/// it.
-pub fn super_relate_consts<R: TypeRelation<'tcx>>(
-    relation: &mut R,
-    a: &'tcx ty::Const<'tcx>,
-    b: &'tcx ty::Const<'tcx>,
-) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
-    let tcx = relation.tcx();
-
-    let eagerly_eval = |x: &'tcx ty::Const<'tcx>| {
-        if !x.val.has_local_value() {
-            return x.eval(tcx, relation.param_env()).val;
-        }
-        x.val
-    };
-
-    // 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)) {
-        (ty::ConstKind::Infer(_), _) | (_, ty::ConstKind::Infer(_)) => {
-            // The caller should handle these cases!
-            bug!("var types encountered in super_relate_consts: {:?} {:?}", a, b)
-        }
-        (ty::ConstKind::Param(a_p), ty::ConstKind::Param(b_p)) if a_p.index == b_p.index => {
-            return Ok(a);
-        }
-        (ty::ConstKind::Placeholder(p1), ty::ConstKind::Placeholder(p2)) if p1 == p2 => {
-            return Ok(a);
-        }
-        (ty::ConstKind::Value(a_val), ty::ConstKind::Value(b_val)) => {
-            let new_val = match (a_val, b_val) {
-                (ConstValue::Scalar(a_val), ConstValue::Scalar(b_val)) if a.ty == b.ty => {
-                    if a_val == b_val {
-                        Ok(ConstValue::Scalar(a_val))
-                    } else if let ty::FnPtr(_) = a.ty.kind {
-                        let alloc_map = tcx.alloc_map.lock();
-                        let a_instance = alloc_map.unwrap_fn(a_val.assert_ptr().alloc_id);
-                        let b_instance = alloc_map.unwrap_fn(b_val.assert_ptr().alloc_id);
-                        if a_instance == b_instance {
-                            Ok(ConstValue::Scalar(a_val))
-                        } else {
-                            Err(TypeError::ConstMismatch(expected_found(relation, &a, &b)))
-                        }
-                    } else {
-                        Err(TypeError::ConstMismatch(expected_found(relation, &a, &b)))
-                    }
-                }
-
-                (a_val @ ConstValue::Slice { .. }, b_val @ ConstValue::Slice { .. }) => {
-                    let a_bytes = get_slice_bytes(&tcx, a_val);
-                    let b_bytes = get_slice_bytes(&tcx, b_val);
-                    if a_bytes == b_bytes {
-                        Ok(a_val)
-                    } else {
-                        Err(TypeError::ConstMismatch(expected_found(relation, &a, &b)))
-                    }
-                }
-
-                // FIXME(const_generics): handle `ConstValue::ByRef`.
-                _ => Err(TypeError::ConstMismatch(expected_found(relation, &a, &b))),
-            };
-
-            new_val.map(ty::ConstKind::Value)
-        }
-
-        // FIXME(const_generics): this is wrong, as it is a projection
-        (
-            ty::ConstKind::Unevaluated(a_def_id, a_substs, a_promoted),
-            ty::ConstKind::Unevaluated(b_def_id, b_substs, b_promoted),
-        ) if a_def_id == b_def_id && a_promoted == b_promoted => {
-            let substs =
-                relation.relate_with_variance(ty::Variance::Invariant, &a_substs, &b_substs)?;
-            Ok(ty::ConstKind::Unevaluated(a_def_id, &substs, a_promoted))
-        }
-        _ => Err(TypeError::ConstMismatch(expected_found(relation, &a, &b))),
-    };
-    new_const_val.map(|val| tcx.mk_const(ty::Const { val, ty: a.ty }))
-}
-
-impl<'tcx> Relate<'tcx> for &'tcx ty::List<ty::ExistentialPredicate<'tcx>> {
-    fn relate<R: TypeRelation<'tcx>>(
-        relation: &mut R,
-        a: &Self,
-        b: &Self,
-    ) -> RelateResult<'tcx, Self> {
-        if a.len() != b.len() {
-            return Err(TypeError::ExistentialMismatch(expected_found(relation, a, b)));
-        }
-
-        let tcx = relation.tcx();
-        let v = a.iter().zip(b.iter()).map(|(ep_a, ep_b)| {
-            use crate::ty::ExistentialPredicate::*;
-            match (*ep_a, *ep_b) {
-                (Trait(ref a), Trait(ref b)) => Ok(Trait(relation.relate(a, b)?)),
-                (Projection(ref a), Projection(ref b)) => Ok(Projection(relation.relate(a, b)?)),
-                (AutoTrait(ref a), AutoTrait(ref b)) if a == b => Ok(AutoTrait(*a)),
-                _ => Err(TypeError::ExistentialMismatch(expected_found(relation, a, b))),
-            }
-        });
-        Ok(tcx.mk_existential_predicates(v)?)
-    }
-}
-
-impl<'tcx> Relate<'tcx> for ty::ClosureSubsts<'tcx> {
-    fn relate<R: TypeRelation<'tcx>>(
-        relation: &mut R,
-        a: &ty::ClosureSubsts<'tcx>,
-        b: &ty::ClosureSubsts<'tcx>,
-    ) -> RelateResult<'tcx, ty::ClosureSubsts<'tcx>> {
-        let substs = relate_substs(relation, None, a.substs, b.substs)?;
-        Ok(ty::ClosureSubsts { substs })
-    }
-}
-
-impl<'tcx> Relate<'tcx> for ty::GeneratorSubsts<'tcx> {
-    fn relate<R: TypeRelation<'tcx>>(
-        relation: &mut R,
-        a: &ty::GeneratorSubsts<'tcx>,
-        b: &ty::GeneratorSubsts<'tcx>,
-    ) -> RelateResult<'tcx, ty::GeneratorSubsts<'tcx>> {
-        let substs = relate_substs(relation, None, a.substs, b.substs)?;
-        Ok(ty::GeneratorSubsts { substs })
-    }
-}
-
-impl<'tcx> Relate<'tcx> for SubstsRef<'tcx> {
-    fn relate<R: TypeRelation<'tcx>>(
-        relation: &mut R,
-        a: &SubstsRef<'tcx>,
-        b: &SubstsRef<'tcx>,
-    ) -> RelateResult<'tcx, SubstsRef<'tcx>> {
-        relate_substs(relation, None, a, b)
-    }
-}
-
-impl<'tcx> Relate<'tcx> for ty::Region<'tcx> {
-    fn relate<R: TypeRelation<'tcx>>(
-        relation: &mut R,
-        a: &ty::Region<'tcx>,
-        b: &ty::Region<'tcx>,
-    ) -> RelateResult<'tcx, ty::Region<'tcx>> {
-        relation.regions(*a, *b)
-    }
-}
-
-impl<'tcx> Relate<'tcx> for &'tcx ty::Const<'tcx> {
-    fn relate<R: TypeRelation<'tcx>>(
-        relation: &mut R,
-        a: &&'tcx ty::Const<'tcx>,
-        b: &&'tcx ty::Const<'tcx>,
-    ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
-        relation.consts(*a, *b)
-    }
-}
-
-impl<'tcx, T: Relate<'tcx>> Relate<'tcx> for ty::Binder<T> {
-    fn relate<R: TypeRelation<'tcx>>(
-        relation: &mut R,
-        a: &ty::Binder<T>,
-        b: &ty::Binder<T>,
-    ) -> RelateResult<'tcx, ty::Binder<T>> {
-        relation.binders(a, b)
-    }
-}
-
-impl<'tcx, T: Relate<'tcx>> Relate<'tcx> for Rc<T> {
-    fn relate<R: TypeRelation<'tcx>>(
-        relation: &mut R,
-        a: &Rc<T>,
-        b: &Rc<T>,
-    ) -> RelateResult<'tcx, Rc<T>> {
-        let a: &T = a;
-        let b: &T = b;
-        Ok(Rc::new(relation.relate(a, b)?))
-    }
-}
-
-impl<'tcx, T: Relate<'tcx>> Relate<'tcx> for Box<T> {
-    fn relate<R: TypeRelation<'tcx>>(
-        relation: &mut R,
-        a: &Box<T>,
-        b: &Box<T>,
-    ) -> RelateResult<'tcx, Box<T>> {
-        let a: &T = a;
-        let b: &T = b;
-        Ok(Box::new(relation.relate(a, b)?))
-    }
-}
-
-impl<'tcx> Relate<'tcx> for GenericArg<'tcx> {
-    fn relate<R: TypeRelation<'tcx>>(
-        relation: &mut R,
-        a: &GenericArg<'tcx>,
-        b: &GenericArg<'tcx>,
-    ) -> RelateResult<'tcx, GenericArg<'tcx>> {
-        match (a.unpack(), b.unpack()) {
-            (GenericArgKind::Lifetime(a_lt), GenericArgKind::Lifetime(b_lt)) => {
-                Ok(relation.relate(&a_lt, &b_lt)?.into())
-            }
-            (GenericArgKind::Type(a_ty), GenericArgKind::Type(b_ty)) => {
-                Ok(relation.relate(&a_ty, &b_ty)?.into())
-            }
-            (GenericArgKind::Const(a_ct), GenericArgKind::Const(b_ct)) => {
-                Ok(relation.relate(&a_ct, &b_ct)?.into())
-            }
-            (GenericArgKind::Lifetime(unpacked), x) => {
-                bug!("impossible case reached: can't relate: {:?} with {:?}", unpacked, x)
-            }
-            (GenericArgKind::Type(unpacked), x) => {
-                bug!("impossible case reached: can't relate: {:?} with {:?}", unpacked, x)
-            }
-            (GenericArgKind::Const(unpacked), x) => {
-                bug!("impossible case reached: can't relate: {:?} with {:?}", unpacked, x)
-            }
-        }
-    }
-}
-
-impl<'tcx> Relate<'tcx> for ty::TraitPredicate<'tcx> {
-    fn relate<R: TypeRelation<'tcx>>(
-        relation: &mut R,
-        a: &ty::TraitPredicate<'tcx>,
-        b: &ty::TraitPredicate<'tcx>,
-    ) -> RelateResult<'tcx, ty::TraitPredicate<'tcx>> {
-        Ok(ty::TraitPredicate { trait_ref: relation.relate(&a.trait_ref, &b.trait_ref)? })
-    }
-}
-
-impl<'tcx> Relate<'tcx> for ty::ProjectionPredicate<'tcx> {
-    fn relate<R: TypeRelation<'tcx>>(
-        relation: &mut R,
-        a: &ty::ProjectionPredicate<'tcx>,
-        b: &ty::ProjectionPredicate<'tcx>,
-    ) -> RelateResult<'tcx, ty::ProjectionPredicate<'tcx>> {
-        Ok(ty::ProjectionPredicate {
-            projection_ty: relation.relate(&a.projection_ty, &b.projection_ty)?,
-            ty: relation.relate(&a.ty, &b.ty)?,
-        })
-    }
-}
-
-impl<'tcx> Relate<'tcx> for traits::WhereClause<'tcx> {
-    fn relate<R: TypeRelation<'tcx>>(
-        relation: &mut R,
-        a: &traits::WhereClause<'tcx>,
-        b: &traits::WhereClause<'tcx>,
-    ) -> RelateResult<'tcx, traits::WhereClause<'tcx>> {
-        use crate::traits::WhereClause::*;
-        match (a, b) {
-            (Implemented(a_pred), Implemented(b_pred)) => {
-                Ok(Implemented(relation.relate(a_pred, b_pred)?))
-            }
-
-            (ProjectionEq(a_pred), ProjectionEq(b_pred)) => {
-                Ok(ProjectionEq(relation.relate(a_pred, b_pred)?))
-            }
-
-            (RegionOutlives(a_pred), RegionOutlives(b_pred)) => {
-                Ok(RegionOutlives(ty::OutlivesPredicate(
-                    relation.relate(&a_pred.0, &b_pred.0)?,
-                    relation.relate(&a_pred.1, &b_pred.1)?,
-                )))
-            }
-
-            (TypeOutlives(a_pred), TypeOutlives(b_pred)) => {
-                Ok(TypeOutlives(ty::OutlivesPredicate(
-                    relation.relate(&a_pred.0, &b_pred.0)?,
-                    relation.relate(&a_pred.1, &b_pred.1)?,
-                )))
-            }
-
-            _ => Err(TypeError::Mismatch),
-        }
-    }
-}
-
-impl<'tcx> Relate<'tcx> for traits::WellFormed<'tcx> {
-    fn relate<R: TypeRelation<'tcx>>(
-        relation: &mut R,
-        a: &traits::WellFormed<'tcx>,
-        b: &traits::WellFormed<'tcx>,
-    ) -> RelateResult<'tcx, traits::WellFormed<'tcx>> {
-        use crate::traits::WellFormed::*;
-        match (a, b) {
-            (Trait(a_pred), Trait(b_pred)) => Ok(Trait(relation.relate(a_pred, b_pred)?)),
-            (Ty(a_ty), Ty(b_ty)) => Ok(Ty(relation.relate(a_ty, b_ty)?)),
-            _ => Err(TypeError::Mismatch),
-        }
-    }
-}
-
-impl<'tcx> Relate<'tcx> for traits::FromEnv<'tcx> {
-    fn relate<R: TypeRelation<'tcx>>(
-        relation: &mut R,
-        a: &traits::FromEnv<'tcx>,
-        b: &traits::FromEnv<'tcx>,
-    ) -> RelateResult<'tcx, traits::FromEnv<'tcx>> {
-        use crate::traits::FromEnv::*;
-        match (a, b) {
-            (Trait(a_pred), Trait(b_pred)) => Ok(Trait(relation.relate(a_pred, b_pred)?)),
-            (Ty(a_ty), Ty(b_ty)) => Ok(Ty(relation.relate(a_ty, b_ty)?)),
-            _ => Err(TypeError::Mismatch),
-        }
-    }
-}
-
-impl<'tcx> Relate<'tcx> for traits::DomainGoal<'tcx> {
-    fn relate<R: TypeRelation<'tcx>>(
-        relation: &mut R,
-        a: &traits::DomainGoal<'tcx>,
-        b: &traits::DomainGoal<'tcx>,
-    ) -> RelateResult<'tcx, traits::DomainGoal<'tcx>> {
-        use crate::traits::DomainGoal::*;
-        match (a, b) {
-            (Holds(a_wc), Holds(b_wc)) => Ok(Holds(relation.relate(a_wc, b_wc)?)),
-            (WellFormed(a_wf), WellFormed(b_wf)) => Ok(WellFormed(relation.relate(a_wf, b_wf)?)),
-            (FromEnv(a_fe), FromEnv(b_fe)) => Ok(FromEnv(relation.relate(a_fe, b_fe)?)),
-
-            (Normalize(a_pred), Normalize(b_pred)) => {
-                Ok(Normalize(relation.relate(a_pred, b_pred)?))
-            }
-
-            _ => Err(TypeError::Mismatch),
-        }
-    }
-}
-
-impl<'tcx> Relate<'tcx> for traits::Goal<'tcx> {
-    fn relate<R: TypeRelation<'tcx>>(
-        relation: &mut R,
-        a: &traits::Goal<'tcx>,
-        b: &traits::Goal<'tcx>,
-    ) -> RelateResult<'tcx, traits::Goal<'tcx>> {
-        use crate::traits::GoalKind::*;
-        match (a, b) {
-            (Implies(a_clauses, a_goal), Implies(b_clauses, b_goal)) => {
-                let clauses = relation.relate(a_clauses, b_clauses)?;
-                let goal = relation.relate(a_goal, b_goal)?;
-                Ok(relation.tcx().mk_goal(Implies(clauses, goal)))
-            }
-
-            (And(a_left, a_right), And(b_left, b_right)) => {
-                let left = relation.relate(a_left, b_left)?;
-                let right = relation.relate(a_right, b_right)?;
-                Ok(relation.tcx().mk_goal(And(left, right)))
-            }
-
-            (Not(a_goal), Not(b_goal)) => {
-                let goal = relation.relate(a_goal, b_goal)?;
-                Ok(relation.tcx().mk_goal(Not(goal)))
-            }
-
-            (DomainGoal(a_goal), DomainGoal(b_goal)) => {
-                let goal = relation.relate(a_goal, b_goal)?;
-                Ok(relation.tcx().mk_goal(DomainGoal(goal)))
-            }
-
-            (Quantified(a_qkind, a_goal), Quantified(b_qkind, b_goal)) if a_qkind == b_qkind => {
-                let goal = relation.relate(a_goal, b_goal)?;
-                Ok(relation.tcx().mk_goal(Quantified(*a_qkind, goal)))
-            }
-
-            (CannotProve, CannotProve) => Ok(*a),
-
-            _ => Err(TypeError::Mismatch),
-        }
-    }
-}
-
-impl<'tcx> Relate<'tcx> for traits::Goals<'tcx> {
-    fn relate<R: TypeRelation<'tcx>>(
-        relation: &mut R,
-        a: &traits::Goals<'tcx>,
-        b: &traits::Goals<'tcx>,
-    ) -> RelateResult<'tcx, traits::Goals<'tcx>> {
-        if a.len() != b.len() {
-            return Err(TypeError::Mismatch);
-        }
-
-        let tcx = relation.tcx();
-        let goals = a.iter().zip(b.iter()).map(|(a, b)| relation.relate(a, b));
-        Ok(tcx.mk_goals(goals)?)
-    }
-}
-
-impl<'tcx> Relate<'tcx> for traits::Clause<'tcx> {
-    fn relate<R: TypeRelation<'tcx>>(
-        relation: &mut R,
-        a: &traits::Clause<'tcx>,
-        b: &traits::Clause<'tcx>,
-    ) -> RelateResult<'tcx, traits::Clause<'tcx>> {
-        use crate::traits::Clause::*;
-        match (a, b) {
-            (Implies(a_clause), Implies(b_clause)) => {
-                let clause = relation.relate(a_clause, b_clause)?;
-                Ok(Implies(clause))
-            }
-
-            (ForAll(a_clause), ForAll(b_clause)) => {
-                let clause = relation.relate(a_clause, b_clause)?;
-                Ok(ForAll(clause))
-            }
-
-            _ => Err(TypeError::Mismatch),
-        }
-    }
-}
-
-impl<'tcx> Relate<'tcx> for traits::Clauses<'tcx> {
-    fn relate<R: TypeRelation<'tcx>>(
-        relation: &mut R,
-        a: &traits::Clauses<'tcx>,
-        b: &traits::Clauses<'tcx>,
-    ) -> RelateResult<'tcx, traits::Clauses<'tcx>> {
-        if a.len() != b.len() {
-            return Err(TypeError::Mismatch);
-        }
-
-        let tcx = relation.tcx();
-        let clauses = a.iter().zip(b.iter()).map(|(a, b)| relation.relate(a, b));
-        Ok(tcx.mk_clauses(clauses)?)
-    }
-}
-
-impl<'tcx> Relate<'tcx> for traits::ProgramClause<'tcx> {
-    fn relate<R: TypeRelation<'tcx>>(
-        relation: &mut R,
-        a: &traits::ProgramClause<'tcx>,
-        b: &traits::ProgramClause<'tcx>,
-    ) -> RelateResult<'tcx, traits::ProgramClause<'tcx>> {
-        Ok(traits::ProgramClause {
-            goal: relation.relate(&a.goal, &b.goal)?,
-            hypotheses: relation.relate(&a.hypotheses, &b.hypotheses)?,
-            category: traits::ProgramClauseCategory::Other,
-        })
-    }
-}
-
-impl<'tcx> Relate<'tcx> for traits::Environment<'tcx> {
-    fn relate<R: TypeRelation<'tcx>>(
-        relation: &mut R,
-        a: &traits::Environment<'tcx>,
-        b: &traits::Environment<'tcx>,
-    ) -> RelateResult<'tcx, traits::Environment<'tcx>> {
-        Ok(traits::Environment { clauses: relation.relate(&a.clauses, &b.clauses)? })
-    }
-}
-
-impl<'tcx, G> Relate<'tcx> for traits::InEnvironment<'tcx, G>
-where
-    G: Relate<'tcx>,
-{
-    fn relate<R: TypeRelation<'tcx>>(
-        relation: &mut R,
-        a: &traits::InEnvironment<'tcx, G>,
-        b: &traits::InEnvironment<'tcx, G>,
-    ) -> RelateResult<'tcx, traits::InEnvironment<'tcx, G>> {
-        Ok(traits::InEnvironment {
-            environment: relation.relate(&a.environment, &b.environment)?,
-            goal: relation.relate(&a.goal, &b.goal)?,
-        })
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////
-// Error handling
-
-pub fn expected_found<R, T>(relation: &mut R, a: &T, b: &T) -> ExpectedFound<T>
-where
-    R: TypeRelation<'tcx>,
-    T: Clone,
-{
-    expected_found_bool(relation.a_is_expected(), a, b)
-}
-
-pub fn expected_found_bool<T>(a_is_expected: bool, a: &T, b: &T) -> ExpectedFound<T>
-where
-    T: Clone,
-{
-    let a = a.clone();
-    let b = b.clone();
-    if a_is_expected {
-        ExpectedFound { expected: a, found: b }
-    } else {
-        ExpectedFound { expected: b, found: a }
-    }
-}
diff --git a/src/librustc/ty/steal.rs b/src/librustc/ty/steal.rs
deleted file mode 100644
index 224e76845d7..00000000000
--- a/src/librustc/ty/steal.rs
+++ /dev/null
@@ -1,44 +0,0 @@
-use rustc_data_structures::sync::{MappedReadGuard, ReadGuard, RwLock};
-
-/// The `Steal` struct is intended to used as the value for a query.
-/// Specifically, we sometimes have queries (*cough* MIR *cough*)
-/// where we create a large, complex value that we want to iteratively
-/// update (e.g., optimize). We could clone the value for each
-/// optimization, but that'd be expensive. And yet we don't just want
-/// to mutate it in place, because that would spoil the idea that
-/// queries are these pure functions that produce an immutable value
-/// (since if you did the query twice, you could observe the mutations).
-/// So instead we have the query produce a `&'tcx Steal<mir::Body<'tcx>>`
-/// (to be very specific). Now we can read from this
-/// as much as we want (using `borrow()`), but you can also
-/// `steal()`. Once you steal, any further attempt to read will panic.
-/// Therefore, we know that -- assuming no ICE -- nobody is observing
-/// the fact that the MIR was updated.
-///
-/// Obviously, whenever you have a query that yields a `Steal` value,
-/// you must treat it with caution, and make sure that you know that
-/// -- once the value is stolen -- it will never be read from again.
-//
-// FIXME(#41710): what is the best way to model linear queries?
-pub struct Steal<T> {
-    value: RwLock<Option<T>>,
-}
-
-impl<T> Steal<T> {
-    pub fn new(value: T) -> Self {
-        Steal { value: RwLock::new(Some(value)) }
-    }
-
-    pub fn borrow(&self) -> MappedReadGuard<'_, T> {
-        ReadGuard::map(self.value.borrow(), |opt| match *opt {
-            None => bug!("attempted to read from stolen value"),
-            Some(ref v) => v,
-        })
-    }
-
-    pub fn steal(&self) -> T {
-        let value_ref = &mut *self.value.try_write().expect("stealing value which is locked");
-        let value = value_ref.take();
-        value.expect("attempt to read from stolen value")
-    }
-}
diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs
deleted file mode 100644
index 03ff1b8a317..00000000000
--- a/src/librustc/ty/structural_impls.rs
+++ /dev/null
@@ -1,1084 +0,0 @@
-//! This module contains implements of the `Lift` and `TypeFoldable`
-//! traits for various types in the Rust compiler. Most are written by
-//! hand, though we've recently added some macros and proc-macros to help with the tedium.
-
-use crate::mir::interpret;
-use crate::mir::ProjectionKind;
-use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
-use crate::ty::print::{FmtPrinter, Printer};
-use crate::ty::{self, InferConst, Lift, Ty, TyCtxt};
-use rustc_hir as hir;
-use rustc_hir::def::Namespace;
-use rustc_hir::def_id::CRATE_DEF_INDEX;
-use rustc_index::vec::{Idx, IndexVec};
-
-use smallvec::SmallVec;
-use std::fmt;
-use std::rc::Rc;
-use std::sync::Arc;
-
-impl fmt::Debug for ty::TraitDef {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        ty::tls::with(|tcx| {
-            FmtPrinter::new(tcx, f, Namespace::TypeNS).print_def_path(self.def_id, &[])?;
-            Ok(())
-        })
-    }
-}
-
-impl fmt::Debug for ty::AdtDef {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        ty::tls::with(|tcx| {
-            FmtPrinter::new(tcx, f, Namespace::TypeNS).print_def_path(self.did, &[])?;
-            Ok(())
-        })
-    }
-}
-
-impl fmt::Debug for ty::UpvarId {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        let name = ty::tls::with(|tcx| tcx.hir().name(self.var_path.hir_id));
-        write!(f, "UpvarId({:?};`{}`;{:?})", self.var_path.hir_id, name, self.closure_expr_id)
-    }
-}
-
-impl fmt::Debug for ty::UpvarBorrow<'tcx> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "UpvarBorrow({:?}, {:?})", self.kind, self.region)
-    }
-}
-
-impl fmt::Debug for ty::ExistentialTraitRef<'tcx> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        fmt::Display::fmt(self, f)
-    }
-}
-
-impl fmt::Debug for ty::adjustment::Adjustment<'tcx> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "{:?} -> {}", self.kind, self.target)
-    }
-}
-
-impl fmt::Debug for ty::BoundRegion {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match *self {
-            ty::BrAnon(n) => write!(f, "BrAnon({:?})", n),
-            ty::BrNamed(did, name) => {
-                if did.index == CRATE_DEF_INDEX {
-                    write!(f, "BrNamed({})", name)
-                } else {
-                    write!(f, "BrNamed({:?}, {})", did, name)
-                }
-            }
-            ty::BrEnv => write!(f, "BrEnv"),
-        }
-    }
-}
-
-impl fmt::Debug for ty::RegionKind {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match *self {
-            ty::ReEarlyBound(ref data) => write!(f, "ReEarlyBound({}, {})", data.index, data.name),
-
-            ty::ReClosureBound(ref vid) => write!(f, "ReClosureBound({:?})", vid),
-
-            ty::ReLateBound(binder_id, ref bound_region) => {
-                write!(f, "ReLateBound({:?}, {:?})", binder_id, bound_region)
-            }
-
-            ty::ReFree(ref fr) => fr.fmt(f),
-
-            ty::ReScope(id) => write!(f, "ReScope({:?})", id),
-
-            ty::ReStatic => write!(f, "ReStatic"),
-
-            ty::ReVar(ref vid) => vid.fmt(f),
-
-            ty::RePlaceholder(placeholder) => write!(f, "RePlaceholder({:?})", placeholder),
-
-            ty::ReEmpty(ui) => write!(f, "ReEmpty({:?})", ui),
-
-            ty::ReErased => write!(f, "ReErased"),
-        }
-    }
-}
-
-impl fmt::Debug for ty::FreeRegion {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "ReFree({:?}, {:?})", self.scope, self.bound_region)
-    }
-}
-
-impl fmt::Debug for ty::Variance {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_str(match *self {
-            ty::Covariant => "+",
-            ty::Contravariant => "-",
-            ty::Invariant => "o",
-            ty::Bivariant => "*",
-        })
-    }
-}
-
-impl fmt::Debug for ty::FnSig<'tcx> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "({:?}; c_variadic: {})->{:?}", self.inputs(), self.c_variadic, self.output())
-    }
-}
-
-impl fmt::Debug for ty::TyVid {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "_#{}t", self.index)
-    }
-}
-
-impl<'tcx> fmt::Debug for ty::ConstVid<'tcx> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "_#{}c", self.index)
-    }
-}
-
-impl fmt::Debug for ty::IntVid {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "_#{}i", self.index)
-    }
-}
-
-impl fmt::Debug for ty::FloatVid {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "_#{}f", self.index)
-    }
-}
-
-impl fmt::Debug for ty::RegionVid {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "'_#{}r", self.index())
-    }
-}
-
-impl fmt::Debug for ty::InferTy {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match *self {
-            ty::TyVar(ref v) => v.fmt(f),
-            ty::IntVar(ref v) => v.fmt(f),
-            ty::FloatVar(ref v) => v.fmt(f),
-            ty::FreshTy(v) => write!(f, "FreshTy({:?})", v),
-            ty::FreshIntTy(v) => write!(f, "FreshIntTy({:?})", v),
-            ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({:?})", v),
-        }
-    }
-}
-
-impl fmt::Debug for ty::IntVarValue {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match *self {
-            ty::IntType(ref v) => v.fmt(f),
-            ty::UintType(ref v) => v.fmt(f),
-        }
-    }
-}
-
-impl fmt::Debug for ty::FloatVarValue {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        self.0.fmt(f)
-    }
-}
-
-impl fmt::Debug for ty::TraitRef<'tcx> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        fmt::Display::fmt(self, f)
-    }
-}
-
-impl fmt::Debug for Ty<'tcx> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        fmt::Display::fmt(self, f)
-    }
-}
-
-impl fmt::Debug for ty::ParamTy {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "{}/#{}", self.name, self.index)
-    }
-}
-
-impl fmt::Debug for ty::ParamConst {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "{}/#{}", self.name, self.index)
-    }
-}
-
-impl fmt::Debug for ty::TraitPredicate<'tcx> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "TraitPredicate({:?})", self.trait_ref)
-    }
-}
-
-impl fmt::Debug for ty::ProjectionPredicate<'tcx> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "ProjectionPredicate({:?}, {:?})", self.projection_ty, self.ty)
-    }
-}
-
-impl fmt::Debug for ty::Predicate<'tcx> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match *self {
-            ty::Predicate::Trait(ref a, constness) => {
-                if let hir::Constness::Const = constness {
-                    write!(f, "const ")?;
-                }
-                a.fmt(f)
-            }
-            ty::Predicate::Subtype(ref pair) => pair.fmt(f),
-            ty::Predicate::RegionOutlives(ref pair) => pair.fmt(f),
-            ty::Predicate::TypeOutlives(ref pair) => pair.fmt(f),
-            ty::Predicate::Projection(ref pair) => pair.fmt(f),
-            ty::Predicate::WellFormed(ty) => write!(f, "WellFormed({:?})", ty),
-            ty::Predicate::ObjectSafe(trait_def_id) => write!(f, "ObjectSafe({:?})", trait_def_id),
-            ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => {
-                write!(f, "ClosureKind({:?}, {:?}, {:?})", closure_def_id, closure_substs, kind)
-            }
-            ty::Predicate::ConstEvaluatable(def_id, substs) => {
-                write!(f, "ConstEvaluatable({:?}, {:?})", def_id, substs)
-            }
-        }
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////
-// Atomic structs
-//
-// For things that don't carry any arena-allocated data (and are
-// copy...), just add them to this list.
-
-CloneTypeFoldableAndLiftImpls! {
-    (),
-    bool,
-    usize,
-    crate::ty::layout::VariantIdx,
-    u64,
-    String,
-    crate::middle::region::Scope,
-    ::syntax::ast::FloatTy,
-    ::syntax::ast::NodeId,
-    ::rustc_span::symbol::Symbol,
-    ::rustc_hir::def::Res,
-    ::rustc_hir::def_id::DefId,
-    ::rustc_hir::InlineAsmInner,
-    ::rustc_hir::MatchSource,
-    ::rustc_hir::Mutability,
-    ::rustc_hir::Unsafety,
-    ::rustc_target::spec::abi::Abi,
-    crate::mir::Local,
-    crate::mir::Promoted,
-    crate::traits::Reveal,
-    crate::ty::adjustment::AutoBorrowMutability,
-    crate::ty::AdtKind,
-    // Including `BoundRegion` is a *bit* dubious, but direct
-    // references to bound region appear in `ty::Error`, and aren't
-    // really meant to be folded. In general, we can only fold a fully
-    // general `Region`.
-    crate::ty::BoundRegion,
-    crate::ty::Placeholder<crate::ty::BoundRegion>,
-    crate::ty::ClosureKind,
-    crate::ty::FreeRegion,
-    crate::ty::InferTy,
-    crate::ty::IntVarValue,
-    crate::ty::ParamConst,
-    crate::ty::ParamTy,
-    crate::ty::adjustment::PointerCast,
-    crate::ty::RegionVid,
-    crate::ty::UniverseIndex,
-    crate::ty::Variance,
-    ::rustc_span::Span,
-}
-
-///////////////////////////////////////////////////////////////////////////
-// Lift implementations
-
-// FIXME(eddyb) replace all the uses of `Option::map` with `?`.
-impl<'tcx, A: Lift<'tcx>, B: Lift<'tcx>> Lift<'tcx> for (A, B) {
-    type Lifted = (A::Lifted, B::Lifted);
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        tcx.lift(&self.0).and_then(|a| tcx.lift(&self.1).map(|b| (a, b)))
-    }
-}
-
-impl<'tcx, A: Lift<'tcx>, B: Lift<'tcx>, C: Lift<'tcx>> Lift<'tcx> for (A, B, C) {
-    type Lifted = (A::Lifted, B::Lifted, C::Lifted);
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        tcx.lift(&self.0)
-            .and_then(|a| tcx.lift(&self.1).and_then(|b| tcx.lift(&self.2).map(|c| (a, b, c))))
-    }
-}
-
-impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Option<T> {
-    type Lifted = Option<T::Lifted>;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        match *self {
-            Some(ref x) => tcx.lift(x).map(Some),
-            None => Some(None),
-        }
-    }
-}
-
-impl<'tcx, T: Lift<'tcx>, E: Lift<'tcx>> Lift<'tcx> for Result<T, E> {
-    type Lifted = Result<T::Lifted, E::Lifted>;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        match *self {
-            Ok(ref x) => tcx.lift(x).map(Ok),
-            Err(ref e) => tcx.lift(e).map(Err),
-        }
-    }
-}
-
-impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Box<T> {
-    type Lifted = Box<T::Lifted>;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        tcx.lift(&**self).map(Box::new)
-    }
-}
-
-impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Rc<T> {
-    type Lifted = Rc<T::Lifted>;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        tcx.lift(&**self).map(Rc::new)
-    }
-}
-
-impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Arc<T> {
-    type Lifted = Arc<T::Lifted>;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        tcx.lift(&**self).map(Arc::new)
-    }
-}
-
-impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for [T] {
-    type Lifted = Vec<T::Lifted>;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        // type annotation needed to inform `projection_must_outlive`
-        let mut result: Vec<<T as Lift<'tcx>>::Lifted> = Vec::with_capacity(self.len());
-        for x in self {
-            if let Some(value) = tcx.lift(x) {
-                result.push(value);
-            } else {
-                return None;
-            }
-        }
-        Some(result)
-    }
-}
-
-impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Vec<T> {
-    type Lifted = Vec<T::Lifted>;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        tcx.lift(&self[..])
-    }
-}
-
-impl<'tcx, I: Idx, T: Lift<'tcx>> Lift<'tcx> for IndexVec<I, T> {
-    type Lifted = IndexVec<I, T::Lifted>;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        self.iter().map(|e| tcx.lift(e)).collect()
-    }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for ty::TraitRef<'a> {
-    type Lifted = ty::TraitRef<'tcx>;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        tcx.lift(&self.substs).map(|substs| ty::TraitRef { def_id: self.def_id, substs })
-    }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialTraitRef<'a> {
-    type Lifted = ty::ExistentialTraitRef<'tcx>;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        tcx.lift(&self.substs).map(|substs| ty::ExistentialTraitRef { def_id: self.def_id, substs })
-    }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialPredicate<'a> {
-    type Lifted = ty::ExistentialPredicate<'tcx>;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        match self {
-            ty::ExistentialPredicate::Trait(x) => tcx.lift(x).map(ty::ExistentialPredicate::Trait),
-            ty::ExistentialPredicate::Projection(x) => {
-                tcx.lift(x).map(ty::ExistentialPredicate::Projection)
-            }
-            ty::ExistentialPredicate::AutoTrait(def_id) => {
-                Some(ty::ExistentialPredicate::AutoTrait(*def_id))
-            }
-        }
-    }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for ty::TraitPredicate<'a> {
-    type Lifted = ty::TraitPredicate<'tcx>;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<ty::TraitPredicate<'tcx>> {
-        tcx.lift(&self.trait_ref).map(|trait_ref| ty::TraitPredicate { trait_ref })
-    }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for ty::SubtypePredicate<'a> {
-    type Lifted = ty::SubtypePredicate<'tcx>;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<ty::SubtypePredicate<'tcx>> {
-        tcx.lift(&(self.a, self.b)).map(|(a, b)| ty::SubtypePredicate {
-            a_is_expected: self.a_is_expected,
-            a,
-            b,
-        })
-    }
-}
-
-impl<'tcx, A: Copy + Lift<'tcx>, B: Copy + Lift<'tcx>> Lift<'tcx> for ty::OutlivesPredicate<A, B> {
-    type Lifted = ty::OutlivesPredicate<A::Lifted, B::Lifted>;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        tcx.lift(&(self.0, self.1)).map(|(a, b)| ty::OutlivesPredicate(a, b))
-    }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for ty::ProjectionTy<'a> {
-    type Lifted = ty::ProjectionTy<'tcx>;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<ty::ProjectionTy<'tcx>> {
-        tcx.lift(&self.substs)
-            .map(|substs| ty::ProjectionTy { item_def_id: self.item_def_id, substs })
-    }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for ty::ProjectionPredicate<'a> {
-    type Lifted = ty::ProjectionPredicate<'tcx>;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<ty::ProjectionPredicate<'tcx>> {
-        tcx.lift(&(self.projection_ty, self.ty))
-            .map(|(projection_ty, ty)| ty::ProjectionPredicate { projection_ty, ty })
-    }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialProjection<'a> {
-    type Lifted = ty::ExistentialProjection<'tcx>;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        tcx.lift(&self.substs).map(|substs| ty::ExistentialProjection {
-            substs,
-            ty: tcx.lift(&self.ty).expect("type must lift when substs do"),
-            item_def_id: self.item_def_id,
-        })
-    }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for ty::Predicate<'a> {
-    type Lifted = ty::Predicate<'tcx>;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        match *self {
-            ty::Predicate::Trait(ref binder, constness) => {
-                tcx.lift(binder).map(|binder| ty::Predicate::Trait(binder, constness))
-            }
-            ty::Predicate::Subtype(ref binder) => tcx.lift(binder).map(ty::Predicate::Subtype),
-            ty::Predicate::RegionOutlives(ref binder) => {
-                tcx.lift(binder).map(ty::Predicate::RegionOutlives)
-            }
-            ty::Predicate::TypeOutlives(ref binder) => {
-                tcx.lift(binder).map(ty::Predicate::TypeOutlives)
-            }
-            ty::Predicate::Projection(ref binder) => {
-                tcx.lift(binder).map(ty::Predicate::Projection)
-            }
-            ty::Predicate::WellFormed(ty) => tcx.lift(&ty).map(ty::Predicate::WellFormed),
-            ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => {
-                tcx.lift(&closure_substs).map(|closure_substs| {
-                    ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind)
-                })
-            }
-            ty::Predicate::ObjectSafe(trait_def_id) => {
-                Some(ty::Predicate::ObjectSafe(trait_def_id))
-            }
-            ty::Predicate::ConstEvaluatable(def_id, substs) => {
-                tcx.lift(&substs).map(|substs| ty::Predicate::ConstEvaluatable(def_id, substs))
-            }
-        }
-    }
-}
-
-impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::Binder<T> {
-    type Lifted = ty::Binder<T::Lifted>;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        tcx.lift(self.skip_binder()).map(ty::Binder::bind)
-    }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for ty::ParamEnv<'a> {
-    type Lifted = ty::ParamEnv<'tcx>;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        tcx.lift(&self.caller_bounds).map(|caller_bounds| ty::ParamEnv {
-            reveal: self.reveal,
-            caller_bounds,
-            def_id: self.def_id,
-        })
-    }
-}
-
-impl<'a, 'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::ParamEnvAnd<'a, T> {
-    type Lifted = ty::ParamEnvAnd<'tcx, T::Lifted>;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        tcx.lift(&self.param_env).and_then(|param_env| {
-            tcx.lift(&self.value).map(|value| ty::ParamEnvAnd { param_env, value })
-        })
-    }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for ty::ClosureSubsts<'a> {
-    type Lifted = ty::ClosureSubsts<'tcx>;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        tcx.lift(&self.substs).map(|substs| ty::ClosureSubsts { substs })
-    }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for ty::GeneratorSubsts<'a> {
-    type Lifted = ty::GeneratorSubsts<'tcx>;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        tcx.lift(&self.substs).map(|substs| ty::GeneratorSubsts { substs })
-    }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::Adjustment<'a> {
-    type Lifted = ty::adjustment::Adjustment<'tcx>;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        tcx.lift(&self.kind).and_then(|kind| {
-            tcx.lift(&self.target).map(|target| ty::adjustment::Adjustment { kind, target })
-        })
-    }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::Adjust<'a> {
-    type Lifted = ty::adjustment::Adjust<'tcx>;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        match *self {
-            ty::adjustment::Adjust::NeverToAny => Some(ty::adjustment::Adjust::NeverToAny),
-            ty::adjustment::Adjust::Pointer(ptr) => Some(ty::adjustment::Adjust::Pointer(ptr)),
-            ty::adjustment::Adjust::Deref(ref overloaded) => {
-                tcx.lift(overloaded).map(ty::adjustment::Adjust::Deref)
-            }
-            ty::adjustment::Adjust::Borrow(ref autoref) => {
-                tcx.lift(autoref).map(ty::adjustment::Adjust::Borrow)
-            }
-        }
-    }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::OverloadedDeref<'a> {
-    type Lifted = ty::adjustment::OverloadedDeref<'tcx>;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        tcx.lift(&self.region)
-            .map(|region| ty::adjustment::OverloadedDeref { region, mutbl: self.mutbl })
-    }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::AutoBorrow<'a> {
-    type Lifted = ty::adjustment::AutoBorrow<'tcx>;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        match *self {
-            ty::adjustment::AutoBorrow::Ref(r, m) => {
-                tcx.lift(&r).map(|r| ty::adjustment::AutoBorrow::Ref(r, m))
-            }
-            ty::adjustment::AutoBorrow::RawPtr(m) => Some(ty::adjustment::AutoBorrow::RawPtr(m)),
-        }
-    }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for ty::GenSig<'a> {
-    type Lifted = ty::GenSig<'tcx>;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        tcx.lift(&(self.resume_ty, self.yield_ty, self.return_ty))
-            .map(|(resume_ty, yield_ty, return_ty)| ty::GenSig { resume_ty, yield_ty, return_ty })
-    }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for ty::FnSig<'a> {
-    type Lifted = ty::FnSig<'tcx>;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        tcx.lift(&self.inputs_and_output).map(|x| ty::FnSig {
-            inputs_and_output: x,
-            c_variadic: self.c_variadic,
-            unsafety: self.unsafety,
-            abi: self.abi,
-        })
-    }
-}
-
-impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::error::ExpectedFound<T> {
-    type Lifted = ty::error::ExpectedFound<T::Lifted>;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        tcx.lift(&self.expected).and_then(|expected| {
-            tcx.lift(&self.found).map(|found| ty::error::ExpectedFound { expected, found })
-        })
-    }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for ty::error::TypeError<'a> {
-    type Lifted = ty::error::TypeError<'tcx>;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        use crate::ty::error::TypeError::*;
-
-        Some(match *self {
-            Mismatch => Mismatch,
-            UnsafetyMismatch(x) => UnsafetyMismatch(x),
-            AbiMismatch(x) => AbiMismatch(x),
-            Mutability => Mutability,
-            TupleSize(x) => TupleSize(x),
-            FixedArraySize(x) => FixedArraySize(x),
-            ArgCount => ArgCount,
-            RegionsDoesNotOutlive(a, b) => {
-                return tcx.lift(&(a, b)).map(|(a, b)| RegionsDoesNotOutlive(a, b));
-            }
-            RegionsInsufficientlyPolymorphic(a, b) => {
-                return tcx.lift(&b).map(|b| RegionsInsufficientlyPolymorphic(a, b));
-            }
-            RegionsOverlyPolymorphic(a, b) => {
-                return tcx.lift(&b).map(|b| RegionsOverlyPolymorphic(a, b));
-            }
-            RegionsPlaceholderMismatch => RegionsPlaceholderMismatch,
-            IntMismatch(x) => IntMismatch(x),
-            FloatMismatch(x) => FloatMismatch(x),
-            Traits(x) => Traits(x),
-            VariadicMismatch(x) => VariadicMismatch(x),
-            CyclicTy(t) => return tcx.lift(&t).map(|t| CyclicTy(t)),
-            ProjectionMismatched(x) => ProjectionMismatched(x),
-            ProjectionBoundsLength(x) => ProjectionBoundsLength(x),
-            Sorts(ref x) => return tcx.lift(x).map(Sorts),
-            ExistentialMismatch(ref x) => return tcx.lift(x).map(ExistentialMismatch),
-            ConstMismatch(ref x) => return tcx.lift(x).map(ConstMismatch),
-            IntrinsicCast => IntrinsicCast,
-            ObjectUnsafeCoercion(ref x) => return tcx.lift(x).map(ObjectUnsafeCoercion),
-        })
-    }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for ty::InstanceDef<'a> {
-    type Lifted = ty::InstanceDef<'tcx>;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        match *self {
-            ty::InstanceDef::Item(def_id) => Some(ty::InstanceDef::Item(def_id)),
-            ty::InstanceDef::VtableShim(def_id) => Some(ty::InstanceDef::VtableShim(def_id)),
-            ty::InstanceDef::ReifyShim(def_id) => Some(ty::InstanceDef::ReifyShim(def_id)),
-            ty::InstanceDef::Intrinsic(def_id) => Some(ty::InstanceDef::Intrinsic(def_id)),
-            ty::InstanceDef::FnPtrShim(def_id, ref ty) => {
-                Some(ty::InstanceDef::FnPtrShim(def_id, tcx.lift(ty)?))
-            }
-            ty::InstanceDef::Virtual(def_id, n) => Some(ty::InstanceDef::Virtual(def_id, n)),
-            ty::InstanceDef::ClosureOnceShim { call_once } => {
-                Some(ty::InstanceDef::ClosureOnceShim { call_once })
-            }
-            ty::InstanceDef::DropGlue(def_id, ref ty) => {
-                Some(ty::InstanceDef::DropGlue(def_id, tcx.lift(ty)?))
-            }
-            ty::InstanceDef::CloneShim(def_id, ref ty) => {
-                Some(ty::InstanceDef::CloneShim(def_id, tcx.lift(ty)?))
-            }
-        }
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////
-// TypeFoldable implementations.
-//
-// Ideally, each type should invoke `folder.fold_foo(self)` and
-// nothing else. In some cases, though, we haven't gotten around to
-// adding methods on the `folder` yet, and thus the folding is
-// hard-coded here. This is less-flexible, because folders cannot
-// override the behavior, but there are a lot of random types and one
-// can easily refactor the folding into the TypeFolder trait as
-// needed.
-
-/// AdtDefs are basically the same as a DefId.
-impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::AdtDef {
-    fn super_fold_with<F: TypeFolder<'tcx>>(&self, _folder: &mut F) -> Self {
-        *self
-    }
-
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> bool {
-        false
-    }
-}
-
-impl<'tcx, T: TypeFoldable<'tcx>, U: TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T, U) {
-    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> (T, U) {
-        (self.0.fold_with(folder), self.1.fold_with(folder))
-    }
-
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
-        self.0.visit_with(visitor) || self.1.visit_with(visitor)
-    }
-}
-
-EnumTypeFoldableImpl! {
-    impl<'tcx, T> TypeFoldable<'tcx> for Option<T> {
-        (Some)(a),
-        (None),
-    } where T: TypeFoldable<'tcx>
-}
-
-EnumTypeFoldableImpl! {
-    impl<'tcx, T, E> TypeFoldable<'tcx> for Result<T, E> {
-        (Ok)(a),
-        (Err)(a),
-    } where T: TypeFoldable<'tcx>, E: TypeFoldable<'tcx>,
-}
-
-impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Rc<T> {
-    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
-        Rc::new((**self).fold_with(folder))
-    }
-
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
-        (**self).visit_with(visitor)
-    }
-}
-
-impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Arc<T> {
-    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
-        Arc::new((**self).fold_with(folder))
-    }
-
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
-        (**self).visit_with(visitor)
-    }
-}
-
-impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<T> {
-    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
-        let content: T = (**self).fold_with(folder);
-        box content
-    }
-
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
-        (**self).visit_with(visitor)
-    }
-}
-
-impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Vec<T> {
-    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
-        self.iter().map(|t| t.fold_with(folder)).collect()
-    }
-
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
-        self.iter().any(|t| t.visit_with(visitor))
-    }
-}
-
-impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<[T]> {
-    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
-        self.iter().map(|t| t.fold_with(folder)).collect::<Vec<_>>().into_boxed_slice()
-    }
-
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
-        self.iter().any(|t| t.visit_with(visitor))
-    }
-}
-
-impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder<T> {
-    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
-        self.map_bound_ref(|ty| ty.fold_with(folder))
-    }
-
-    fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
-        folder.fold_binder(self)
-    }
-
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
-        self.skip_binder().visit_with(visitor)
-    }
-
-    fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
-        visitor.visit_binder(self)
-    }
-}
-
-impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::ExistentialPredicate<'tcx>> {
-    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
-        fold_list(*self, folder, |tcx, v| tcx.intern_existential_predicates(v))
-    }
-
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
-        self.iter().any(|p| p.visit_with(visitor))
-    }
-}
-
-impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<Ty<'tcx>> {
-    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
-        fold_list(*self, folder, |tcx, v| tcx.intern_type_list(v))
-    }
-
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
-        self.iter().any(|t| t.visit_with(visitor))
-    }
-}
-
-impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ProjectionKind> {
-    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
-        fold_list(*self, folder, |tcx, v| tcx.intern_projs(v))
-    }
-
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
-        self.iter().any(|t| t.visit_with(visitor))
-    }
-}
-
-impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> {
-    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
-        use crate::ty::InstanceDef::*;
-        Self {
-            substs: self.substs.fold_with(folder),
-            def: match self.def {
-                Item(did) => Item(did.fold_with(folder)),
-                VtableShim(did) => VtableShim(did.fold_with(folder)),
-                ReifyShim(did) => ReifyShim(did.fold_with(folder)),
-                Intrinsic(did) => Intrinsic(did.fold_with(folder)),
-                FnPtrShim(did, ty) => FnPtrShim(did.fold_with(folder), ty.fold_with(folder)),
-                Virtual(did, i) => Virtual(did.fold_with(folder), i),
-                ClosureOnceShim { call_once } => {
-                    ClosureOnceShim { call_once: call_once.fold_with(folder) }
-                }
-                DropGlue(did, ty) => DropGlue(did.fold_with(folder), ty.fold_with(folder)),
-                CloneShim(did, ty) => CloneShim(did.fold_with(folder), ty.fold_with(folder)),
-            },
-        }
-    }
-
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
-        use crate::ty::InstanceDef::*;
-        self.substs.visit_with(visitor)
-            || match self.def {
-                Item(did) | VtableShim(did) | ReifyShim(did) | Intrinsic(did) | Virtual(did, _) => {
-                    did.visit_with(visitor)
-                }
-                FnPtrShim(did, ty) | CloneShim(did, ty) => {
-                    did.visit_with(visitor) || ty.visit_with(visitor)
-                }
-                DropGlue(did, ty) => did.visit_with(visitor) || ty.visit_with(visitor),
-                ClosureOnceShim { call_once } => call_once.visit_with(visitor),
-            }
-    }
-}
-
-impl<'tcx> TypeFoldable<'tcx> for interpret::GlobalId<'tcx> {
-    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
-        Self { instance: self.instance.fold_with(folder), promoted: self.promoted }
-    }
-
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
-        self.instance.visit_with(visitor)
-    }
-}
-
-impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
-    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
-        let kind = match self.kind {
-            ty::RawPtr(tm) => ty::RawPtr(tm.fold_with(folder)),
-            ty::Array(typ, sz) => ty::Array(typ.fold_with(folder), sz.fold_with(folder)),
-            ty::Slice(typ) => ty::Slice(typ.fold_with(folder)),
-            ty::Adt(tid, substs) => ty::Adt(tid, substs.fold_with(folder)),
-            ty::Dynamic(ref trait_ty, ref region) => {
-                ty::Dynamic(trait_ty.fold_with(folder), region.fold_with(folder))
-            }
-            ty::Tuple(ts) => ty::Tuple(ts.fold_with(folder)),
-            ty::FnDef(def_id, substs) => ty::FnDef(def_id, substs.fold_with(folder)),
-            ty::FnPtr(f) => ty::FnPtr(f.fold_with(folder)),
-            ty::Ref(ref r, ty, mutbl) => ty::Ref(r.fold_with(folder), ty.fold_with(folder), mutbl),
-            ty::Generator(did, substs, movability) => {
-                ty::Generator(did, substs.fold_with(folder), movability)
-            }
-            ty::GeneratorWitness(types) => ty::GeneratorWitness(types.fold_with(folder)),
-            ty::Closure(did, substs) => ty::Closure(did, substs.fold_with(folder)),
-            ty::Projection(ref data) => ty::Projection(data.fold_with(folder)),
-            ty::UnnormalizedProjection(ref data) => {
-                ty::UnnormalizedProjection(data.fold_with(folder))
-            }
-            ty::Opaque(did, substs) => ty::Opaque(did, substs.fold_with(folder)),
-
-            ty::Bool
-            | ty::Char
-            | ty::Str
-            | ty::Int(_)
-            | ty::Uint(_)
-            | ty::Float(_)
-            | ty::Error
-            | ty::Infer(_)
-            | ty::Param(..)
-            | ty::Bound(..)
-            | ty::Placeholder(..)
-            | ty::Never
-            | ty::Foreign(..) => return self,
-        };
-
-        if self.kind == kind { self } else { folder.tcx().mk_ty(kind) }
-    }
-
-    fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
-        folder.fold_ty(*self)
-    }
-
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
-        match self.kind {
-            ty::RawPtr(ref tm) => tm.visit_with(visitor),
-            ty::Array(typ, sz) => typ.visit_with(visitor) || sz.visit_with(visitor),
-            ty::Slice(typ) => typ.visit_with(visitor),
-            ty::Adt(_, substs) => substs.visit_with(visitor),
-            ty::Dynamic(ref trait_ty, ref reg) => {
-                trait_ty.visit_with(visitor) || reg.visit_with(visitor)
-            }
-            ty::Tuple(ts) => ts.visit_with(visitor),
-            ty::FnDef(_, substs) => substs.visit_with(visitor),
-            ty::FnPtr(ref f) => f.visit_with(visitor),
-            ty::Ref(r, ty, _) => r.visit_with(visitor) || ty.visit_with(visitor),
-            ty::Generator(_did, ref substs, _) => substs.visit_with(visitor),
-            ty::GeneratorWitness(ref types) => types.visit_with(visitor),
-            ty::Closure(_did, ref substs) => substs.visit_with(visitor),
-            ty::Projection(ref data) | ty::UnnormalizedProjection(ref data) => {
-                data.visit_with(visitor)
-            }
-            ty::Opaque(_, ref substs) => substs.visit_with(visitor),
-
-            ty::Bool
-            | ty::Char
-            | ty::Str
-            | ty::Int(_)
-            | ty::Uint(_)
-            | ty::Float(_)
-            | ty::Error
-            | ty::Infer(_)
-            | ty::Bound(..)
-            | ty::Placeholder(..)
-            | ty::Param(..)
-            | ty::Never
-            | ty::Foreign(..) => false,
-        }
-    }
-
-    fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
-        visitor.visit_ty(self)
-    }
-}
-
-impl<'tcx> TypeFoldable<'tcx> for ty::Region<'tcx> {
-    fn super_fold_with<F: TypeFolder<'tcx>>(&self, _folder: &mut F) -> Self {
-        *self
-    }
-
-    fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
-        folder.fold_region(*self)
-    }
-
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> bool {
-        false
-    }
-
-    fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
-        visitor.visit_region(*self)
-    }
-}
-
-impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Predicate<'tcx>> {
-    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
-        fold_list(*self, folder, |tcx, v| tcx.intern_predicates(v))
-    }
-
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
-        self.iter().any(|p| p.visit_with(visitor))
-    }
-}
-
-impl<'tcx, T: TypeFoldable<'tcx>, I: Idx> TypeFoldable<'tcx> for IndexVec<I, T> {
-    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
-        self.iter().map(|x| x.fold_with(folder)).collect()
-    }
-
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
-        self.iter().any(|t| t.visit_with(visitor))
-    }
-}
-
-impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Const<'tcx> {
-    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
-        let ty = self.ty.fold_with(folder);
-        let val = self.val.fold_with(folder);
-        folder.tcx().mk_const(ty::Const { ty, val })
-    }
-
-    fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
-        folder.fold_const(*self)
-    }
-
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
-        self.ty.visit_with(visitor) || self.val.visit_with(visitor)
-    }
-
-    fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
-        visitor.visit_const(self)
-    }
-}
-
-impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> {
-    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
-        match *self {
-            ty::ConstKind::Infer(ic) => ty::ConstKind::Infer(ic.fold_with(folder)),
-            ty::ConstKind::Param(p) => ty::ConstKind::Param(p.fold_with(folder)),
-            ty::ConstKind::Unevaluated(did, substs, promoted) => {
-                ty::ConstKind::Unevaluated(did, substs.fold_with(folder), promoted)
-            }
-            ty::ConstKind::Value(_) | ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(..) => {
-                *self
-            }
-        }
-    }
-
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
-        match *self {
-            ty::ConstKind::Infer(ic) => ic.visit_with(visitor),
-            ty::ConstKind::Param(p) => p.visit_with(visitor),
-            ty::ConstKind::Unevaluated(_, substs, _) => substs.visit_with(visitor),
-            ty::ConstKind::Value(_) | ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(_) => {
-                false
-            }
-        }
-    }
-}
-
-impl<'tcx> TypeFoldable<'tcx> for InferConst<'tcx> {
-    fn super_fold_with<F: TypeFolder<'tcx>>(&self, _folder: &mut F) -> Self {
-        *self
-    }
-
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> bool {
-        false
-    }
-}
-
-// Does the equivalent of
-// ```
-// let v = self.iter().map(|p| p.fold_with(folder)).collect::<SmallVec<[_; 8]>>();
-// folder.tcx().intern_*(&v)
-// ```
-fn fold_list<'tcx, F, T>(
-    list: &'tcx ty::List<T>,
-    folder: &mut F,
-    intern: impl FnOnce(TyCtxt<'tcx>, &[T]) -> &'tcx ty::List<T>,
-) -> &'tcx ty::List<T>
-where
-    F: TypeFolder<'tcx>,
-    T: TypeFoldable<'tcx> + PartialEq + Copy,
-{
-    let mut iter = list.iter();
-    // Look for the first element that changed
-    if let Some((i, new_t)) = iter.by_ref().enumerate().find_map(|(i, t)| {
-        let new_t = t.fold_with(folder);
-        if new_t == *t { None } else { Some((i, new_t)) }
-    }) {
-        // An element changed, prepare to intern the resulting list
-        let mut new_list = SmallVec::<[_; 8]>::with_capacity(list.len());
-        new_list.extend_from_slice(&list[..i]);
-        new_list.push(new_t);
-        new_list.extend(iter.map(|t| t.fold_with(folder)));
-        intern(folder.tcx(), &new_list)
-    } else {
-        list
-    }
-}
diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
deleted file mode 100644
index c3698f402a9..00000000000
--- a/src/librustc/ty/sty.rs
+++ /dev/null
@@ -1,2602 +0,0 @@
-//! This module contains `TyKind` and its major components.
-
-#![allow(rustc::usage_of_ty_tykind)]
-
-use self::InferTy::*;
-use self::TyKind::*;
-
-use crate::infer::canonical::Canonical;
-use crate::middle::region;
-use crate::mir::interpret::ConstValue;
-use crate::mir::interpret::Scalar;
-use crate::mir::Promoted;
-use crate::ty::layout::VariantIdx;
-use crate::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, SubstsRef};
-use crate::ty::{
-    self, AdtDef, DefIdTree, Discr, Ty, TyCtxt, TypeFlags, TypeFoldable, WithConstness,
-};
-use crate::ty::{List, ParamEnv, ParamEnvAnd, TyS};
-use polonius_engine::Atom;
-use rustc_data_structures::captures::Captures;
-use rustc_hir as hir;
-use rustc_hir::def_id::DefId;
-use rustc_index::vec::Idx;
-use rustc_macros::HashStable;
-use rustc_span::symbol::{kw, Symbol};
-use rustc_target::spec::abi;
-use smallvec::SmallVec;
-use std::borrow::Cow;
-use std::cmp::Ordering;
-use std::marker::PhantomData;
-use std::ops::Range;
-use syntax::ast::{self, Ident};
-
-#[derive(
-    Clone,
-    Copy,
-    PartialEq,
-    Eq,
-    PartialOrd,
-    Ord,
-    Hash,
-    Debug,
-    RustcEncodable,
-    RustcDecodable,
-    HashStable,
-    TypeFoldable,
-    Lift
-)]
-pub struct TypeAndMut<'tcx> {
-    pub ty: Ty<'tcx>,
-    pub mutbl: hir::Mutability,
-}
-
-#[derive(
-    Clone,
-    PartialEq,
-    PartialOrd,
-    Eq,
-    Ord,
-    Hash,
-    RustcEncodable,
-    RustcDecodable,
-    Copy,
-    HashStable
-)]
-/// A "free" region `fr` can be interpreted as "some region
-/// at least as big as the scope `fr.scope`".
-pub struct FreeRegion {
-    pub scope: DefId,
-    pub bound_region: BoundRegion,
-}
-
-#[derive(
-    Clone,
-    PartialEq,
-    PartialOrd,
-    Eq,
-    Ord,
-    Hash,
-    RustcEncodable,
-    RustcDecodable,
-    Copy,
-    HashStable
-)]
-pub enum BoundRegion {
-    /// An anonymous region parameter for a given fn (&T)
-    BrAnon(u32),
-
-    /// Named region parameters for functions (a in &'a T)
-    ///
-    /// The `DefId` is needed to distinguish free regions in
-    /// the event of shadowing.
-    BrNamed(DefId, Symbol),
-
-    /// Anonymous region for the implicit env pointer parameter
-    /// to a closure
-    BrEnv,
-}
-
-impl BoundRegion {
-    pub fn is_named(&self) -> bool {
-        match *self {
-            BoundRegion::BrNamed(_, name) => name != kw::UnderscoreLifetime,
-            _ => false,
-        }
-    }
-
-    /// When canonicalizing, we replace unbound inference variables and free
-    /// regions with anonymous late bound regions. This method asserts that
-    /// we have an anonymous late bound region, which hence may refer to
-    /// a canonical variable.
-    pub fn assert_bound_var(&self) -> BoundVar {
-        match *self {
-            BoundRegion::BrAnon(var) => BoundVar::from_u32(var),
-            _ => bug!("bound region is not anonymous"),
-        }
-    }
-}
-
-/// N.B., if you change this, you'll probably want to change the corresponding
-/// AST structure in `libsyntax/ast.rs` as well.
-#[derive(
-    Clone,
-    PartialEq,
-    Eq,
-    PartialOrd,
-    Ord,
-    Hash,
-    RustcEncodable,
-    RustcDecodable,
-    HashStable,
-    Debug
-)]
-#[rustc_diagnostic_item = "TyKind"]
-pub enum TyKind<'tcx> {
-    /// The primitive boolean type. Written as `bool`.
-    Bool,
-
-    /// The primitive character type; holds a Unicode scalar value
-    /// (a non-surrogate code point). Written as `char`.
-    Char,
-
-    /// A primitive signed integer type. For example, `i32`.
-    Int(ast::IntTy),
-
-    /// A primitive unsigned integer type. For example, `u32`.
-    Uint(ast::UintTy),
-
-    /// A primitive floating-point type. For example, `f64`.
-    Float(ast::FloatTy),
-
-    /// Structures, enumerations and unions.
-    ///
-    /// InternalSubsts here, possibly against intuition, *may* contain `Param`s.
-    /// That is, even after substitution it is possible that there are type
-    /// variables. This happens when the `Adt` corresponds to an ADT
-    /// definition and not a concrete use of it.
-    Adt(&'tcx AdtDef, SubstsRef<'tcx>),
-
-    /// An unsized FFI type that is opaque to Rust. Written as `extern type T`.
-    Foreign(DefId),
-
-    /// The pointee of a string slice. Written as `str`.
-    Str,
-
-    /// An array with the given length. Written as `[T; n]`.
-    Array(Ty<'tcx>, &'tcx ty::Const<'tcx>),
-
-    /// The pointee of an array slice. Written as `[T]`.
-    Slice(Ty<'tcx>),
-
-    /// A raw pointer. Written as `*mut T` or `*const T`
-    RawPtr(TypeAndMut<'tcx>),
-
-    /// A reference; a pointer with an associated lifetime. Written as
-    /// `&'a mut T` or `&'a T`.
-    Ref(Region<'tcx>, Ty<'tcx>, hir::Mutability),
-
-    /// The anonymous type of a function declaration/definition. Each
-    /// function has a unique type, which is output (for a function
-    /// named `foo` returning an `i32`) as `fn() -> i32 {foo}`.
-    ///
-    /// For example the type of `bar` here:
-    ///
-    /// ```rust
-    /// fn foo() -> i32 { 1 }
-    /// let bar = foo; // bar: fn() -> i32 {foo}
-    /// ```
-    FnDef(DefId, SubstsRef<'tcx>),
-
-    /// A pointer to a function. Written as `fn() -> i32`.
-    ///
-    /// For example the type of `bar` here:
-    ///
-    /// ```rust
-    /// fn foo() -> i32 { 1 }
-    /// let bar: fn() -> i32 = foo;
-    /// ```
-    FnPtr(PolyFnSig<'tcx>),
-
-    /// A trait, defined with `trait`.
-    Dynamic(Binder<&'tcx List<ExistentialPredicate<'tcx>>>, ty::Region<'tcx>),
-
-    /// The anonymous type of a closure. Used to represent the type of
-    /// `|a| a`.
-    Closure(DefId, SubstsRef<'tcx>),
-
-    /// The anonymous type of a generator. Used to represent the type of
-    /// `|a| yield a`.
-    Generator(DefId, SubstsRef<'tcx>, hir::Movability),
-
-    /// A type representin the types stored inside a generator.
-    /// This should only appear in GeneratorInteriors.
-    GeneratorWitness(Binder<&'tcx List<Ty<'tcx>>>),
-
-    /// The never type `!`
-    Never,
-
-    /// A tuple type. For example, `(i32, bool)`.
-    /// Use `TyS::tuple_fields` to iterate over the field types.
-    Tuple(SubstsRef<'tcx>),
-
-    /// The projection of an associated type. For example,
-    /// `<T as Trait<..>>::N`.
-    Projection(ProjectionTy<'tcx>),
-
-    /// A placeholder type used when we do not have enough information
-    /// to normalize the projection of an associated type to an
-    /// existing concrete type. Currently only used with chalk-engine.
-    UnnormalizedProjection(ProjectionTy<'tcx>),
-
-    /// Opaque (`impl Trait`) type found in a return type.
-    /// The `DefId` comes either from
-    /// * the `impl Trait` ast::Ty node,
-    /// * or the `type Foo = impl Trait` declaration
-    /// The substitutions are for the generics of the function in question.
-    /// After typeck, the concrete type can be found in the `types` map.
-    Opaque(DefId, SubstsRef<'tcx>),
-
-    /// A type parameter; for example, `T` in `fn f<T>(x: T) {}
-    Param(ParamTy),
-
-    /// Bound type variable, used only when preparing a trait query.
-    Bound(ty::DebruijnIndex, BoundTy),
-
-    /// A placeholder type - universally quantified higher-ranked type.
-    Placeholder(ty::PlaceholderType),
-
-    /// A type variable used during type checking.
-    Infer(InferTy),
-
-    /// A placeholder for a type which could not be computed; this is
-    /// propagated to avoid useless error messages.
-    Error,
-}
-
-// `TyKind` is used a lot. Make sure it doesn't unintentionally get bigger.
-#[cfg(target_arch = "x86_64")]
-static_assert_size!(TyKind<'_>, 24);
-
-/// A closure can be modeled as a struct that looks like:
-///
-///     struct Closure<'l0...'li, T0...Tj, CK, CS, U0...Uk> {
-///         upvar0: U0,
-///         ...
-///         upvark: Uk
-///     }
-///
-/// where:
-///
-/// - 'l0...'li and T0...Tj are the lifetime and type parameters
-///   in scope on the function that defined the closure,
-/// - CK represents the *closure kind* (Fn vs FnMut vs FnOnce). This
-///   is rather hackily encoded via a scalar type. See
-///   `TyS::to_opt_closure_kind` for details.
-/// - CS represents the *closure signature*, representing as a `fn()`
-///   type. For example, `fn(u32, u32) -> u32` would mean that the closure
-///   implements `CK<(u32, u32), Output = u32>`, where `CK` is the trait
-///   specified above.
-/// - U0...Uk are type parameters representing the types of its upvars
-///   (borrowed, if appropriate; that is, if Ui represents a by-ref upvar,
-///    and the up-var has the type `Foo`, then `Ui = &Foo`).
-///
-/// So, for example, given this function:
-///
-///     fn foo<'a, T>(data: &'a mut T) {
-///          do(|| data.count += 1)
-///     }
-///
-/// the type of the closure would be something like:
-///
-///     struct Closure<'a, T, U0> {
-///         data: U0
-///     }
-///
-/// Note that the type of the upvar is not specified in the struct.
-/// You may wonder how the impl would then be able to use the upvar,
-/// if it doesn't know it's type? The answer is that the impl is
-/// (conceptually) not fully generic over Closure but rather tied to
-/// instances with the expected upvar types:
-///
-///     impl<'b, 'a, T> FnMut() for Closure<'a, T, &'b mut &'a mut T> {
-///         ...
-///     }
-///
-/// You can see that the *impl* fully specified the type of the upvar
-/// and thus knows full well that `data` has type `&'b mut &'a mut T`.
-/// (Here, I am assuming that `data` is mut-borrowed.)
-///
-/// Now, the last question you may ask is: Why include the upvar types
-/// as extra type parameters? The reason for this design is that the
-/// upvar types can reference lifetimes that are internal to the
-/// creating function. In my example above, for example, the lifetime
-/// `'b` represents the scope of the closure itself; this is some
-/// subset of `foo`, probably just the scope of the call to the to
-/// `do()`. If we just had the lifetime/type parameters from the
-/// enclosing function, we couldn't name this lifetime `'b`. Note that
-/// there can also be lifetimes in the types of the upvars themselves,
-/// if one of them happens to be a reference to something that the
-/// creating fn owns.
-///
-/// OK, you say, so why not create a more minimal set of parameters
-/// that just includes the extra lifetime parameters? The answer is
-/// primarily that it would be hard --- we don't know at the time when
-/// we create the closure type what the full types of the upvars are,
-/// nor do we know which are borrowed and which are not. In this
-/// design, we can just supply a fresh type parameter and figure that
-/// out later.
-///
-/// All right, you say, but why include the type parameters from the
-/// original function then? The answer is that codegen may need them
-/// when monomorphizing, and they may not appear in the upvars. A
-/// closure could capture no variables but still make use of some
-/// in-scope type parameter with a bound (e.g., if our example above
-/// had an extra `U: Default`, and the closure called `U::default()`).
-///
-/// There is another reason. This design (implicitly) prohibits
-/// closures from capturing themselves (except via a trait
-/// object). This simplifies closure inference considerably, since it
-/// means that when we infer the kind of a closure or its upvars, we
-/// don't have to handle cycles where the decisions we make for
-/// closure C wind up influencing the decisions we ought to make for
-/// closure C (which would then require fixed point iteration to
-/// handle). Plus it fixes an ICE. :P
-///
-/// ## Generators
-///
-/// Generators are handled similarly in `GeneratorSubsts`.  The set of
-/// type parameters is similar, but `CK` and `CS` are replaced by the
-/// following type parameters:
-///
-/// * `GS`: The generator's "resume type", which is the type of the
-///   argument passed to `resume`, and the type of `yield` expressions
-///   inside the generator.
-/// * `GY`: The "yield type", which is the type of values passed to
-///   `yield` inside the generator.
-/// * `GR`: The "return type", which is the type of value returned upon
-///   completion of the generator.
-/// * `GW`: The "generator witness".
-#[derive(Copy, Clone, Debug, TypeFoldable)]
-pub struct ClosureSubsts<'tcx> {
-    /// Lifetime and type parameters from the enclosing function,
-    /// concatenated with the types of the upvars.
-    ///
-    /// These are separated out because codegen wants to pass them around
-    /// when monomorphizing.
-    pub substs: SubstsRef<'tcx>,
-}
-
-/// Struct returned by `split()`. Note that these are subslices of the
-/// parent slice and not canonical substs themselves.
-struct SplitClosureSubsts<'tcx> {
-    closure_kind_ty: Ty<'tcx>,
-    closure_sig_ty: Ty<'tcx>,
-    upvar_kinds: &'tcx [GenericArg<'tcx>],
-}
-
-impl<'tcx> ClosureSubsts<'tcx> {
-    /// Divides the closure substs into their respective
-    /// components. Single source of truth with respect to the
-    /// ordering.
-    fn split(self, def_id: DefId, tcx: TyCtxt<'_>) -> SplitClosureSubsts<'tcx> {
-        let generics = tcx.generics_of(def_id);
-        let parent_len = generics.parent_count;
-        SplitClosureSubsts {
-            closure_kind_ty: self.substs.type_at(parent_len),
-            closure_sig_ty: self.substs.type_at(parent_len + 1),
-            upvar_kinds: &self.substs[parent_len + 2..],
-        }
-    }
-
-    #[inline]
-    pub fn upvar_tys(
-        self,
-        def_id: DefId,
-        tcx: TyCtxt<'_>,
-    ) -> impl Iterator<Item = Ty<'tcx>> + 'tcx {
-        let SplitClosureSubsts { upvar_kinds, .. } = self.split(def_id, tcx);
-        upvar_kinds.iter().map(|t| {
-            if let GenericArgKind::Type(ty) = t.unpack() {
-                ty
-            } else {
-                bug!("upvar should be type")
-            }
-        })
-    }
-
-    /// Returns the closure kind for this closure; may return a type
-    /// variable during inference. To get the closure kind during
-    /// inference, use `infcx.closure_kind(def_id, substs)`.
-    pub fn kind_ty(self, def_id: DefId, tcx: TyCtxt<'_>) -> Ty<'tcx> {
-        self.split(def_id, tcx).closure_kind_ty
-    }
-
-    /// Returns the type representing the closure signature for this
-    /// closure; may contain type variables during inference. To get
-    /// the closure signature during inference, use
-    /// `infcx.fn_sig(def_id)`.
-    pub fn sig_ty(self, def_id: DefId, tcx: TyCtxt<'_>) -> Ty<'tcx> {
-        self.split(def_id, tcx).closure_sig_ty
-    }
-
-    /// Returns the closure kind for this closure; only usable outside
-    /// of an inference context, because in that context we know that
-    /// there are no type variables.
-    ///
-    /// If you have an inference context, use `infcx.closure_kind()`.
-    pub fn kind(self, def_id: DefId, tcx: TyCtxt<'tcx>) -> ty::ClosureKind {
-        self.split(def_id, tcx).closure_kind_ty.to_opt_closure_kind().unwrap()
-    }
-
-    /// Extracts the signature from the closure; only usable outside
-    /// of an inference context, because in that context we know that
-    /// there are no type variables.
-    ///
-    /// If you have an inference context, use `infcx.closure_sig()`.
-    pub fn sig(&self, def_id: DefId, tcx: TyCtxt<'tcx>) -> ty::PolyFnSig<'tcx> {
-        let ty = self.sig_ty(def_id, tcx);
-        match ty.kind {
-            ty::FnPtr(sig) => sig,
-            _ => bug!("closure_sig_ty is not a fn-ptr: {:?}", ty.kind),
-        }
-    }
-}
-
-/// Similar to `ClosureSubsts`; see the above documentation for more.
-#[derive(Copy, Clone, Debug, TypeFoldable)]
-pub struct GeneratorSubsts<'tcx> {
-    pub substs: SubstsRef<'tcx>,
-}
-
-struct SplitGeneratorSubsts<'tcx> {
-    resume_ty: Ty<'tcx>,
-    yield_ty: Ty<'tcx>,
-    return_ty: Ty<'tcx>,
-    witness: Ty<'tcx>,
-    upvar_kinds: &'tcx [GenericArg<'tcx>],
-}
-
-impl<'tcx> GeneratorSubsts<'tcx> {
-    fn split(self, def_id: DefId, tcx: TyCtxt<'_>) -> SplitGeneratorSubsts<'tcx> {
-        let generics = tcx.generics_of(def_id);
-        let parent_len = generics.parent_count;
-        SplitGeneratorSubsts {
-            resume_ty: self.substs.type_at(parent_len),
-            yield_ty: self.substs.type_at(parent_len + 1),
-            return_ty: self.substs.type_at(parent_len + 2),
-            witness: self.substs.type_at(parent_len + 3),
-            upvar_kinds: &self.substs[parent_len + 4..],
-        }
-    }
-
-    /// This describes the types that can be contained in a generator.
-    /// It will be a type variable initially and unified in the last stages of typeck of a body.
-    /// It contains a tuple of all the types that could end up on a generator frame.
-    /// The state transformation MIR pass may only produce layouts which mention types
-    /// in this tuple. Upvars are not counted here.
-    pub fn witness(self, def_id: DefId, tcx: TyCtxt<'_>) -> Ty<'tcx> {
-        self.split(def_id, tcx).witness
-    }
-
-    #[inline]
-    pub fn upvar_tys(
-        self,
-        def_id: DefId,
-        tcx: TyCtxt<'_>,
-    ) -> impl Iterator<Item = Ty<'tcx>> + 'tcx {
-        let SplitGeneratorSubsts { upvar_kinds, .. } = self.split(def_id, tcx);
-        upvar_kinds.iter().map(|t| {
-            if let GenericArgKind::Type(ty) = t.unpack() {
-                ty
-            } else {
-                bug!("upvar should be type")
-            }
-        })
-    }
-
-    /// Returns the type representing the resume type of the generator.
-    pub fn resume_ty(self, def_id: DefId, tcx: TyCtxt<'_>) -> Ty<'tcx> {
-        self.split(def_id, tcx).resume_ty
-    }
-
-    /// Returns the type representing the yield type of the generator.
-    pub fn yield_ty(self, def_id: DefId, tcx: TyCtxt<'_>) -> Ty<'tcx> {
-        self.split(def_id, tcx).yield_ty
-    }
-
-    /// Returns the type representing the return type of the generator.
-    pub fn return_ty(self, def_id: DefId, tcx: TyCtxt<'_>) -> Ty<'tcx> {
-        self.split(def_id, tcx).return_ty
-    }
-
-    /// Returns the "generator signature", which consists of its yield
-    /// and return types.
-    ///
-    /// N.B., some bits of the code prefers to see this wrapped in a
-    /// binder, but it never contains bound regions. Probably this
-    /// function should be removed.
-    pub fn poly_sig(self, def_id: DefId, tcx: TyCtxt<'_>) -> PolyGenSig<'tcx> {
-        ty::Binder::dummy(self.sig(def_id, tcx))
-    }
-
-    /// Returns the "generator signature", which consists of its resume, yield
-    /// and return types.
-    pub fn sig(self, def_id: DefId, tcx: TyCtxt<'_>) -> GenSig<'tcx> {
-        ty::GenSig {
-            resume_ty: self.resume_ty(def_id, tcx),
-            yield_ty: self.yield_ty(def_id, tcx),
-            return_ty: self.return_ty(def_id, tcx),
-        }
-    }
-}
-
-impl<'tcx> GeneratorSubsts<'tcx> {
-    /// Generator has not been resumed yet.
-    pub const UNRESUMED: usize = 0;
-    /// Generator has returned or is completed.
-    pub const RETURNED: usize = 1;
-    /// Generator has been poisoned.
-    pub const POISONED: usize = 2;
-
-    const UNRESUMED_NAME: &'static str = "Unresumed";
-    const RETURNED_NAME: &'static str = "Returned";
-    const POISONED_NAME: &'static str = "Panicked";
-
-    /// The valid variant indices of this generator.
-    #[inline]
-    pub fn variant_range(&self, def_id: DefId, tcx: TyCtxt<'tcx>) -> Range<VariantIdx> {
-        // FIXME requires optimized MIR
-        let num_variants = tcx.generator_layout(def_id).variant_fields.len();
-        VariantIdx::new(0)..VariantIdx::new(num_variants)
-    }
-
-    /// The discriminant for the given variant. Panics if the `variant_index` is
-    /// out of range.
-    #[inline]
-    pub fn discriminant_for_variant(
-        &self,
-        def_id: DefId,
-        tcx: TyCtxt<'tcx>,
-        variant_index: VariantIdx,
-    ) -> Discr<'tcx> {
-        // Generators don't support explicit discriminant values, so they are
-        // the same as the variant index.
-        assert!(self.variant_range(def_id, tcx).contains(&variant_index));
-        Discr { val: variant_index.as_usize() as u128, ty: self.discr_ty(tcx) }
-    }
-
-    /// The set of all discriminants for the generator, enumerated with their
-    /// variant indices.
-    #[inline]
-    pub fn discriminants(
-        self,
-        def_id: DefId,
-        tcx: TyCtxt<'tcx>,
-    ) -> impl Iterator<Item = (VariantIdx, Discr<'tcx>)> + Captures<'tcx> {
-        self.variant_range(def_id, tcx).map(move |index| {
-            (index, Discr { val: index.as_usize() as u128, ty: self.discr_ty(tcx) })
-        })
-    }
-
-    /// Calls `f` with a reference to the name of the enumerator for the given
-    /// variant `v`.
-    #[inline]
-    pub fn variant_name(self, v: VariantIdx) -> Cow<'static, str> {
-        match v.as_usize() {
-            Self::UNRESUMED => Cow::from(Self::UNRESUMED_NAME),
-            Self::RETURNED => Cow::from(Self::RETURNED_NAME),
-            Self::POISONED => Cow::from(Self::POISONED_NAME),
-            _ => Cow::from(format!("Suspend{}", v.as_usize() - 3)),
-        }
-    }
-
-    /// The type of the state discriminant used in the generator type.
-    #[inline]
-    pub fn discr_ty(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
-        tcx.types.u32
-    }
-
-    /// This returns the types of the MIR locals which had to be stored across suspension points.
-    /// It is calculated in rustc_mir::transform::generator::StateTransform.
-    /// All the types here must be in the tuple in GeneratorInterior.
-    ///
-    /// The locals are grouped by their variant number. Note that some locals may
-    /// be repeated in multiple variants.
-    #[inline]
-    pub fn state_tys(
-        self,
-        def_id: DefId,
-        tcx: TyCtxt<'tcx>,
-    ) -> impl Iterator<Item = impl Iterator<Item = Ty<'tcx>> + Captures<'tcx>> {
-        let layout = tcx.generator_layout(def_id);
-        layout.variant_fields.iter().map(move |variant| {
-            variant.iter().map(move |field| layout.field_tys[*field].subst(tcx, self.substs))
-        })
-    }
-
-    /// This is the types of the fields of a generator which are not stored in a
-    /// variant.
-    #[inline]
-    pub fn prefix_tys(self, def_id: DefId, tcx: TyCtxt<'tcx>) -> impl Iterator<Item = Ty<'tcx>> {
-        self.upvar_tys(def_id, tcx)
-    }
-}
-
-#[derive(Debug, Copy, Clone)]
-pub enum UpvarSubsts<'tcx> {
-    Closure(SubstsRef<'tcx>),
-    Generator(SubstsRef<'tcx>),
-}
-
-impl<'tcx> UpvarSubsts<'tcx> {
-    #[inline]
-    pub fn upvar_tys(
-        self,
-        def_id: DefId,
-        tcx: TyCtxt<'tcx>,
-    ) -> impl Iterator<Item = Ty<'tcx>> + 'tcx {
-        let upvar_kinds = match self {
-            UpvarSubsts::Closure(substs) => substs.as_closure().split(def_id, tcx).upvar_kinds,
-            UpvarSubsts::Generator(substs) => substs.as_generator().split(def_id, tcx).upvar_kinds,
-        };
-        upvar_kinds.iter().map(|t| {
-            if let GenericArgKind::Type(ty) = t.unpack() {
-                ty
-            } else {
-                bug!("upvar should be type")
-            }
-        })
-    }
-}
-
-#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Hash, RustcEncodable, RustcDecodable)]
-#[derive(HashStable, TypeFoldable)]
-pub enum ExistentialPredicate<'tcx> {
-    /// E.g., `Iterator`.
-    Trait(ExistentialTraitRef<'tcx>),
-    /// E.g., `Iterator::Item = T`.
-    Projection(ExistentialProjection<'tcx>),
-    /// E.g., `Send`.
-    AutoTrait(DefId),
-}
-
-impl<'tcx> ExistentialPredicate<'tcx> {
-    /// Compares via an ordering that will not change if modules are reordered or other changes are
-    /// made to the tree. In particular, this ordering is preserved across incremental compilations.
-    pub fn stable_cmp(&self, tcx: TyCtxt<'tcx>, other: &Self) -> Ordering {
-        use self::ExistentialPredicate::*;
-        match (*self, *other) {
-            (Trait(_), Trait(_)) => Ordering::Equal,
-            (Projection(ref a), Projection(ref b)) => {
-                tcx.def_path_hash(a.item_def_id).cmp(&tcx.def_path_hash(b.item_def_id))
-            }
-            (AutoTrait(ref a), AutoTrait(ref b)) => {
-                tcx.trait_def(*a).def_path_hash.cmp(&tcx.trait_def(*b).def_path_hash)
-            }
-            (Trait(_), _) => Ordering::Less,
-            (Projection(_), Trait(_)) => Ordering::Greater,
-            (Projection(_), _) => Ordering::Less,
-            (AutoTrait(_), _) => Ordering::Greater,
-        }
-    }
-}
-
-impl<'tcx> Binder<ExistentialPredicate<'tcx>> {
-    pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::Predicate<'tcx> {
-        use crate::ty::ToPredicate;
-        match *self.skip_binder() {
-            ExistentialPredicate::Trait(tr) => {
-                Binder(tr).with_self_ty(tcx, self_ty).without_const().to_predicate()
-            }
-            ExistentialPredicate::Projection(p) => {
-                ty::Predicate::Projection(Binder(p.with_self_ty(tcx, self_ty)))
-            }
-            ExistentialPredicate::AutoTrait(did) => {
-                let trait_ref =
-                    Binder(ty::TraitRef { def_id: did, substs: tcx.mk_substs_trait(self_ty, &[]) });
-                trait_ref.without_const().to_predicate()
-            }
-        }
-    }
-}
-
-impl<'tcx> rustc_serialize::UseSpecializedDecodable for &'tcx List<ExistentialPredicate<'tcx>> {}
-
-impl<'tcx> List<ExistentialPredicate<'tcx>> {
-    /// Returns the "principal `DefId`" of this set of existential predicates.
-    ///
-    /// A Rust trait object type consists (in addition to a lifetime bound)
-    /// of a set of trait bounds, which are separated into any number
-    /// of auto-trait bounds, and at most one non-auto-trait bound. The
-    /// non-auto-trait bound is called the "principal" of the trait
-    /// object.
-    ///
-    /// Only the principal can have methods or type parameters (because
-    /// auto traits can have neither of them). This is important, because
-    /// it means the auto traits can be treated as an unordered set (methods
-    /// would force an order for the vtable, while relating traits with
-    /// type parameters without knowing the order to relate them in is
-    /// a rather non-trivial task).
-    ///
-    /// For example, in the trait object `dyn fmt::Debug + Sync`, the
-    /// principal bound is `Some(fmt::Debug)`, while the auto-trait bounds
-    /// are the set `{Sync}`.
-    ///
-    /// It is also possible to have a "trivial" trait object that
-    /// consists only of auto traits, with no principal - for example,
-    /// `dyn Send + Sync`. In that case, the set of auto-trait bounds
-    /// is `{Send, Sync}`, while there is no principal. These trait objects
-    /// have a "trivial" vtable consisting of just the size, alignment,
-    /// and destructor.
-    pub fn principal(&self) -> Option<ExistentialTraitRef<'tcx>> {
-        match self[0] {
-            ExistentialPredicate::Trait(tr) => Some(tr),
-            _ => None,
-        }
-    }
-
-    pub fn principal_def_id(&self) -> Option<DefId> {
-        self.principal().map(|trait_ref| trait_ref.def_id)
-    }
-
-    #[inline]
-    pub fn projection_bounds<'a>(
-        &'a self,
-    ) -> impl Iterator<Item = ExistentialProjection<'tcx>> + 'a {
-        self.iter().filter_map(|predicate| match *predicate {
-            ExistentialPredicate::Projection(projection) => Some(projection),
-            _ => None,
-        })
-    }
-
-    #[inline]
-    pub fn auto_traits<'a>(&'a self) -> impl Iterator<Item = DefId> + 'a {
-        self.iter().filter_map(|predicate| match *predicate {
-            ExistentialPredicate::AutoTrait(did) => Some(did),
-            _ => None,
-        })
-    }
-}
-
-impl<'tcx> Binder<&'tcx List<ExistentialPredicate<'tcx>>> {
-    pub fn principal(&self) -> Option<ty::Binder<ExistentialTraitRef<'tcx>>> {
-        self.skip_binder().principal().map(Binder::bind)
-    }
-
-    pub fn principal_def_id(&self) -> Option<DefId> {
-        self.skip_binder().principal_def_id()
-    }
-
-    #[inline]
-    pub fn projection_bounds<'a>(
-        &'a self,
-    ) -> impl Iterator<Item = PolyExistentialProjection<'tcx>> + 'a {
-        self.skip_binder().projection_bounds().map(Binder::bind)
-    }
-
-    #[inline]
-    pub fn auto_traits<'a>(&'a self) -> impl Iterator<Item = DefId> + 'a {
-        self.skip_binder().auto_traits()
-    }
-
-    pub fn iter<'a>(
-        &'a self,
-    ) -> impl DoubleEndedIterator<Item = Binder<ExistentialPredicate<'tcx>>> + 'tcx {
-        self.skip_binder().iter().cloned().map(Binder::bind)
-    }
-}
-
-/// A complete reference to a trait. These take numerous guises in syntax,
-/// but perhaps the most recognizable form is in a where-clause:
-///
-///     T: Foo<U>
-///
-/// This would be represented by a trait-reference where the `DefId` is the
-/// `DefId` for the trait `Foo` and the substs define `T` as parameter 0,
-/// and `U` as parameter 1.
-///
-/// Trait references also appear in object types like `Foo<U>`, but in
-/// that case the `Self` parameter is absent from the substitutions.
-///
-/// Note that a `TraitRef` introduces a level of region binding, to
-/// account for higher-ranked trait bounds like `T: for<'a> Foo<&'a U>`
-/// or higher-ranked object types.
-#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
-#[derive(HashStable, TypeFoldable)]
-pub struct TraitRef<'tcx> {
-    pub def_id: DefId,
-    pub substs: SubstsRef<'tcx>,
-}
-
-impl<'tcx> TraitRef<'tcx> {
-    pub fn new(def_id: DefId, substs: SubstsRef<'tcx>) -> TraitRef<'tcx> {
-        TraitRef { def_id, substs }
-    }
-
-    /// Returns a `TraitRef` of the form `P0: Foo<P1..Pn>` where `Pi`
-    /// are the parameters defined on trait.
-    pub fn identity(tcx: TyCtxt<'tcx>, def_id: DefId) -> TraitRef<'tcx> {
-        TraitRef { def_id, substs: InternalSubsts::identity_for_item(tcx, def_id) }
-    }
-
-    #[inline]
-    pub fn self_ty(&self) -> Ty<'tcx> {
-        self.substs.type_at(0)
-    }
-
-    pub fn input_types<'a>(&'a self) -> impl DoubleEndedIterator<Item = Ty<'tcx>> + 'a {
-        // Select only the "input types" from a trait-reference. For
-        // now this is all the types that appear in the
-        // trait-reference, but it should eventually exclude
-        // associated types.
-        self.substs.types()
-    }
-
-    pub fn from_method(
-        tcx: TyCtxt<'tcx>,
-        trait_id: DefId,
-        substs: SubstsRef<'tcx>,
-    ) -> ty::TraitRef<'tcx> {
-        let defs = tcx.generics_of(trait_id);
-
-        ty::TraitRef { def_id: trait_id, substs: tcx.intern_substs(&substs[..defs.params.len()]) }
-    }
-}
-
-pub type PolyTraitRef<'tcx> = Binder<TraitRef<'tcx>>;
-
-impl<'tcx> PolyTraitRef<'tcx> {
-    pub fn self_ty(&self) -> Ty<'tcx> {
-        self.skip_binder().self_ty()
-    }
-
-    pub fn def_id(&self) -> DefId {
-        self.skip_binder().def_id
-    }
-
-    pub fn to_poly_trait_predicate(&self) -> ty::PolyTraitPredicate<'tcx> {
-        // Note that we preserve binding levels
-        Binder(ty::TraitPredicate { trait_ref: *self.skip_binder() })
-    }
-}
-
-/// An existential reference to a trait, where `Self` is erased.
-/// For example, the trait object `Trait<'a, 'b, X, Y>` is:
-///
-///     exists T. T: Trait<'a, 'b, X, Y>
-///
-/// The substitutions don't include the erased `Self`, only trait
-/// type and lifetime parameters (`[X, Y]` and `['a, 'b]` above).
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
-#[derive(HashStable, TypeFoldable)]
-pub struct ExistentialTraitRef<'tcx> {
-    pub def_id: DefId,
-    pub substs: SubstsRef<'tcx>,
-}
-
-impl<'tcx> ExistentialTraitRef<'tcx> {
-    pub fn input_types<'b>(&'b self) -> impl DoubleEndedIterator<Item = Ty<'tcx>> + 'b {
-        // Select only the "input types" from a trait-reference. For
-        // now this is all the types that appear in the
-        // trait-reference, but it should eventually exclude
-        // associated types.
-        self.substs.types()
-    }
-
-    pub fn erase_self_ty(
-        tcx: TyCtxt<'tcx>,
-        trait_ref: ty::TraitRef<'tcx>,
-    ) -> ty::ExistentialTraitRef<'tcx> {
-        // Assert there is a Self.
-        trait_ref.substs.type_at(0);
-
-        ty::ExistentialTraitRef {
-            def_id: trait_ref.def_id,
-            substs: tcx.intern_substs(&trait_ref.substs[1..]),
-        }
-    }
-
-    /// Object types don't have a self type specified. Therefore, when
-    /// we convert the principal trait-ref into a normal trait-ref,
-    /// you must give *some* self type. A common choice is `mk_err()`
-    /// or some placeholder type.
-    pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::TraitRef<'tcx> {
-        // otherwise the escaping vars would be captured by the binder
-        // debug_assert!(!self_ty.has_escaping_bound_vars());
-
-        ty::TraitRef { def_id: self.def_id, substs: tcx.mk_substs_trait(self_ty, self.substs) }
-    }
-}
-
-pub type PolyExistentialTraitRef<'tcx> = Binder<ExistentialTraitRef<'tcx>>;
-
-impl<'tcx> PolyExistentialTraitRef<'tcx> {
-    pub fn def_id(&self) -> DefId {
-        self.skip_binder().def_id
-    }
-
-    /// Object types don't have a self type specified. Therefore, when
-    /// we convert the principal trait-ref into a normal trait-ref,
-    /// you must give *some* self type. A common choice is `mk_err()`
-    /// or some placeholder type.
-    pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::PolyTraitRef<'tcx> {
-        self.map_bound(|trait_ref| trait_ref.with_self_ty(tcx, self_ty))
-    }
-}
-
-/// Binder is a binder for higher-ranked lifetimes or types. It is part of the
-/// compiler's representation for things like `for<'a> Fn(&'a isize)`
-/// (which would be represented by the type `PolyTraitRef ==
-/// Binder<TraitRef>`). Note that when we instantiate,
-/// erase, or otherwise "discharge" these bound vars, we change the
-/// type from `Binder<T>` to just `T` (see
-/// e.g., `liberate_late_bound_regions`).
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
-pub struct Binder<T>(T);
-
-impl<T> Binder<T> {
-    /// Wraps `value` in a binder, asserting that `value` does not
-    /// contain any bound vars that would be bound by the
-    /// binder. This is commonly used to 'inject' a value T into a
-    /// different binding level.
-    pub fn dummy<'tcx>(value: T) -> Binder<T>
-    where
-        T: TypeFoldable<'tcx>,
-    {
-        debug_assert!(!value.has_escaping_bound_vars());
-        Binder(value)
-    }
-
-    /// Wraps `value` in a binder, binding higher-ranked vars (if any).
-    pub fn bind(value: T) -> Binder<T> {
-        Binder(value)
-    }
-
-    /// Skips the binder and returns the "bound" value. This is a
-    /// risky thing to do because it's easy to get confused about
-    /// De Bruijn indices and the like. It is usually better to
-    /// discharge the binder using `no_bound_vars` or
-    /// `replace_late_bound_regions` or something like
-    /// that. `skip_binder` is only valid when you are either
-    /// extracting data that has nothing to do with bound vars, you
-    /// are doing some sort of test that does not involve bound
-    /// regions, or you are being very careful about your depth
-    /// accounting.
-    ///
-    /// Some examples where `skip_binder` is reasonable:
-    ///
-    /// - extracting the `DefId` from a PolyTraitRef;
-    /// - comparing the self type of a PolyTraitRef to see if it is equal to
-    ///   a type parameter `X`, since the type `X` does not reference any regions
-    pub fn skip_binder(&self) -> &T {
-        &self.0
-    }
-
-    pub fn as_ref(&self) -> Binder<&T> {
-        Binder(&self.0)
-    }
-
-    pub fn map_bound_ref<F, U>(&self, f: F) -> Binder<U>
-    where
-        F: FnOnce(&T) -> U,
-    {
-        self.as_ref().map_bound(f)
-    }
-
-    pub fn map_bound<F, U>(self, f: F) -> Binder<U>
-    where
-        F: FnOnce(T) -> U,
-    {
-        Binder(f(self.0))
-    }
-
-    /// Unwraps and returns the value within, but only if it contains
-    /// no bound vars at all. (In other words, if this binder --
-    /// and indeed any enclosing binder -- doesn't bind anything at
-    /// all.) Otherwise, returns `None`.
-    ///
-    /// (One could imagine having a method that just unwraps a single
-    /// binder, but permits late-bound vars bound by enclosing
-    /// binders, but that would require adjusting the debruijn
-    /// indices, and given the shallow binding structure we often use,
-    /// would not be that useful.)
-    pub fn no_bound_vars<'tcx>(self) -> Option<T>
-    where
-        T: TypeFoldable<'tcx>,
-    {
-        if self.skip_binder().has_escaping_bound_vars() {
-            None
-        } else {
-            Some(self.skip_binder().clone())
-        }
-    }
-
-    /// Given two things that have the same binder level,
-    /// and an operation that wraps on their contents, executes the operation
-    /// and then wraps its result.
-    ///
-    /// `f` should consider bound regions at depth 1 to be free, and
-    /// anything it produces with bound regions at depth 1 will be
-    /// bound in the resulting return value.
-    pub fn fuse<U, F, R>(self, u: Binder<U>, f: F) -> Binder<R>
-    where
-        F: FnOnce(T, U) -> R,
-    {
-        Binder(f(self.0, u.0))
-    }
-
-    /// Splits the contents into two things that share the same binder
-    /// level as the original, returning two distinct binders.
-    ///
-    /// `f` should consider bound regions at depth 1 to be free, and
-    /// anything it produces with bound regions at depth 1 will be
-    /// bound in the resulting return values.
-    pub fn split<U, V, F>(self, f: F) -> (Binder<U>, Binder<V>)
-    where
-        F: FnOnce(T) -> (U, V),
-    {
-        let (u, v) = f(self.0);
-        (Binder(u), Binder(v))
-    }
-}
-
-/// Represents the projection of an associated type. In explicit UFCS
-/// form this would be written `<T as Trait<..>>::N`.
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
-#[derive(HashStable, TypeFoldable)]
-pub struct ProjectionTy<'tcx> {
-    /// The parameters of the associated item.
-    pub substs: SubstsRef<'tcx>,
-
-    /// The `DefId` of the `TraitItem` for the associated type `N`.
-    ///
-    /// Note that this is not the `DefId` of the `TraitRef` containing this
-    /// associated type, which is in `tcx.associated_item(item_def_id).container`.
-    pub item_def_id: DefId,
-}
-
-impl<'tcx> ProjectionTy<'tcx> {
-    /// Construct a `ProjectionTy` by searching the trait from `trait_ref` for the
-    /// associated item named `item_name`.
-    pub fn from_ref_and_name(
-        tcx: TyCtxt<'_>,
-        trait_ref: ty::TraitRef<'tcx>,
-        item_name: Ident,
-    ) -> ProjectionTy<'tcx> {
-        let item_def_id = tcx
-            .associated_items(trait_ref.def_id)
-            .find_by_name_and_kind(tcx, item_name, ty::AssocKind::Type, trait_ref.def_id)
-            .unwrap()
-            .def_id;
-
-        ProjectionTy { substs: trait_ref.substs, item_def_id }
-    }
-
-    /// Extracts the underlying trait reference from this projection.
-    /// For example, if this is a projection of `<T as Iterator>::Item`,
-    /// then this function would return a `T: Iterator` trait reference.
-    pub fn trait_ref(&self, tcx: TyCtxt<'tcx>) -> ty::TraitRef<'tcx> {
-        let def_id = tcx.associated_item(self.item_def_id).container.id();
-        ty::TraitRef { def_id, substs: self.substs.truncate_to(tcx, tcx.generics_of(def_id)) }
-    }
-
-    pub fn self_ty(&self) -> Ty<'tcx> {
-        self.substs.type_at(0)
-    }
-}
-
-#[derive(Clone, Debug, TypeFoldable)]
-pub struct GenSig<'tcx> {
-    pub resume_ty: Ty<'tcx>,
-    pub yield_ty: Ty<'tcx>,
-    pub return_ty: Ty<'tcx>,
-}
-
-pub type PolyGenSig<'tcx> = Binder<GenSig<'tcx>>;
-
-impl<'tcx> PolyGenSig<'tcx> {
-    pub fn resume_ty(&self) -> ty::Binder<Ty<'tcx>> {
-        self.map_bound_ref(|sig| sig.resume_ty)
-    }
-    pub fn yield_ty(&self) -> ty::Binder<Ty<'tcx>> {
-        self.map_bound_ref(|sig| sig.yield_ty)
-    }
-    pub fn return_ty(&self) -> ty::Binder<Ty<'tcx>> {
-        self.map_bound_ref(|sig| sig.return_ty)
-    }
-}
-
-/// Signature of a function type, which we have arbitrarily
-/// decided to use to refer to the input/output types.
-///
-/// - `inputs`: is the list of arguments and their modes.
-/// - `output`: is the return type.
-/// - `c_variadic`: indicates whether this is a C-variadic function.
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
-#[derive(HashStable, TypeFoldable)]
-pub struct FnSig<'tcx> {
-    pub inputs_and_output: &'tcx List<Ty<'tcx>>,
-    pub c_variadic: bool,
-    pub unsafety: hir::Unsafety,
-    pub abi: abi::Abi,
-}
-
-impl<'tcx> FnSig<'tcx> {
-    pub fn inputs(&self) -> &'tcx [Ty<'tcx>] {
-        &self.inputs_and_output[..self.inputs_and_output.len() - 1]
-    }
-
-    pub fn output(&self) -> Ty<'tcx> {
-        self.inputs_and_output[self.inputs_and_output.len() - 1]
-    }
-
-    // Creates a minimal `FnSig` to be used when encountering a `TyKind::Error` in a fallible
-    // method.
-    fn fake() -> FnSig<'tcx> {
-        FnSig {
-            inputs_and_output: List::empty(),
-            c_variadic: false,
-            unsafety: hir::Unsafety::Normal,
-            abi: abi::Abi::Rust,
-        }
-    }
-}
-
-pub type PolyFnSig<'tcx> = Binder<FnSig<'tcx>>;
-
-impl<'tcx> PolyFnSig<'tcx> {
-    #[inline]
-    pub fn inputs(&self) -> Binder<&'tcx [Ty<'tcx>]> {
-        self.map_bound_ref(|fn_sig| fn_sig.inputs())
-    }
-    #[inline]
-    pub fn input(&self, index: usize) -> ty::Binder<Ty<'tcx>> {
-        self.map_bound_ref(|fn_sig| fn_sig.inputs()[index])
-    }
-    pub fn inputs_and_output(&self) -> ty::Binder<&'tcx List<Ty<'tcx>>> {
-        self.map_bound_ref(|fn_sig| fn_sig.inputs_and_output)
-    }
-    #[inline]
-    pub fn output(&self) -> ty::Binder<Ty<'tcx>> {
-        self.map_bound_ref(|fn_sig| fn_sig.output())
-    }
-    pub fn c_variadic(&self) -> bool {
-        self.skip_binder().c_variadic
-    }
-    pub fn unsafety(&self) -> hir::Unsafety {
-        self.skip_binder().unsafety
-    }
-    pub fn abi(&self) -> abi::Abi {
-        self.skip_binder().abi
-    }
-}
-
-pub type CanonicalPolyFnSig<'tcx> = Canonical<'tcx, Binder<FnSig<'tcx>>>;
-
-#[derive(
-    Clone,
-    Copy,
-    PartialEq,
-    Eq,
-    PartialOrd,
-    Ord,
-    Hash,
-    RustcEncodable,
-    RustcDecodable,
-    HashStable
-)]
-pub struct ParamTy {
-    pub index: u32,
-    pub name: Symbol,
-}
-
-impl<'tcx> ParamTy {
-    pub fn new(index: u32, name: Symbol) -> ParamTy {
-        ParamTy { index, name: name }
-    }
-
-    pub fn for_self() -> ParamTy {
-        ParamTy::new(0, kw::SelfUpper)
-    }
-
-    pub fn for_def(def: &ty::GenericParamDef) -> ParamTy {
-        ParamTy::new(def.index, def.name)
-    }
-
-    pub fn to_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
-        tcx.mk_ty_param(self.index, self.name)
-    }
-}
-
-#[derive(
-    Copy,
-    Clone,
-    Hash,
-    RustcEncodable,
-    RustcDecodable,
-    Eq,
-    PartialEq,
-    Ord,
-    PartialOrd,
-    HashStable
-)]
-pub struct ParamConst {
-    pub index: u32,
-    pub name: Symbol,
-}
-
-impl<'tcx> ParamConst {
-    pub fn new(index: u32, name: Symbol) -> ParamConst {
-        ParamConst { index, name }
-    }
-
-    pub fn for_def(def: &ty::GenericParamDef) -> ParamConst {
-        ParamConst::new(def.index, def.name)
-    }
-
-    pub fn to_const(self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> &'tcx Const<'tcx> {
-        tcx.mk_const_param(self.index, self.name, ty)
-    }
-}
-
-rustc_index::newtype_index! {
-    /// A [De Bruijn index][dbi] is a standard means of representing
-    /// regions (and perhaps later types) in a higher-ranked setting. In
-    /// particular, imagine a type like this:
-    ///
-    ///     for<'a> fn(for<'b> fn(&'b isize, &'a isize), &'a char)
-    ///     ^          ^            |        |         |
-    ///     |          |            |        |         |
-    ///     |          +------------+ 0      |         |
-    ///     |                                |         |
-    ///     +--------------------------------+ 1       |
-    ///     |                                          |
-    ///     +------------------------------------------+ 0
-    ///
-    /// In this type, there are two binders (the outer fn and the inner
-    /// fn). We need to be able to determine, for any given region, which
-    /// fn type it is bound by, the inner or the outer one. There are
-    /// various ways you can do this, but a De Bruijn index is one of the
-    /// more convenient and has some nice properties. The basic idea is to
-    /// count the number of binders, inside out. Some examples should help
-    /// clarify what I mean.
-    ///
-    /// Let's start with the reference type `&'b isize` that is the first
-    /// argument to the inner function. This region `'b` is assigned a De
-    /// Bruijn index of 0, meaning "the innermost binder" (in this case, a
-    /// fn). The region `'a` that appears in the second argument type (`&'a
-    /// isize`) would then be assigned a De Bruijn index of 1, meaning "the
-    /// second-innermost binder". (These indices are written on the arrays
-    /// in the diagram).
-    ///
-    /// What is interesting is that De Bruijn index attached to a particular
-    /// variable will vary depending on where it appears. For example,
-    /// the final type `&'a char` also refers to the region `'a` declared on
-    /// the outermost fn. But this time, this reference is not nested within
-    /// any other binders (i.e., it is not an argument to the inner fn, but
-    /// rather the outer one). Therefore, in this case, it is assigned a
-    /// De Bruijn index of 0, because the innermost binder in that location
-    /// is the outer fn.
-    ///
-    /// [dbi]: http://en.wikipedia.org/wiki/De_Bruijn_index
-    #[derive(HashStable)]
-    pub struct DebruijnIndex {
-        DEBUG_FORMAT = "DebruijnIndex({})",
-        const INNERMOST = 0,
-    }
-}
-
-pub type Region<'tcx> = &'tcx RegionKind;
-
-/// Representation of (lexical) regions. Note that the NLL checker
-/// uses a distinct representation of regions. For this reason, it
-/// internally replaces all the regions with inference variables --
-/// the index of the variable is then used to index into internal NLL
-/// data structures. See `rustc_mir::borrow_check` module for more
-/// information.
-///
-/// ## The Region lattice within a given function
-///
-/// In general, the (lexical, and hence deprecated) region lattice
-/// looks like
-///
-/// ```
-/// static ----------+-----...------+       (greatest)
-/// |                |              |
-/// early-bound and  |              |
-/// free regions     |              |
-/// |                |              |
-/// scope regions    |              |
-/// |                |              |
-/// empty(root)   placeholder(U1)   |
-/// |            /                  |
-/// |           /         placeholder(Un)
-/// empty(U1) --         /
-/// |                   /
-/// ...                /
-/// |                 /
-/// empty(Un) --------                      (smallest)
-/// ```
-///
-/// Early-bound/free regions are the named lifetimes in scope from the
-/// function declaration. They have relationships to one another
-/// determined based on the declared relationships from the
-/// function. They all collectively outlive the scope regions. (See
-/// `RegionRelations` type, and particularly
-/// `crate::infer::outlives::free_region_map::FreeRegionMap`.)
-///
-/// The scope regions are related to one another based on the AST
-/// structure. (See `RegionRelations` type, and particularly the
-/// `rustc::middle::region::ScopeTree`.)
-///
-/// Note that inference variables and bound regions are not included
-/// in this diagram. In the case of inference variables, they should
-/// be inferred to some other region from the diagram.  In the case of
-/// bound regions, they are excluded because they don't make sense to
-/// include -- the diagram indicates the relationship between free
-/// regions.
-///
-/// ## Inference variables
-///
-/// During region inference, we sometimes create inference variables,
-/// represented as `ReVar`. These will be inferred by the code in
-/// `infer::lexical_region_resolve` to some free region from the
-/// lattice above (the minimal region that meets the
-/// constraints).
-///
-/// During NLL checking, where regions are defined differently, we
-/// also use `ReVar` -- in that case, the index is used to index into
-/// the NLL region checker's data structures. The variable may in fact
-/// represent either a free region or an inference variable, in that
-/// case.
-///
-/// ## Bound Regions
-///
-/// These are regions that are stored behind a binder and must be substituted
-/// with some concrete region before being used. There are two kind of
-/// bound regions: early-bound, which are bound in an item's `Generics`,
-/// and are substituted by a `InternalSubsts`, and late-bound, which are part of
-/// higher-ranked types (e.g., `for<'a> fn(&'a ())`), and are substituted by
-/// the likes of `liberate_late_bound_regions`. The distinction exists
-/// because higher-ranked lifetimes aren't supported in all places. See [1][2].
-///
-/// Unlike `Param`s, bound regions are not supposed to exist "in the wild"
-/// outside their binder, e.g., in types passed to type inference, and
-/// should first be substituted (by placeholder regions, free regions,
-/// or region variables).
-///
-/// ## Placeholder and Free Regions
-///
-/// One often wants to work with bound regions without knowing their precise
-/// identity. For example, when checking a function, the lifetime of a borrow
-/// can end up being assigned to some region parameter. In these cases,
-/// it must be ensured that bounds on the region can't be accidentally
-/// assumed without being checked.
-///
-/// To do this, we replace the bound regions with placeholder markers,
-/// which don't satisfy any relation not explicitly provided.
-///
-/// There are two kinds of placeholder regions in rustc: `ReFree` and
-/// `RePlaceholder`. When checking an item's body, `ReFree` is supposed
-/// to be used. These also support explicit bounds: both the internally-stored
-/// *scope*, which the region is assumed to outlive, as well as other
-/// relations stored in the `FreeRegionMap`. Note that these relations
-/// aren't checked when you `make_subregion` (or `eq_types`), only by
-/// `resolve_regions_and_report_errors`.
-///
-/// When working with higher-ranked types, some region relations aren't
-/// yet known, so you can't just call `resolve_regions_and_report_errors`.
-/// `RePlaceholder` is designed for this purpose. In these contexts,
-/// there's also the risk that some inference variable laying around will
-/// get unified with your placeholder region: if you want to check whether
-/// `for<'a> Foo<'_>: 'a`, and you substitute your bound region `'a`
-/// with a placeholder region `'%a`, the variable `'_` would just be
-/// instantiated to the placeholder region `'%a`, which is wrong because
-/// the inference variable is supposed to satisfy the relation
-/// *for every value of the placeholder region*. To ensure that doesn't
-/// happen, you can use `leak_check`. This is more clearly explained
-/// by the [rustc guide].
-///
-/// [1]: http://smallcultfollowing.com/babysteps/blog/2013/10/29/intermingled-parameter-lists/
-/// [2]: http://smallcultfollowing.com/babysteps/blog/2013/11/04/intermingled-parameter-lists/
-/// [rustc guide]: https://rust-lang.github.io/rustc-guide/traits/hrtb.html
-#[derive(Clone, PartialEq, Eq, Hash, Copy, RustcEncodable, RustcDecodable, PartialOrd, Ord)]
-pub enum RegionKind {
-    /// Region bound in a type or fn declaration which will be
-    /// substituted 'early' -- that is, at the same time when type
-    /// parameters are substituted.
-    ReEarlyBound(EarlyBoundRegion),
-
-    /// Region bound in a function scope, which will be substituted when the
-    /// function is called.
-    ReLateBound(DebruijnIndex, BoundRegion),
-
-    /// When checking a function body, the types of all arguments and so forth
-    /// that refer to bound region parameters are modified to refer to free
-    /// region parameters.
-    ReFree(FreeRegion),
-
-    /// A concrete region naming some statically determined scope
-    /// (e.g., an expression or sequence of statements) within the
-    /// current function.
-    ReScope(region::Scope),
-
-    /// Static data that has an "infinite" lifetime. Top in the region lattice.
-    ReStatic,
-
-    /// A region variable. Should not exist after typeck.
-    ReVar(RegionVid),
-
-    /// A placeholder region -- basically, the higher-ranked version of `ReFree`.
-    /// Should not exist after typeck.
-    RePlaceholder(ty::PlaceholderRegion),
-
-    /// Empty lifetime is for data that is never accessed.  We tag the
-    /// empty lifetime with a universe -- the idea is that we don't
-    /// want `exists<'a> { forall<'b> { 'b: 'a } }` to be satisfiable.
-    /// Therefore, the `'empty` in a universe `U` is less than all
-    /// regions visible from `U`, but not less than regions not visible
-    /// from `U`.
-    ReEmpty(ty::UniverseIndex),
-
-    /// Erased region, used by trait selection, in MIR and during codegen.
-    ReErased,
-
-    /// These are regions bound in the "defining type" for a
-    /// closure. They are used ONLY as part of the
-    /// `ClosureRegionRequirements` that are produced by MIR borrowck.
-    /// See `ClosureRegionRequirements` for more details.
-    ReClosureBound(RegionVid),
-}
-
-impl<'tcx> rustc_serialize::UseSpecializedDecodable for Region<'tcx> {}
-
-#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug, PartialOrd, Ord)]
-pub struct EarlyBoundRegion {
-    pub def_id: DefId,
-    pub index: u32,
-    pub name: Symbol,
-}
-
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
-pub struct TyVid {
-    pub index: u32,
-}
-
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
-pub struct ConstVid<'tcx> {
-    pub index: u32,
-    pub phantom: PhantomData<&'tcx ()>,
-}
-
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
-pub struct IntVid {
-    pub index: u32,
-}
-
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
-pub struct FloatVid {
-    pub index: u32,
-}
-
-rustc_index::newtype_index! {
-    pub struct RegionVid {
-        DEBUG_FORMAT = custom,
-    }
-}
-
-impl Atom for RegionVid {
-    fn index(self) -> usize {
-        Idx::index(self)
-    }
-}
-
-#[derive(
-    Clone,
-    Copy,
-    PartialEq,
-    Eq,
-    PartialOrd,
-    Ord,
-    Hash,
-    RustcEncodable,
-    RustcDecodable,
-    HashStable
-)]
-pub enum InferTy {
-    TyVar(TyVid),
-    IntVar(IntVid),
-    FloatVar(FloatVid),
-
-    /// A `FreshTy` is one that is generated as a replacement for an
-    /// unbound type variable. This is convenient for caching etc. See
-    /// `infer::freshen` for more details.
-    FreshTy(u32),
-    FreshIntTy(u32),
-    FreshFloatTy(u32),
-}
-
-rustc_index::newtype_index! {
-    pub struct BoundVar { .. }
-}
-
-#[derive(
-    Clone,
-    Copy,
-    PartialEq,
-    Eq,
-    PartialOrd,
-    Ord,
-    Hash,
-    Debug,
-    RustcEncodable,
-    RustcDecodable,
-    HashStable
-)]
-pub struct BoundTy {
-    pub var: BoundVar,
-    pub kind: BoundTyKind,
-}
-
-#[derive(
-    Clone,
-    Copy,
-    PartialEq,
-    Eq,
-    PartialOrd,
-    Ord,
-    Hash,
-    Debug,
-    RustcEncodable,
-    RustcDecodable,
-    HashStable
-)]
-pub enum BoundTyKind {
-    Anon,
-    Param(Symbol),
-}
-
-impl From<BoundVar> for BoundTy {
-    fn from(var: BoundVar) -> Self {
-        BoundTy { var, kind: BoundTyKind::Anon }
-    }
-}
-
-/// A `ProjectionPredicate` for an `ExistentialTraitRef`.
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
-#[derive(HashStable, TypeFoldable)]
-pub struct ExistentialProjection<'tcx> {
-    pub item_def_id: DefId,
-    pub substs: SubstsRef<'tcx>,
-    pub ty: Ty<'tcx>,
-}
-
-pub type PolyExistentialProjection<'tcx> = Binder<ExistentialProjection<'tcx>>;
-
-impl<'tcx> ExistentialProjection<'tcx> {
-    /// Extracts the underlying existential trait reference from this projection.
-    /// For example, if this is a projection of `exists T. <T as Iterator>::Item == X`,
-    /// then this function would return a `exists T. T: Iterator` existential trait
-    /// reference.
-    pub fn trait_ref(&self, tcx: TyCtxt<'_>) -> ty::ExistentialTraitRef<'tcx> {
-        let def_id = tcx.associated_item(self.item_def_id).container.id();
-        ty::ExistentialTraitRef { def_id, substs: self.substs }
-    }
-
-    pub fn with_self_ty(
-        &self,
-        tcx: TyCtxt<'tcx>,
-        self_ty: Ty<'tcx>,
-    ) -> ty::ProjectionPredicate<'tcx> {
-        // otherwise the escaping regions would be captured by the binders
-        debug_assert!(!self_ty.has_escaping_bound_vars());
-
-        ty::ProjectionPredicate {
-            projection_ty: ty::ProjectionTy {
-                item_def_id: self.item_def_id,
-                substs: tcx.mk_substs_trait(self_ty, self.substs),
-            },
-            ty: self.ty,
-        }
-    }
-}
-
-impl<'tcx> PolyExistentialProjection<'tcx> {
-    pub fn with_self_ty(
-        &self,
-        tcx: TyCtxt<'tcx>,
-        self_ty: Ty<'tcx>,
-    ) -> ty::PolyProjectionPredicate<'tcx> {
-        self.map_bound(|p| p.with_self_ty(tcx, self_ty))
-    }
-
-    pub fn item_def_id(&self) -> DefId {
-        return self.skip_binder().item_def_id;
-    }
-}
-
-impl DebruijnIndex {
-    /// Returns the resulting index when this value is moved into
-    /// `amount` number of new binders. So, e.g., if you had
-    ///
-    ///    for<'a> fn(&'a x)
-    ///
-    /// and you wanted to change it to
-    ///
-    ///    for<'a> fn(for<'b> fn(&'a x))
-    ///
-    /// you would need to shift the index for `'a` into a new binder.
-    #[must_use]
-    pub fn shifted_in(self, amount: u32) -> DebruijnIndex {
-        DebruijnIndex::from_u32(self.as_u32() + amount)
-    }
-
-    /// Update this index in place by shifting it "in" through
-    /// `amount` number of binders.
-    pub fn shift_in(&mut self, amount: u32) {
-        *self = self.shifted_in(amount);
-    }
-
-    /// Returns the resulting index when this value is moved out from
-    /// `amount` number of new binders.
-    #[must_use]
-    pub fn shifted_out(self, amount: u32) -> DebruijnIndex {
-        DebruijnIndex::from_u32(self.as_u32() - amount)
-    }
-
-    /// Update in place by shifting out from `amount` binders.
-    pub fn shift_out(&mut self, amount: u32) {
-        *self = self.shifted_out(amount);
-    }
-
-    /// Adjusts any De Bruijn indices so as to make `to_binder` the
-    /// innermost binder. That is, if we have something bound at `to_binder`,
-    /// it will now be bound at INNERMOST. This is an appropriate thing to do
-    /// when moving a region out from inside binders:
-    ///
-    /// ```
-    ///             for<'a>   fn(for<'b>   for<'c>   fn(&'a u32), _)
-    /// // Binder:  D3           D2        D1            ^^
-    /// ```
-    ///
-    /// Here, the region `'a` would have the De Bruijn index D3,
-    /// because it is the bound 3 binders out. However, if we wanted
-    /// to refer to that region `'a` in the second argument (the `_`),
-    /// those two binders would not be in scope. In that case, we
-    /// might invoke `shift_out_to_binder(D3)`. This would adjust the
-    /// De Bruijn index of `'a` to D1 (the innermost binder).
-    ///
-    /// If we invoke `shift_out_to_binder` and the region is in fact
-    /// bound by one of the binders we are shifting out of, that is an
-    /// error (and should fail an assertion failure).
-    pub fn shifted_out_to_binder(self, to_binder: DebruijnIndex) -> Self {
-        self.shifted_out(to_binder.as_u32() - INNERMOST.as_u32())
-    }
-}
-
-/// Region utilities
-impl RegionKind {
-    /// Is this region named by the user?
-    pub fn has_name(&self) -> bool {
-        match *self {
-            RegionKind::ReEarlyBound(ebr) => ebr.has_name(),
-            RegionKind::ReLateBound(_, br) => br.is_named(),
-            RegionKind::ReFree(fr) => fr.bound_region.is_named(),
-            RegionKind::ReScope(..) => false,
-            RegionKind::ReStatic => true,
-            RegionKind::ReVar(..) => false,
-            RegionKind::RePlaceholder(placeholder) => placeholder.name.is_named(),
-            RegionKind::ReEmpty(_) => false,
-            RegionKind::ReErased => false,
-            RegionKind::ReClosureBound(..) => false,
-        }
-    }
-
-    pub fn is_late_bound(&self) -> bool {
-        match *self {
-            ty::ReLateBound(..) => true,
-            _ => false,
-        }
-    }
-
-    pub fn is_placeholder(&self) -> bool {
-        match *self {
-            ty::RePlaceholder(..) => true,
-            _ => false,
-        }
-    }
-
-    pub fn bound_at_or_above_binder(&self, index: DebruijnIndex) -> bool {
-        match *self {
-            ty::ReLateBound(debruijn, _) => debruijn >= index,
-            _ => false,
-        }
-    }
-
-    /// Adjusts any De Bruijn indices so as to make `to_binder` the
-    /// innermost binder. That is, if we have something bound at `to_binder`,
-    /// it will now be bound at INNERMOST. This is an appropriate thing to do
-    /// when moving a region out from inside binders:
-    ///
-    /// ```
-    ///             for<'a>   fn(for<'b>   for<'c>   fn(&'a u32), _)
-    /// // Binder:  D3           D2        D1            ^^
-    /// ```
-    ///
-    /// Here, the region `'a` would have the De Bruijn index D3,
-    /// because it is the bound 3 binders out. However, if we wanted
-    /// to refer to that region `'a` in the second argument (the `_`),
-    /// those two binders would not be in scope. In that case, we
-    /// might invoke `shift_out_to_binder(D3)`. This would adjust the
-    /// De Bruijn index of `'a` to D1 (the innermost binder).
-    ///
-    /// If we invoke `shift_out_to_binder` and the region is in fact
-    /// bound by one of the binders we are shifting out of, that is an
-    /// error (and should fail an assertion failure).
-    pub fn shifted_out_to_binder(&self, to_binder: ty::DebruijnIndex) -> RegionKind {
-        match *self {
-            ty::ReLateBound(debruijn, r) => {
-                ty::ReLateBound(debruijn.shifted_out_to_binder(to_binder), r)
-            }
-            r => r,
-        }
-    }
-
-    pub fn keep_in_local_tcx(&self) -> bool {
-        if let ty::ReVar(..) = self { true } else { false }
-    }
-
-    pub fn type_flags(&self) -> TypeFlags {
-        let mut flags = TypeFlags::empty();
-
-        if self.keep_in_local_tcx() {
-            flags = flags | TypeFlags::KEEP_IN_LOCAL_TCX;
-        }
-
-        match *self {
-            ty::ReVar(..) => {
-                flags = flags | TypeFlags::HAS_FREE_REGIONS;
-                flags = flags | TypeFlags::HAS_RE_INFER;
-            }
-            ty::RePlaceholder(..) => {
-                flags = flags | TypeFlags::HAS_FREE_REGIONS;
-                flags = flags | TypeFlags::HAS_RE_PLACEHOLDER;
-            }
-            ty::ReLateBound(..) => {
-                flags = flags | TypeFlags::HAS_RE_LATE_BOUND;
-            }
-            ty::ReEarlyBound(..) => {
-                flags = flags | TypeFlags::HAS_FREE_REGIONS;
-                flags = flags | TypeFlags::HAS_RE_EARLY_BOUND;
-            }
-            ty::ReEmpty(_) | ty::ReStatic | ty::ReFree { .. } | ty::ReScope { .. } => {
-                flags = flags | TypeFlags::HAS_FREE_REGIONS;
-            }
-            ty::ReErased => {
-                flags = flags | TypeFlags::HAS_RE_ERASED;
-            }
-            ty::ReClosureBound(..) => {
-                flags = flags | TypeFlags::HAS_FREE_REGIONS;
-            }
-        }
-
-        match *self {
-            ty::ReStatic | ty::ReEmpty(_) | ty::ReErased | ty::ReLateBound(..) => (),
-            _ => flags = flags | TypeFlags::HAS_FREE_LOCAL_NAMES,
-        }
-
-        debug!("type_flags({:?}) = {:?}", self, flags);
-
-        flags
-    }
-
-    /// Given an early-bound or free region, returns the `DefId` where it was bound.
-    /// For example, consider the regions in this snippet of code:
-    ///
-    /// ```
-    /// impl<'a> Foo {
-    ///      ^^ -- early bound, declared on an impl
-    ///
-    ///     fn bar<'b, 'c>(x: &self, y: &'b u32, z: &'c u64) where 'static: 'c
-    ///            ^^  ^^     ^ anonymous, late-bound
-    ///            |   early-bound, appears in where-clauses
-    ///            late-bound, appears only in fn args
-    ///     {..}
-    /// }
-    /// ```
-    ///
-    /// Here, `free_region_binding_scope('a)` would return the `DefId`
-    /// of the impl, and for all the other highlighted regions, it
-    /// would return the `DefId` of the function. In other cases (not shown), this
-    /// function might return the `DefId` of a closure.
-    pub fn free_region_binding_scope(&self, tcx: TyCtxt<'_>) -> DefId {
-        match self {
-            ty::ReEarlyBound(br) => tcx.parent(br.def_id).unwrap(),
-            ty::ReFree(fr) => fr.scope,
-            _ => bug!("free_region_binding_scope invoked on inappropriate region: {:?}", self),
-        }
-    }
-}
-
-/// Type utilities
-impl<'tcx> TyS<'tcx> {
-    #[inline]
-    pub fn is_unit(&self) -> bool {
-        match self.kind {
-            Tuple(ref tys) => tys.is_empty(),
-            _ => false,
-        }
-    }
-
-    #[inline]
-    pub fn is_never(&self) -> bool {
-        match self.kind {
-            Never => true,
-            _ => false,
-        }
-    }
-
-    /// Checks whether a type is definitely uninhabited. This is
-    /// conservative: for some types that are uninhabited we return `false`,
-    /// but we only return `true` for types that are definitely uninhabited.
-    /// `ty.conservative_is_privately_uninhabited` implies that any value of type `ty`
-    /// will be `Abi::Uninhabited`. (Note that uninhabited types may have nonzero
-    /// size, to account for partial initialisation. See #49298 for details.)
-    pub fn conservative_is_privately_uninhabited(&self, tcx: TyCtxt<'tcx>) -> bool {
-        // FIXME(varkor): we can make this less conversative by substituting concrete
-        // type arguments.
-        match self.kind {
-            ty::Never => true,
-            ty::Adt(def, _) if def.is_union() => {
-                // For now, `union`s are never considered uninhabited.
-                false
-            }
-            ty::Adt(def, _) => {
-                // Any ADT is uninhabited if either:
-                // (a) It has no variants (i.e. an empty `enum`);
-                // (b) Each of its variants (a single one in the case of a `struct`) has at least
-                //     one uninhabited field.
-                def.variants.iter().all(|var| {
-                    var.fields.iter().any(|field| {
-                        tcx.type_of(field.did).conservative_is_privately_uninhabited(tcx)
-                    })
-                })
-            }
-            ty::Tuple(..) => {
-                self.tuple_fields().any(|ty| ty.conservative_is_privately_uninhabited(tcx))
-            }
-            ty::Array(ty, len) => {
-                match len.try_eval_usize(tcx, ParamEnv::empty()) {
-                    // If the array is definitely non-empty, it's uninhabited if
-                    // the type of its elements is uninhabited.
-                    Some(n) if n != 0 => ty.conservative_is_privately_uninhabited(tcx),
-                    _ => false,
-                }
-            }
-            ty::Ref(..) => {
-                // References to uninitialised memory is valid for any type, including
-                // uninhabited types, in unsafe code, so we treat all references as
-                // inhabited.
-                false
-            }
-            _ => false,
-        }
-    }
-
-    #[inline]
-    pub fn is_primitive(&self) -> bool {
-        match self.kind {
-            Bool | Char | Int(_) | Uint(_) | Float(_) => true,
-            _ => false,
-        }
-    }
-
-    #[inline]
-    pub fn is_ty_var(&self) -> bool {
-        match self.kind {
-            Infer(TyVar(_)) => true,
-            _ => false,
-        }
-    }
-
-    #[inline]
-    pub fn is_ty_infer(&self) -> bool {
-        match self.kind {
-            Infer(_) => true,
-            _ => false,
-        }
-    }
-
-    #[inline]
-    pub fn is_phantom_data(&self) -> bool {
-        if let Adt(def, _) = self.kind { def.is_phantom_data() } else { false }
-    }
-
-    #[inline]
-    pub fn is_bool(&self) -> bool {
-        self.kind == Bool
-    }
-
-    /// Returns `true` if this type is a `str`.
-    #[inline]
-    pub fn is_str(&self) -> bool {
-        self.kind == Str
-    }
-
-    #[inline]
-    pub fn is_param(&self, index: u32) -> bool {
-        match self.kind {
-            ty::Param(ref data) => data.index == index,
-            _ => false,
-        }
-    }
-
-    #[inline]
-    pub fn is_slice(&self) -> bool {
-        match self.kind {
-            RawPtr(TypeAndMut { ty, .. }) | Ref(_, ty, _) => match ty.kind {
-                Slice(_) | Str => true,
-                _ => false,
-            },
-            _ => false,
-        }
-    }
-
-    #[inline]
-    pub fn is_simd(&self) -> bool {
-        match self.kind {
-            Adt(def, _) => def.repr.simd(),
-            _ => false,
-        }
-    }
-
-    pub fn sequence_element_type(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
-        match self.kind {
-            Array(ty, _) | Slice(ty) => ty,
-            Str => tcx.mk_mach_uint(ast::UintTy::U8),
-            _ => bug!("`sequence_element_type` called on non-sequence value: {}", self),
-        }
-    }
-
-    pub fn simd_type(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
-        match self.kind {
-            Adt(def, substs) => def.non_enum_variant().fields[0].ty(tcx, substs),
-            _ => bug!("`simd_type` called on invalid type"),
-        }
-    }
-
-    pub fn simd_size(&self, _tcx: TyCtxt<'tcx>) -> u64 {
-        // Parameter currently unused, but probably needed in the future to
-        // allow `#[repr(simd)] struct Simd<T, const N: usize>([T; N]);`.
-        match self.kind {
-            Adt(def, _) => def.non_enum_variant().fields.len() as u64,
-            _ => bug!("`simd_size` called on invalid type"),
-        }
-    }
-
-    pub fn simd_size_and_type(&self, tcx: TyCtxt<'tcx>) -> (u64, Ty<'tcx>) {
-        match self.kind {
-            Adt(def, substs) => {
-                let variant = def.non_enum_variant();
-                (variant.fields.len() as u64, variant.fields[0].ty(tcx, substs))
-            }
-            _ => bug!("`simd_size_and_type` called on invalid type"),
-        }
-    }
-
-    #[inline]
-    pub fn is_region_ptr(&self) -> bool {
-        match self.kind {
-            Ref(..) => true,
-            _ => false,
-        }
-    }
-
-    #[inline]
-    pub fn is_mutable_ptr(&self) -> bool {
-        match self.kind {
-            RawPtr(TypeAndMut { mutbl: hir::Mutability::Mut, .. })
-            | Ref(_, _, hir::Mutability::Mut) => true,
-            _ => false,
-        }
-    }
-
-    #[inline]
-    pub fn is_unsafe_ptr(&self) -> bool {
-        match self.kind {
-            RawPtr(_) => return true,
-            _ => return false,
-        }
-    }
-
-    /// Tests if this is any kind of primitive pointer type (reference, raw pointer, fn pointer).
-    #[inline]
-    pub fn is_any_ptr(&self) -> bool {
-        self.is_region_ptr() || self.is_unsafe_ptr() || self.is_fn_ptr()
-    }
-
-    /// Returns `true` if this type is an `Arc<T>`.
-    #[inline]
-    pub fn is_arc(&self) -> bool {
-        match self.kind {
-            Adt(def, _) => def.is_arc(),
-            _ => false,
-        }
-    }
-
-    /// Returns `true` if this type is an `Rc<T>`.
-    #[inline]
-    pub fn is_rc(&self) -> bool {
-        match self.kind {
-            Adt(def, _) => def.is_rc(),
-            _ => false,
-        }
-    }
-
-    #[inline]
-    pub fn is_box(&self) -> bool {
-        match self.kind {
-            Adt(def, _) => def.is_box(),
-            _ => false,
-        }
-    }
-
-    /// Panics if called on any type other than `Box<T>`.
-    pub fn boxed_ty(&self) -> Ty<'tcx> {
-        match self.kind {
-            Adt(def, substs) if def.is_box() => substs.type_at(0),
-            _ => bug!("`boxed_ty` is called on non-box type {:?}", self),
-        }
-    }
-
-    /// A scalar type is one that denotes an atomic datum, with no sub-components.
-    /// (A RawPtr is scalar because it represents a non-managed pointer, so its
-    /// contents are abstract to rustc.)
-    #[inline]
-    pub fn is_scalar(&self) -> bool {
-        match self.kind {
-            Bool | Char | Int(_) | Float(_) | Uint(_) | Infer(IntVar(_)) | Infer(FloatVar(_))
-            | FnDef(..) | FnPtr(_) | RawPtr(_) => true,
-            _ => false,
-        }
-    }
-
-    /// Returns `true` if this type is a floating point type.
-    #[inline]
-    pub fn is_floating_point(&self) -> bool {
-        match self.kind {
-            Float(_) | Infer(FloatVar(_)) => true,
-            _ => false,
-        }
-    }
-
-    #[inline]
-    pub fn is_trait(&self) -> bool {
-        match self.kind {
-            Dynamic(..) => true,
-            _ => false,
-        }
-    }
-
-    #[inline]
-    pub fn is_enum(&self) -> bool {
-        match self.kind {
-            Adt(adt_def, _) => adt_def.is_enum(),
-            _ => false,
-        }
-    }
-
-    #[inline]
-    pub fn is_closure(&self) -> bool {
-        match self.kind {
-            Closure(..) => true,
-            _ => false,
-        }
-    }
-
-    #[inline]
-    pub fn is_generator(&self) -> bool {
-        match self.kind {
-            Generator(..) => true,
-            _ => false,
-        }
-    }
-
-    #[inline]
-    pub fn is_integral(&self) -> bool {
-        match self.kind {
-            Infer(IntVar(_)) | Int(_) | Uint(_) => true,
-            _ => false,
-        }
-    }
-
-    #[inline]
-    pub fn is_fresh_ty(&self) -> bool {
-        match self.kind {
-            Infer(FreshTy(_)) => true,
-            _ => false,
-        }
-    }
-
-    #[inline]
-    pub fn is_fresh(&self) -> bool {
-        match self.kind {
-            Infer(FreshTy(_)) => true,
-            Infer(FreshIntTy(_)) => true,
-            Infer(FreshFloatTy(_)) => true,
-            _ => false,
-        }
-    }
-
-    #[inline]
-    pub fn is_char(&self) -> bool {
-        match self.kind {
-            Char => true,
-            _ => false,
-        }
-    }
-
-    #[inline]
-    pub fn is_numeric(&self) -> bool {
-        self.is_integral() || self.is_floating_point()
-    }
-
-    #[inline]
-    pub fn is_signed(&self) -> bool {
-        match self.kind {
-            Int(_) => true,
-            _ => false,
-        }
-    }
-
-    #[inline]
-    pub fn is_ptr_sized_integral(&self) -> bool {
-        match self.kind {
-            Int(ast::IntTy::Isize) | Uint(ast::UintTy::Usize) => true,
-            _ => false,
-        }
-    }
-
-    #[inline]
-    pub fn is_machine(&self) -> bool {
-        match self.kind {
-            Int(..) | Uint(..) | Float(..) => true,
-            _ => false,
-        }
-    }
-
-    #[inline]
-    pub fn has_concrete_skeleton(&self) -> bool {
-        match self.kind {
-            Param(_) | Infer(_) | Error => false,
-            _ => true,
-        }
-    }
-
-    /// Returns the type and mutability of `*ty`.
-    ///
-    /// The parameter `explicit` indicates if this is an *explicit* dereference.
-    /// Some types -- notably unsafe ptrs -- can only be dereferenced explicitly.
-    pub fn builtin_deref(&self, explicit: bool) -> Option<TypeAndMut<'tcx>> {
-        match self.kind {
-            Adt(def, _) if def.is_box() => {
-                Some(TypeAndMut { ty: self.boxed_ty(), mutbl: hir::Mutability::Not })
-            }
-            Ref(_, ty, mutbl) => Some(TypeAndMut { ty, mutbl }),
-            RawPtr(mt) if explicit => Some(mt),
-            _ => None,
-        }
-    }
-
-    /// Returns the type of `ty[i]`.
-    pub fn builtin_index(&self) -> Option<Ty<'tcx>> {
-        match self.kind {
-            Array(ty, _) | Slice(ty) => Some(ty),
-            _ => None,
-        }
-    }
-
-    pub fn fn_sig(&self, tcx: TyCtxt<'tcx>) -> PolyFnSig<'tcx> {
-        match self.kind {
-            FnDef(def_id, substs) => tcx.fn_sig(def_id).subst(tcx, substs),
-            FnPtr(f) => f,
-            Error => {
-                // ignore errors (#54954)
-                ty::Binder::dummy(FnSig::fake())
-            }
-            Closure(..) => {
-                bug!("to get the signature of a closure, use `closure_sig()` not `fn_sig()`",)
-            }
-            _ => bug!("Ty::fn_sig() called on non-fn type: {:?}", self),
-        }
-    }
-
-    #[inline]
-    pub fn is_fn(&self) -> bool {
-        match self.kind {
-            FnDef(..) | FnPtr(_) => true,
-            _ => false,
-        }
-    }
-
-    #[inline]
-    pub fn is_fn_ptr(&self) -> bool {
-        match self.kind {
-            FnPtr(_) => true,
-            _ => false,
-        }
-    }
-
-    #[inline]
-    pub fn is_impl_trait(&self) -> bool {
-        match self.kind {
-            Opaque(..) => true,
-            _ => false,
-        }
-    }
-
-    #[inline]
-    pub fn ty_adt_def(&self) -> Option<&'tcx AdtDef> {
-        match self.kind {
-            Adt(adt, _) => Some(adt),
-            _ => None,
-        }
-    }
-
-    /// Iterates over tuple fields.
-    /// Panics when called on anything but a tuple.
-    pub fn tuple_fields(&self) -> impl DoubleEndedIterator<Item = Ty<'tcx>> {
-        match self.kind {
-            Tuple(substs) => substs.iter().map(|field| field.expect_ty()),
-            _ => bug!("tuple_fields called on non-tuple"),
-        }
-    }
-
-    /// If the type contains variants, returns the valid range of variant indices.
-    //
-    // FIXME: This requires the optimized MIR in the case of generators.
-    #[inline]
-    pub fn variant_range(&self, tcx: TyCtxt<'tcx>) -> Option<Range<VariantIdx>> {
-        match self.kind {
-            TyKind::Adt(adt, _) => Some(adt.variant_range()),
-            TyKind::Generator(def_id, substs, _) => {
-                Some(substs.as_generator().variant_range(def_id, tcx))
-            }
-            _ => None,
-        }
-    }
-
-    /// If the type contains variants, returns the variant for `variant_index`.
-    /// Panics if `variant_index` is out of range.
-    //
-    // FIXME: This requires the optimized MIR in the case of generators.
-    #[inline]
-    pub fn discriminant_for_variant(
-        &self,
-        tcx: TyCtxt<'tcx>,
-        variant_index: VariantIdx,
-    ) -> Option<Discr<'tcx>> {
-        match self.kind {
-            TyKind::Adt(adt, _) => Some(adt.discriminant_for_variant(tcx, variant_index)),
-            TyKind::Generator(def_id, substs, _) => {
-                Some(substs.as_generator().discriminant_for_variant(def_id, tcx, variant_index))
-            }
-            _ => None,
-        }
-    }
-
-    /// Pushes onto `out` the regions directly referenced from this type (but not
-    /// types reachable from this type via `walk_tys`). This ignores late-bound
-    /// regions binders.
-    pub fn push_regions(&self, out: &mut SmallVec<[ty::Region<'tcx>; 4]>) {
-        match self.kind {
-            Ref(region, _, _) => {
-                out.push(region);
-            }
-            Dynamic(ref obj, region) => {
-                out.push(region);
-                if let Some(principal) = obj.principal() {
-                    out.extend(principal.skip_binder().substs.regions());
-                }
-            }
-            Adt(_, substs) | Opaque(_, substs) => out.extend(substs.regions()),
-            Closure(_, ref substs) | Generator(_, ref substs, _) => out.extend(substs.regions()),
-            Projection(ref data) | UnnormalizedProjection(ref data) => {
-                out.extend(data.substs.regions())
-            }
-            FnDef(..) | FnPtr(_) | GeneratorWitness(..) | Bool | Char | Int(_) | Uint(_)
-            | Float(_) | Str | Array(..) | Slice(_) | RawPtr(_) | Never | Tuple(..)
-            | Foreign(..) | Param(_) | Bound(..) | Placeholder(..) | Infer(_) | Error => {}
-        }
-    }
-
-    /// When we create a closure, we record its kind (i.e., what trait
-    /// it implements) into its `ClosureSubsts` using a type
-    /// parameter. This is kind of a phantom type, except that the
-    /// most convenient thing for us to are the integral types. This
-    /// function converts such a special type into the closure
-    /// kind. To go the other way, use
-    /// `tcx.closure_kind_ty(closure_kind)`.
-    ///
-    /// Note that during type checking, we use an inference variable
-    /// to represent the closure kind, because it has not yet been
-    /// inferred. Once upvar inference (in `src/librustc_typeck/check/upvar.rs`)
-    /// is complete, that type variable will be unified.
-    pub fn to_opt_closure_kind(&self) -> Option<ty::ClosureKind> {
-        match self.kind {
-            Int(int_ty) => match int_ty {
-                ast::IntTy::I8 => Some(ty::ClosureKind::Fn),
-                ast::IntTy::I16 => Some(ty::ClosureKind::FnMut),
-                ast::IntTy::I32 => Some(ty::ClosureKind::FnOnce),
-                _ => bug!("cannot convert type `{:?}` to a closure kind", self),
-            },
-
-            // "Bound" types appear in canonical queries when the
-            // closure type is not yet known
-            Bound(..) | Infer(_) => None,
-
-            Error => Some(ty::ClosureKind::Fn),
-
-            _ => bug!("cannot convert type `{:?}` to a closure kind", self),
-        }
-    }
-
-    /// Fast path helper for testing if a type is `Sized`.
-    ///
-    /// Returning true means the type is known to be sized. Returning
-    /// `false` means nothing -- could be sized, might not be.
-    pub fn is_trivially_sized(&self, tcx: TyCtxt<'tcx>) -> bool {
-        match self.kind {
-            ty::Infer(ty::IntVar(_))
-            | ty::Infer(ty::FloatVar(_))
-            | ty::Uint(_)
-            | ty::Int(_)
-            | ty::Bool
-            | ty::Float(_)
-            | ty::FnDef(..)
-            | ty::FnPtr(_)
-            | ty::RawPtr(..)
-            | ty::Char
-            | ty::Ref(..)
-            | ty::Generator(..)
-            | ty::GeneratorWitness(..)
-            | ty::Array(..)
-            | ty::Closure(..)
-            | ty::Never
-            | ty::Error => true,
-
-            ty::Str | ty::Slice(_) | ty::Dynamic(..) | ty::Foreign(..) => false,
-
-            ty::Tuple(tys) => tys.iter().all(|ty| ty.expect_ty().is_trivially_sized(tcx)),
-
-            ty::Adt(def, _substs) => def.sized_constraint(tcx).is_empty(),
-
-            ty::Projection(_) | ty::Param(_) | ty::Opaque(..) => false,
-
-            ty::UnnormalizedProjection(..) => bug!("only used with chalk-engine"),
-
-            ty::Infer(ty::TyVar(_)) => false,
-
-            ty::Bound(..)
-            | ty::Placeholder(..)
-            | ty::Infer(ty::FreshTy(_))
-            | ty::Infer(ty::FreshIntTy(_))
-            | ty::Infer(ty::FreshFloatTy(_)) => {
-                bug!("`is_trivially_sized` applied to unexpected type: {:?}", self)
-            }
-        }
-    }
-}
-
-/// Typed constant value.
-#[derive(
-    Copy,
-    Clone,
-    Debug,
-    Hash,
-    RustcEncodable,
-    RustcDecodable,
-    Eq,
-    PartialEq,
-    Ord,
-    PartialOrd,
-    HashStable
-)]
-pub struct Const<'tcx> {
-    pub ty: Ty<'tcx>,
-
-    pub val: ConstKind<'tcx>,
-}
-
-#[cfg(target_arch = "x86_64")]
-static_assert_size!(Const<'_>, 48);
-
-impl<'tcx> Const<'tcx> {
-    #[inline]
-    pub fn from_value(tcx: TyCtxt<'tcx>, val: ConstValue<'tcx>, ty: Ty<'tcx>) -> &'tcx Self {
-        tcx.mk_const(Self { val: ConstKind::Value(val), ty })
-    }
-
-    #[inline]
-    pub fn from_scalar(tcx: TyCtxt<'tcx>, val: Scalar, ty: Ty<'tcx>) -> &'tcx Self {
-        Self::from_value(tcx, ConstValue::Scalar(val), ty)
-    }
-
-    #[inline]
-    pub fn from_bits(tcx: TyCtxt<'tcx>, bits: u128, ty: ParamEnvAnd<'tcx, Ty<'tcx>>) -> &'tcx Self {
-        let size = tcx
-            .layout_of(ty)
-            .unwrap_or_else(|e| panic!("could not compute layout for {:?}: {:?}", ty, e))
-            .size;
-        Self::from_scalar(tcx, Scalar::from_uint(bits, size), ty.value)
-    }
-
-    #[inline]
-    pub fn zero_sized(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> &'tcx Self {
-        Self::from_scalar(tcx, Scalar::zst(), ty)
-    }
-
-    #[inline]
-    pub fn from_bool(tcx: TyCtxt<'tcx>, v: bool) -> &'tcx Self {
-        Self::from_bits(tcx, v as u128, ParamEnv::empty().and(tcx.types.bool))
-    }
-
-    #[inline]
-    pub fn from_usize(tcx: TyCtxt<'tcx>, n: u64) -> &'tcx Self {
-        Self::from_bits(tcx, n as u128, ParamEnv::empty().and(tcx.types.usize))
-    }
-
-    #[inline]
-    pub fn try_eval_bits(
-        &self,
-        tcx: TyCtxt<'tcx>,
-        param_env: ParamEnv<'tcx>,
-        ty: Ty<'tcx>,
-    ) -> Option<u128> {
-        assert_eq!(self.ty, ty);
-        let size = tcx.layout_of(param_env.with_reveal_all().and(ty)).ok()?.size;
-        // if `ty` does not depend on generic parameters, use an empty param_env
-        self.eval(tcx, param_env).val.try_to_bits(size)
-    }
-
-    #[inline]
-    pub fn eval(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> &Const<'tcx> {
-        let try_const_eval = |did, param_env: ParamEnv<'tcx>, substs, promoted| {
-            let param_env_and_substs = param_env.with_reveal_all().and(substs);
-
-            // Avoid querying `tcx.const_eval(...)` with any e.g. inference vars.
-            if param_env_and_substs.has_local_value() {
-                return None;
-            }
-
-            let (param_env, substs) = param_env_and_substs.into_parts();
-
-            // try to resolve e.g. associated constants to their definition on an impl, and then
-            // evaluate the const.
-            tcx.const_eval_resolve(param_env, did, substs, promoted, None)
-                .ok()
-                .map(|val| Const::from_value(tcx, val, self.ty))
-        };
-
-        match self.val {
-            ConstKind::Unevaluated(did, substs, promoted) => {
-                // HACK(eddyb) when substs contain e.g. inference variables,
-                // attempt using identity substs instead, that will succeed
-                // when the expression doesn't depend on any parameters.
-                // FIXME(eddyb) make `const_eval` a canonical query instead,
-                // that would properly handle inference variables in `substs`.
-                if substs.has_local_value() {
-                    let identity_substs = InternalSubsts::identity_for_item(tcx, did);
-                    // The `ParamEnv` needs to match the `identity_substs`.
-                    let identity_param_env = tcx.param_env(did);
-                    match try_const_eval(did, identity_param_env, identity_substs, promoted) {
-                        Some(ct) => ct.subst(tcx, substs),
-                        None => self,
-                    }
-                } else {
-                    try_const_eval(did, param_env, substs, promoted).unwrap_or(self)
-                }
-            }
-            _ => self,
-        }
-    }
-
-    #[inline]
-    pub fn try_eval_bool(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Option<bool> {
-        self.try_eval_bits(tcx, param_env, tcx.types.bool).and_then(|v| match v {
-            0 => Some(false),
-            1 => Some(true),
-            _ => None,
-        })
-    }
-
-    #[inline]
-    pub fn try_eval_usize(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Option<u64> {
-        self.try_eval_bits(tcx, param_env, tcx.types.usize).map(|v| v as u64)
-    }
-
-    #[inline]
-    pub fn eval_bits(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ty: Ty<'tcx>) -> u128 {
-        self.try_eval_bits(tcx, param_env, ty)
-            .unwrap_or_else(|| bug!("expected bits of {:#?}, got {:#?}", ty, self))
-    }
-
-    #[inline]
-    pub fn eval_usize(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> u64 {
-        self.eval_bits(tcx, param_env, tcx.types.usize) as u64
-    }
-}
-
-impl<'tcx> rustc_serialize::UseSpecializedDecodable for &'tcx Const<'tcx> {}
-
-/// Represents a constant in Rust.
-#[derive(
-    Copy,
-    Clone,
-    Debug,
-    Eq,
-    PartialEq,
-    PartialOrd,
-    Ord,
-    RustcEncodable,
-    RustcDecodable,
-    Hash,
-    HashStable
-)]
-pub enum ConstKind<'tcx> {
-    /// A const generic parameter.
-    Param(ParamConst),
-
-    /// Infer the value of the const.
-    Infer(InferConst<'tcx>),
-
-    /// Bound const variable, used only when preparing a trait query.
-    Bound(DebruijnIndex, BoundVar),
-
-    /// A placeholder const - universally quantified higher-ranked const.
-    Placeholder(ty::PlaceholderConst),
-
-    /// Used in the HIR by using `Unevaluated` everywhere and later normalizing to one of the other
-    /// variants when the code is monomorphic enough for that.
-    Unevaluated(DefId, SubstsRef<'tcx>, Option<Promoted>),
-
-    /// Used to hold computed value.
-    Value(ConstValue<'tcx>),
-}
-
-#[cfg(target_arch = "x86_64")]
-static_assert_size!(ConstKind<'_>, 40);
-
-impl<'tcx> ConstKind<'tcx> {
-    #[inline]
-    pub fn try_to_scalar(&self) -> Option<Scalar> {
-        if let ConstKind::Value(val) = self { val.try_to_scalar() } else { None }
-    }
-
-    #[inline]
-    pub fn try_to_bits(&self, size: ty::layout::Size) -> Option<u128> {
-        self.try_to_scalar()?.to_bits(size).ok()
-    }
-}
-
-/// An inference variable for a const, for use in const generics.
-#[derive(
-    Copy,
-    Clone,
-    Debug,
-    Eq,
-    PartialEq,
-    PartialOrd,
-    Ord,
-    RustcEncodable,
-    RustcDecodable,
-    Hash,
-    HashStable
-)]
-pub enum InferConst<'tcx> {
-    /// Infer the value of the const.
-    Var(ConstVid<'tcx>),
-    /// A fresh const variable. See `infer::freshen` for more details.
-    Fresh(u32),
-}
diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs
deleted file mode 100644
index a0055812835..00000000000
--- a/src/librustc/ty/subst.rs
+++ /dev/null
@@ -1,724 +0,0 @@
-// Type substitutions.
-
-use crate::infer::canonical::Canonical;
-use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
-use crate::ty::sty::{ClosureSubsts, GeneratorSubsts};
-use crate::ty::{self, Lift, List, ParamConst, Ty, TyCtxt};
-
-use rustc_hir::def_id::DefId;
-use rustc_macros::HashStable;
-use rustc_serialize::{self, Decodable, Decoder, Encodable, Encoder};
-use rustc_span::{Span, DUMMY_SP};
-use smallvec::SmallVec;
-
-use core::intrinsics;
-use std::cmp::Ordering;
-use std::fmt;
-use std::marker::PhantomData;
-use std::mem;
-use std::num::NonZeroUsize;
-
-/// An entity in the Rust type system, which can be one of
-/// several kinds (types, lifetimes, and consts).
-/// To reduce memory usage, a `GenericArg` is a interned pointer,
-/// with the lowest 2 bits being reserved for a tag to
-/// indicate the type (`Ty`, `Region`, or `Const`) it points to.
-#[derive(Copy, Clone, PartialEq, Eq, Hash)]
-pub struct GenericArg<'tcx> {
-    ptr: NonZeroUsize,
-    marker: PhantomData<(Ty<'tcx>, ty::Region<'tcx>, &'tcx ty::Const<'tcx>)>,
-}
-
-const TAG_MASK: usize = 0b11;
-const TYPE_TAG: usize = 0b00;
-const REGION_TAG: usize = 0b01;
-const CONST_TAG: usize = 0b10;
-
-#[derive(Debug, RustcEncodable, RustcDecodable, PartialEq, Eq, PartialOrd, Ord, HashStable)]
-pub enum GenericArgKind<'tcx> {
-    Lifetime(ty::Region<'tcx>),
-    Type(Ty<'tcx>),
-    Const(&'tcx ty::Const<'tcx>),
-}
-
-impl<'tcx> GenericArgKind<'tcx> {
-    fn pack(self) -> GenericArg<'tcx> {
-        let (tag, ptr) = match self {
-            GenericArgKind::Lifetime(lt) => {
-                // Ensure we can use the tag bits.
-                assert_eq!(mem::align_of_val(lt) & TAG_MASK, 0);
-                (REGION_TAG, lt as *const _ as usize)
-            }
-            GenericArgKind::Type(ty) => {
-                // Ensure we can use the tag bits.
-                assert_eq!(mem::align_of_val(ty) & TAG_MASK, 0);
-                (TYPE_TAG, ty as *const _ as usize)
-            }
-            GenericArgKind::Const(ct) => {
-                // Ensure we can use the tag bits.
-                assert_eq!(mem::align_of_val(ct) & TAG_MASK, 0);
-                (CONST_TAG, ct as *const _ as usize)
-            }
-        };
-
-        GenericArg { ptr: unsafe { NonZeroUsize::new_unchecked(ptr | tag) }, marker: PhantomData }
-    }
-}
-
-impl fmt::Debug for GenericArg<'tcx> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match self.unpack() {
-            GenericArgKind::Lifetime(lt) => lt.fmt(f),
-            GenericArgKind::Type(ty) => ty.fmt(f),
-            GenericArgKind::Const(ct) => ct.fmt(f),
-        }
-    }
-}
-
-impl<'tcx> Ord for GenericArg<'tcx> {
-    fn cmp(&self, other: &GenericArg<'_>) -> Ordering {
-        self.unpack().cmp(&other.unpack())
-    }
-}
-
-impl<'tcx> PartialOrd for GenericArg<'tcx> {
-    fn partial_cmp(&self, other: &GenericArg<'_>) -> Option<Ordering> {
-        Some(self.cmp(&other))
-    }
-}
-
-impl<'tcx> From<ty::Region<'tcx>> for GenericArg<'tcx> {
-    fn from(r: ty::Region<'tcx>) -> GenericArg<'tcx> {
-        GenericArgKind::Lifetime(r).pack()
-    }
-}
-
-impl<'tcx> From<Ty<'tcx>> for GenericArg<'tcx> {
-    fn from(ty: Ty<'tcx>) -> GenericArg<'tcx> {
-        GenericArgKind::Type(ty).pack()
-    }
-}
-
-impl<'tcx> From<&'tcx ty::Const<'tcx>> for GenericArg<'tcx> {
-    fn from(c: &'tcx ty::Const<'tcx>) -> GenericArg<'tcx> {
-        GenericArgKind::Const(c).pack()
-    }
-}
-
-impl<'tcx> GenericArg<'tcx> {
-    #[inline]
-    pub fn unpack(self) -> GenericArgKind<'tcx> {
-        let ptr = self.ptr.get();
-        unsafe {
-            match ptr & TAG_MASK {
-                REGION_TAG => GenericArgKind::Lifetime(&*((ptr & !TAG_MASK) as *const _)),
-                TYPE_TAG => GenericArgKind::Type(&*((ptr & !TAG_MASK) as *const _)),
-                CONST_TAG => GenericArgKind::Const(&*((ptr & !TAG_MASK) as *const _)),
-                _ => intrinsics::unreachable(),
-            }
-        }
-    }
-
-    /// Unpack the `GenericArg` as a type when it is known certainly to be a type.
-    /// This is true in cases where `Substs` is used in places where the kinds are known
-    /// to be limited (e.g. in tuples, where the only parameters are type parameters).
-    pub fn expect_ty(self) -> Ty<'tcx> {
-        match self.unpack() {
-            GenericArgKind::Type(ty) => ty,
-            _ => bug!("expected a type, but found another kind"),
-        }
-    }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for GenericArg<'a> {
-    type Lifted = GenericArg<'tcx>;
-
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        match self.unpack() {
-            GenericArgKind::Lifetime(lt) => tcx.lift(&lt).map(|lt| lt.into()),
-            GenericArgKind::Type(ty) => tcx.lift(&ty).map(|ty| ty.into()),
-            GenericArgKind::Const(ct) => tcx.lift(&ct).map(|ct| ct.into()),
-        }
-    }
-}
-
-impl<'tcx> TypeFoldable<'tcx> for GenericArg<'tcx> {
-    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
-        match self.unpack() {
-            GenericArgKind::Lifetime(lt) => lt.fold_with(folder).into(),
-            GenericArgKind::Type(ty) => ty.fold_with(folder).into(),
-            GenericArgKind::Const(ct) => ct.fold_with(folder).into(),
-        }
-    }
-
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
-        match self.unpack() {
-            GenericArgKind::Lifetime(lt) => lt.visit_with(visitor),
-            GenericArgKind::Type(ty) => ty.visit_with(visitor),
-            GenericArgKind::Const(ct) => ct.visit_with(visitor),
-        }
-    }
-}
-
-impl<'tcx> Encodable for GenericArg<'tcx> {
-    fn encode<E: Encoder>(&self, e: &mut E) -> Result<(), E::Error> {
-        self.unpack().encode(e)
-    }
-}
-
-impl<'tcx> Decodable for GenericArg<'tcx> {
-    fn decode<D: Decoder>(d: &mut D) -> Result<GenericArg<'tcx>, D::Error> {
-        Ok(GenericArgKind::decode(d)?.pack())
-    }
-}
-
-/// A substitution mapping generic parameters to new values.
-pub type InternalSubsts<'tcx> = List<GenericArg<'tcx>>;
-
-pub type SubstsRef<'tcx> = &'tcx InternalSubsts<'tcx>;
-
-impl<'a, 'tcx> InternalSubsts<'tcx> {
-    /// Interpret these substitutions as the substitutions of a closure type.
-    /// Closure substitutions have a particular structure controlled by the
-    /// compiler that encodes information like the signature and closure kind;
-    /// see `ty::ClosureSubsts` struct for more comments.
-    pub fn as_closure(&'a self) -> ClosureSubsts<'a> {
-        ClosureSubsts { substs: self }
-    }
-
-    /// Interpret these substitutions as the substitutions of a generator type.
-    /// Closure substitutions have a particular structure controlled by the
-    /// compiler that encodes information like the signature and generator kind;
-    /// see `ty::GeneratorSubsts` struct for more comments.
-    pub fn as_generator(&'tcx self) -> GeneratorSubsts<'tcx> {
-        GeneratorSubsts { substs: self }
-    }
-
-    /// Creates a `InternalSubsts` that maps each generic parameter to itself.
-    pub fn identity_for_item(tcx: TyCtxt<'tcx>, def_id: DefId) -> SubstsRef<'tcx> {
-        Self::for_item(tcx, def_id, |param, _| tcx.mk_param_from_def(param))
-    }
-
-    /// Creates a `InternalSubsts` that maps each generic parameter to a higher-ranked
-    /// var bound at index `0`. For types, we use a `BoundVar` index equal to
-    /// the type parameter index. For regions, we use the `BoundRegion::BrNamed`
-    /// variant (which has a `DefId`).
-    pub fn bound_vars_for_item(tcx: TyCtxt<'tcx>, def_id: DefId) -> SubstsRef<'tcx> {
-        Self::for_item(tcx, def_id, |param, _| match param.kind {
-            ty::GenericParamDefKind::Type { .. } => tcx
-                .mk_ty(ty::Bound(
-                    ty::INNERMOST,
-                    ty::BoundTy {
-                        var: ty::BoundVar::from(param.index),
-                        kind: ty::BoundTyKind::Param(param.name),
-                    },
-                ))
-                .into(),
-
-            ty::GenericParamDefKind::Lifetime => tcx
-                .mk_region(ty::RegionKind::ReLateBound(
-                    ty::INNERMOST,
-                    ty::BoundRegion::BrNamed(param.def_id, param.name),
-                ))
-                .into(),
-
-            ty::GenericParamDefKind::Const => tcx
-                .mk_const(ty::Const {
-                    val: ty::ConstKind::Bound(ty::INNERMOST, ty::BoundVar::from(param.index)),
-                    ty: tcx.type_of(param.def_id),
-                })
-                .into(),
-        })
-    }
-
-    /// Creates a `InternalSubsts` for generic parameter definitions,
-    /// by calling closures to obtain each kind.
-    /// The closures get to observe the `InternalSubsts` as they're
-    /// being built, which can be used to correctly
-    /// substitute defaults of generic parameters.
-    pub fn for_item<F>(tcx: TyCtxt<'tcx>, def_id: DefId, mut mk_kind: F) -> SubstsRef<'tcx>
-    where
-        F: FnMut(&ty::GenericParamDef, &[GenericArg<'tcx>]) -> GenericArg<'tcx>,
-    {
-        let defs = tcx.generics_of(def_id);
-        let count = defs.count();
-        let mut substs = SmallVec::with_capacity(count);
-        Self::fill_item(&mut substs, tcx, defs, &mut mk_kind);
-        tcx.intern_substs(&substs)
-    }
-
-    pub fn extend_to<F>(&self, tcx: TyCtxt<'tcx>, def_id: DefId, mut mk_kind: F) -> SubstsRef<'tcx>
-    where
-        F: FnMut(&ty::GenericParamDef, &[GenericArg<'tcx>]) -> GenericArg<'tcx>,
-    {
-        Self::for_item(tcx, def_id, |param, substs| {
-            self.get(param.index as usize).cloned().unwrap_or_else(|| mk_kind(param, substs))
-        })
-    }
-
-    fn fill_item<F>(
-        substs: &mut SmallVec<[GenericArg<'tcx>; 8]>,
-        tcx: TyCtxt<'tcx>,
-        defs: &ty::Generics,
-        mk_kind: &mut F,
-    ) where
-        F: FnMut(&ty::GenericParamDef, &[GenericArg<'tcx>]) -> GenericArg<'tcx>,
-    {
-        if let Some(def_id) = defs.parent {
-            let parent_defs = tcx.generics_of(def_id);
-            Self::fill_item(substs, tcx, parent_defs, mk_kind);
-        }
-        Self::fill_single(substs, defs, mk_kind)
-    }
-
-    fn fill_single<F>(
-        substs: &mut SmallVec<[GenericArg<'tcx>; 8]>,
-        defs: &ty::Generics,
-        mk_kind: &mut F,
-    ) where
-        F: FnMut(&ty::GenericParamDef, &[GenericArg<'tcx>]) -> GenericArg<'tcx>,
-    {
-        substs.reserve(defs.params.len());
-        for param in &defs.params {
-            let kind = mk_kind(param, substs);
-            assert_eq!(param.index as usize, substs.len());
-            substs.push(kind);
-        }
-    }
-
-    pub fn is_noop(&self) -> bool {
-        self.is_empty()
-    }
-
-    #[inline]
-    pub fn types(&'a self) -> impl DoubleEndedIterator<Item = Ty<'tcx>> + 'a {
-        self.iter()
-            .filter_map(|k| if let GenericArgKind::Type(ty) = k.unpack() { Some(ty) } else { None })
-    }
-
-    #[inline]
-    pub fn regions(&'a self) -> impl DoubleEndedIterator<Item = ty::Region<'tcx>> + 'a {
-        self.iter().filter_map(|k| {
-            if let GenericArgKind::Lifetime(lt) = k.unpack() { Some(lt) } else { None }
-        })
-    }
-
-    #[inline]
-    pub fn consts(&'a self) -> impl DoubleEndedIterator<Item = &'tcx ty::Const<'tcx>> + 'a {
-        self.iter().filter_map(|k| {
-            if let GenericArgKind::Const(ct) = k.unpack() { Some(ct) } else { None }
-        })
-    }
-
-    #[inline]
-    pub fn non_erasable_generics(
-        &'a self,
-    ) -> impl DoubleEndedIterator<Item = GenericArgKind<'tcx>> + 'a {
-        self.iter().filter_map(|k| match k.unpack() {
-            GenericArgKind::Lifetime(_) => None,
-            generic => Some(generic),
-        })
-    }
-
-    #[inline]
-    pub fn type_at(&self, i: usize) -> Ty<'tcx> {
-        if let GenericArgKind::Type(ty) = self[i].unpack() {
-            ty
-        } else {
-            bug!("expected type for param #{} in {:?}", i, self);
-        }
-    }
-
-    #[inline]
-    pub fn region_at(&self, i: usize) -> ty::Region<'tcx> {
-        if let GenericArgKind::Lifetime(lt) = self[i].unpack() {
-            lt
-        } else {
-            bug!("expected region for param #{} in {:?}", i, self);
-        }
-    }
-
-    #[inline]
-    pub fn const_at(&self, i: usize) -> &'tcx ty::Const<'tcx> {
-        if let GenericArgKind::Const(ct) = self[i].unpack() {
-            ct
-        } else {
-            bug!("expected const for param #{} in {:?}", i, self);
-        }
-    }
-
-    #[inline]
-    pub fn type_for_def(&self, def: &ty::GenericParamDef) -> GenericArg<'tcx> {
-        self.type_at(def.index as usize).into()
-    }
-
-    /// Transform from substitutions for a child of `source_ancestor`
-    /// (e.g., a trait or impl) to substitutions for the same child
-    /// in a different item, with `target_substs` as the base for
-    /// the target impl/trait, with the source child-specific
-    /// parameters (e.g., method parameters) on top of that base.
-    pub fn rebase_onto(
-        &self,
-        tcx: TyCtxt<'tcx>,
-        source_ancestor: DefId,
-        target_substs: SubstsRef<'tcx>,
-    ) -> SubstsRef<'tcx> {
-        let defs = tcx.generics_of(source_ancestor);
-        tcx.mk_substs(target_substs.iter().chain(&self[defs.params.len()..]).cloned())
-    }
-
-    pub fn truncate_to(&self, tcx: TyCtxt<'tcx>, generics: &ty::Generics) -> SubstsRef<'tcx> {
-        tcx.mk_substs(self.iter().take(generics.count()).cloned())
-    }
-}
-
-impl<'tcx> TypeFoldable<'tcx> for SubstsRef<'tcx> {
-    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
-        // This code is hot enough that it's worth specializing for the most
-        // common length lists, to avoid the overhead of `SmallVec` creation.
-        // The match arms are in order of frequency. The 1, 2, and 0 cases are
-        // typically hit in 90--99.99% of cases. When folding doesn't change
-        // the substs, it's faster to reuse the existing substs rather than
-        // calling `intern_substs`.
-        match self.len() {
-            1 => {
-                let param0 = self[0].fold_with(folder);
-                if param0 == self[0] { self } else { folder.tcx().intern_substs(&[param0]) }
-            }
-            2 => {
-                let param0 = self[0].fold_with(folder);
-                let param1 = self[1].fold_with(folder);
-                if param0 == self[0] && param1 == self[1] {
-                    self
-                } else {
-                    folder.tcx().intern_substs(&[param0, param1])
-                }
-            }
-            0 => self,
-            _ => {
-                let params: SmallVec<[_; 8]> = self.iter().map(|k| k.fold_with(folder)).collect();
-                if params[..] == self[..] { self } else { folder.tcx().intern_substs(&params) }
-            }
-        }
-    }
-
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
-        self.iter().any(|t| t.visit_with(visitor))
-    }
-}
-
-impl<'tcx> rustc_serialize::UseSpecializedDecodable for SubstsRef<'tcx> {}
-
-///////////////////////////////////////////////////////////////////////////
-// Public trait `Subst`
-//
-// Just call `foo.subst(tcx, substs)` to perform a substitution across
-// `foo`. Or use `foo.subst_spanned(tcx, substs, Some(span))` when
-// there is more information available (for better errors).
-
-pub trait Subst<'tcx>: Sized {
-    fn subst(&self, tcx: TyCtxt<'tcx>, substs: &[GenericArg<'tcx>]) -> Self {
-        self.subst_spanned(tcx, substs, None)
-    }
-
-    fn subst_spanned(
-        &self,
-        tcx: TyCtxt<'tcx>,
-        substs: &[GenericArg<'tcx>],
-        span: Option<Span>,
-    ) -> Self;
-}
-
-impl<'tcx, T: TypeFoldable<'tcx>> Subst<'tcx> for T {
-    fn subst_spanned(
-        &self,
-        tcx: TyCtxt<'tcx>,
-        substs: &[GenericArg<'tcx>],
-        span: Option<Span>,
-    ) -> T {
-        let mut folder =
-            SubstFolder { tcx, substs, span, root_ty: None, ty_stack_depth: 0, binders_passed: 0 };
-        (*self).fold_with(&mut folder)
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////
-// The actual substitution engine itself is a type folder.
-
-struct SubstFolder<'a, 'tcx> {
-    tcx: TyCtxt<'tcx>,
-    substs: &'a [GenericArg<'tcx>],
-
-    /// The location for which the substitution is performed, if available.
-    span: Option<Span>,
-
-    /// The root type that is being substituted, if available.
-    root_ty: Option<Ty<'tcx>>,
-
-    /// Depth of type stack
-    ty_stack_depth: usize,
-
-    /// Number of region binders we have passed through while doing the substitution
-    binders_passed: u32,
-}
-
-impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> {
-    fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
-        self.tcx
-    }
-
-    fn fold_binder<T: TypeFoldable<'tcx>>(&mut self, t: &ty::Binder<T>) -> ty::Binder<T> {
-        self.binders_passed += 1;
-        let t = t.super_fold_with(self);
-        self.binders_passed -= 1;
-        t
-    }
-
-    fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
-        // Note: This routine only handles regions that are bound on
-        // type declarations and other outer declarations, not those
-        // bound in *fn types*. Region substitution of the bound
-        // regions that appear in a function signature is done using
-        // the specialized routine `ty::replace_late_regions()`.
-        match *r {
-            ty::ReEarlyBound(data) => {
-                let rk = self.substs.get(data.index as usize).map(|k| k.unpack());
-                match rk {
-                    Some(GenericArgKind::Lifetime(lt)) => self.shift_region_through_binders(lt),
-                    _ => {
-                        let span = self.span.unwrap_or(DUMMY_SP);
-                        let msg = format!(
-                            "Region parameter out of range \
-                             when substituting in region {} (root type={:?}) \
-                             (index={})",
-                            data.name, self.root_ty, data.index
-                        );
-                        span_bug!(span, "{}", msg);
-                    }
-                }
-            }
-            _ => r,
-        }
-    }
-
-    fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
-        if !t.needs_subst() {
-            return t;
-        }
-
-        // track the root type we were asked to substitute
-        let depth = self.ty_stack_depth;
-        if depth == 0 {
-            self.root_ty = Some(t);
-        }
-        self.ty_stack_depth += 1;
-
-        let t1 = match t.kind {
-            ty::Param(p) => self.ty_for_param(p, t),
-            _ => t.super_fold_with(self),
-        };
-
-        assert_eq!(depth + 1, self.ty_stack_depth);
-        self.ty_stack_depth -= 1;
-        if depth == 0 {
-            self.root_ty = None;
-        }
-
-        return t1;
-    }
-
-    fn fold_const(&mut self, c: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
-        if !c.needs_subst() {
-            return c;
-        }
-
-        if let ty::ConstKind::Param(p) = c.val {
-            self.const_for_param(p, c)
-        } else {
-            c.super_fold_with(self)
-        }
-    }
-}
-
-impl<'a, 'tcx> SubstFolder<'a, 'tcx> {
-    fn ty_for_param(&self, p: ty::ParamTy, source_ty: Ty<'tcx>) -> Ty<'tcx> {
-        // Look up the type in the substitutions. It really should be in there.
-        let opt_ty = self.substs.get(p.index as usize).map(|k| k.unpack());
-        let ty = match opt_ty {
-            Some(GenericArgKind::Type(ty)) => ty,
-            Some(kind) => {
-                let span = self.span.unwrap_or(DUMMY_SP);
-                span_bug!(
-                    span,
-                    "expected type for `{:?}` ({:?}/{}) but found {:?} \
-                     when substituting (root type={:?}) substs={:?}",
-                    p,
-                    source_ty,
-                    p.index,
-                    kind,
-                    self.root_ty,
-                    self.substs,
-                );
-            }
-            None => {
-                let span = self.span.unwrap_or(DUMMY_SP);
-                span_bug!(
-                    span,
-                    "type parameter `{:?}` ({:?}/{}) out of range \
-                     when substituting (root type={:?}) substs={:?}",
-                    p,
-                    source_ty,
-                    p.index,
-                    self.root_ty,
-                    self.substs,
-                );
-            }
-        };
-
-        self.shift_vars_through_binders(ty)
-    }
-
-    fn const_for_param(
-        &self,
-        p: ParamConst,
-        source_ct: &'tcx ty::Const<'tcx>,
-    ) -> &'tcx ty::Const<'tcx> {
-        // Look up the const in the substitutions. It really should be in there.
-        let opt_ct = self.substs.get(p.index as usize).map(|k| k.unpack());
-        let ct = match opt_ct {
-            Some(GenericArgKind::Const(ct)) => ct,
-            Some(kind) => {
-                let span = self.span.unwrap_or(DUMMY_SP);
-                span_bug!(
-                    span,
-                    "expected const for `{:?}` ({:?}/{}) but found {:?} \
-                     when substituting substs={:?}",
-                    p,
-                    source_ct,
-                    p.index,
-                    kind,
-                    self.substs,
-                );
-            }
-            None => {
-                let span = self.span.unwrap_or(DUMMY_SP);
-                span_bug!(
-                    span,
-                    "const parameter `{:?}` ({:?}/{}) out of range \
-                     when substituting substs={:?}",
-                    p,
-                    source_ct,
-                    p.index,
-                    self.substs,
-                );
-            }
-        };
-
-        self.shift_vars_through_binders(ct)
-    }
-
-    /// It is sometimes necessary to adjust the De Bruijn indices during substitution. This occurs
-    /// when we are substituting a type with escaping bound vars into a context where we have
-    /// passed through binders. That's quite a mouthful. Let's see an example:
-    ///
-    /// ```
-    /// type Func<A> = fn(A);
-    /// type MetaFunc = for<'a> fn(Func<&'a int>)
-    /// ```
-    ///
-    /// The type `MetaFunc`, when fully expanded, will be
-    ///
-    ///     for<'a> fn(fn(&'a int))
-    ///             ^~ ^~ ^~~
-    ///             |  |  |
-    ///             |  |  DebruijnIndex of 2
-    ///             Binders
-    ///
-    /// Here the `'a` lifetime is bound in the outer function, but appears as an argument of the
-    /// inner one. Therefore, that appearance will have a DebruijnIndex of 2, because we must skip
-    /// over the inner binder (remember that we count De Bruijn indices from 1). However, in the
-    /// definition of `MetaFunc`, the binder is not visible, so the type `&'a int` will have a
-    /// De Bruijn index of 1. It's only during the substitution that we can see we must increase the
-    /// depth by 1 to account for the binder that we passed through.
-    ///
-    /// As a second example, consider this twist:
-    ///
-    /// ```
-    /// type FuncTuple<A> = (A,fn(A));
-    /// type MetaFuncTuple = for<'a> fn(FuncTuple<&'a int>)
-    /// ```
-    ///
-    /// Here the final type will be:
-    ///
-    ///     for<'a> fn((&'a int, fn(&'a int)))
-    ///                 ^~~         ^~~
-    ///                 |           |
-    ///          DebruijnIndex of 1 |
-    ///                      DebruijnIndex of 2
-    ///
-    /// As indicated in the diagram, here the same type `&'a int` is substituted once, but in the
-    /// first case we do not increase the De Bruijn index and in the second case we do. The reason
-    /// is that only in the second case have we passed through a fn binder.
-    fn shift_vars_through_binders<T: TypeFoldable<'tcx>>(&self, val: T) -> T {
-        debug!(
-            "shift_vars(val={:?}, binders_passed={:?}, has_escaping_bound_vars={:?})",
-            val,
-            self.binders_passed,
-            val.has_escaping_bound_vars()
-        );
-
-        if self.binders_passed == 0 || !val.has_escaping_bound_vars() {
-            return val;
-        }
-
-        let result = ty::fold::shift_vars(self.tcx(), &val, self.binders_passed);
-        debug!("shift_vars: shifted result = {:?}", result);
-
-        result
-    }
-
-    fn shift_region_through_binders(&self, region: ty::Region<'tcx>) -> ty::Region<'tcx> {
-        if self.binders_passed == 0 || !region.has_escaping_bound_vars() {
-            return region;
-        }
-        ty::fold::shift_region(self.tcx, region, self.binders_passed)
-    }
-}
-
-pub type CanonicalUserSubsts<'tcx> = Canonical<'tcx, UserSubsts<'tcx>>;
-
-/// Stores the user-given substs to reach some fully qualified path
-/// (e.g., `<T>::Item` or `<T as Trait>::Item`).
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
-#[derive(HashStable, TypeFoldable, Lift)]
-pub struct UserSubsts<'tcx> {
-    /// The substitutions for the item as given by the user.
-    pub substs: SubstsRef<'tcx>,
-
-    /// The self type, in the case of a `<T>::Item` path (when applied
-    /// to an inherent impl). See `UserSelfTy` below.
-    pub user_self_ty: Option<UserSelfTy<'tcx>>,
-}
-
-/// Specifies the user-given self type. In the case of a path that
-/// refers to a member in an inherent impl, this self type is
-/// sometimes needed to constrain the type parameters on the impl. For
-/// example, in this code:
-///
-/// ```
-/// struct Foo<T> { }
-/// impl<A> Foo<A> { fn method() { } }
-/// ```
-///
-/// when you then have a path like `<Foo<&'static u32>>::method`,
-/// this struct would carry the `DefId` of the impl along with the
-/// self type `Foo<u32>`. Then we can instantiate the parameters of
-/// the impl (with the substs from `UserSubsts`) and apply those to
-/// the self type, giving `Foo<?A>`. Finally, we unify that with
-/// the self type here, which contains `?A` to be `&'static u32`
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
-#[derive(HashStable, TypeFoldable, Lift)]
-pub struct UserSelfTy<'tcx> {
-    pub impl_def_id: DefId,
-    pub self_ty: Ty<'tcx>,
-}
diff --git a/src/librustc/ty/trait_def.rs b/src/librustc/ty/trait_def.rs
deleted file mode 100644
index 0cf1c397648..00000000000
--- a/src/librustc/ty/trait_def.rs
+++ /dev/null
@@ -1,191 +0,0 @@
-use crate::hir::map::DefPathHash;
-use crate::ich::{self, StableHashingContext};
-use crate::traits::specialization_graph;
-use crate::ty::fast_reject;
-use crate::ty::fold::TypeFoldable;
-use crate::ty::{Ty, TyCtxt};
-use rustc_hir as hir;
-use rustc_hir::def_id::DefId;
-
-use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
-use rustc_macros::HashStable;
-
-/// A trait's definition with type information.
-#[derive(HashStable)]
-pub struct TraitDef {
-    // We already have the def_path_hash below, no need to hash it twice
-    #[stable_hasher(ignore)]
-    pub def_id: DefId,
-
-    pub unsafety: hir::Unsafety,
-
-    /// If `true`, then this trait had the `#[rustc_paren_sugar]`
-    /// attribute, indicating that it should be used with `Foo()`
-    /// sugar. This is a temporary thing -- eventually any trait will
-    /// be usable with the sugar (or without it).
-    pub paren_sugar: bool,
-
-    pub has_auto_impl: bool,
-
-    /// If `true`, then this trait has the `#[marker]` attribute, indicating
-    /// that all its associated items have defaults that cannot be overridden,
-    /// and thus `impl`s of it are allowed to overlap.
-    pub is_marker: bool,
-
-    /// The ICH of this trait's DefPath, cached here so it doesn't have to be
-    /// recomputed all the time.
-    pub def_path_hash: DefPathHash,
-}
-
-#[derive(Default)]
-pub struct TraitImpls {
-    blanket_impls: Vec<DefId>,
-    /// Impls indexed by their simplified self type, for fast lookup.
-    non_blanket_impls: FxHashMap<fast_reject::SimplifiedType, Vec<DefId>>,
-}
-
-impl<'tcx> TraitDef {
-    pub fn new(
-        def_id: DefId,
-        unsafety: hir::Unsafety,
-        paren_sugar: bool,
-        has_auto_impl: bool,
-        is_marker: bool,
-        def_path_hash: DefPathHash,
-    ) -> TraitDef {
-        TraitDef { def_id, unsafety, paren_sugar, has_auto_impl, is_marker, def_path_hash }
-    }
-
-    pub fn ancestors(
-        &self,
-        tcx: TyCtxt<'tcx>,
-        of_impl: DefId,
-    ) -> specialization_graph::Ancestors<'tcx> {
-        specialization_graph::ancestors(tcx, self.def_id, of_impl)
-    }
-}
-
-impl<'tcx> TyCtxt<'tcx> {
-    pub fn for_each_impl<F: FnMut(DefId)>(self, def_id: DefId, mut f: F) {
-        let impls = self.trait_impls_of(def_id);
-
-        for &impl_def_id in impls.blanket_impls.iter() {
-            f(impl_def_id);
-        }
-
-        for v in impls.non_blanket_impls.values() {
-            for &impl_def_id in v {
-                f(impl_def_id);
-            }
-        }
-    }
-
-    /// Iterate over every impl that could possibly match the
-    /// self type `self_ty`.
-    pub fn for_each_relevant_impl<F: FnMut(DefId)>(
-        self,
-        def_id: DefId,
-        self_ty: Ty<'tcx>,
-        mut f: F,
-    ) {
-        let impls = self.trait_impls_of(def_id);
-
-        for &impl_def_id in impls.blanket_impls.iter() {
-            f(impl_def_id);
-        }
-
-        // simplify_type(.., false) basically replaces type parameters and
-        // projections with infer-variables. This is, of course, done on
-        // the impl trait-ref when it is instantiated, but not on the
-        // predicate trait-ref which is passed here.
-        //
-        // for example, if we match `S: Copy` against an impl like
-        // `impl<T:Copy> Copy for Option<T>`, we replace the type variable
-        // in `Option<T>` with an infer variable, to `Option<_>` (this
-        // doesn't actually change fast_reject output), but we don't
-        // replace `S` with anything - this impl of course can't be
-        // selected, and as there are hundreds of similar impls,
-        // considering them would significantly harm performance.
-
-        // This depends on the set of all impls for the trait. That is
-        // unfortunate. When we get red-green recompilation, we would like
-        // to have a way of knowing whether the set of relevant impls
-        // changed. The most naive
-        // way would be to compute the Vec of relevant impls and see whether
-        // it differs between compilations. That shouldn't be too slow by
-        // itself - we do quite a bit of work for each relevant impl anyway.
-        //
-        // If we want to be faster, we could have separate queries for
-        // blanket and non-blanket impls, and compare them separately.
-        //
-        // I think we'll cross that bridge when we get to it.
-        if let Some(simp) = fast_reject::simplify_type(self, self_ty, true) {
-            if let Some(impls) = impls.non_blanket_impls.get(&simp) {
-                for &impl_def_id in impls {
-                    f(impl_def_id);
-                }
-            }
-        } else {
-            for &impl_def_id in impls.non_blanket_impls.values().flatten() {
-                f(impl_def_id);
-            }
-        }
-    }
-
-    /// Returns a vector containing all impls
-    pub fn all_impls(self, def_id: DefId) -> Vec<DefId> {
-        let impls = self.trait_impls_of(def_id);
-
-        impls
-            .blanket_impls
-            .iter()
-            .chain(impls.non_blanket_impls.values().flatten())
-            .cloned()
-            .collect()
-    }
-}
-
-// Query provider for `trait_impls_of`.
-pub(super) fn trait_impls_of_provider(tcx: TyCtxt<'_>, trait_id: DefId) -> &TraitImpls {
-    let mut impls = TraitImpls::default();
-
-    {
-        let mut add_impl = |impl_def_id| {
-            let impl_self_ty = tcx.type_of(impl_def_id);
-            if impl_def_id.is_local() && impl_self_ty.references_error() {
-                return;
-            }
-
-            if let Some(simplified_self_ty) = fast_reject::simplify_type(tcx, impl_self_ty, false) {
-                impls.non_blanket_impls.entry(simplified_self_ty).or_default().push(impl_def_id);
-            } else {
-                impls.blanket_impls.push(impl_def_id);
-            }
-        };
-
-        // Traits defined in the current crate can't have impls in upstream
-        // crates, so we don't bother querying the cstore.
-        if !trait_id.is_local() {
-            for &cnum in tcx.crates().iter() {
-                for &def_id in tcx.implementations_of_trait((cnum, trait_id)).iter() {
-                    add_impl(def_id);
-                }
-            }
-        }
-
-        for &hir_id in tcx.hir().trait_impls(trait_id) {
-            add_impl(tcx.hir().local_def_id(hir_id));
-        }
-    }
-
-    tcx.arena.alloc(impls)
-}
-
-impl<'a> HashStable<StableHashingContext<'a>> for TraitImpls {
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        let TraitImpls { ref blanket_impls, ref non_blanket_impls } = *self;
-
-        ich::hash_stable_trait_impls(hcx, hasher, blanket_impls, non_blanket_impls);
-    }
-}
diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs
deleted file mode 100644
index eec6893d357..00000000000
--- a/src/librustc/ty/util.rs
+++ /dev/null
@@ -1,1096 +0,0 @@
-//! Miscellaneous type-system utilities that are too small to deserve their own modules.
-
-use crate::hir::map::DefPathData;
-use crate::ich::NodeIdHashingMode;
-use crate::mir::interpret::{sign_extend, truncate};
-use crate::ty::layout::{Integer, IntegerExt, Size};
-use crate::ty::query::TyCtxtAt;
-use crate::ty::subst::{GenericArgKind, InternalSubsts, Subst, SubstsRef};
-use crate::ty::TyKind::*;
-use crate::ty::{self, DefIdTree, GenericParamDefKind, Ty, TyCtxt, TypeFoldable};
-use crate::util::common::ErrorReported;
-use rustc_apfloat::Float as _;
-use rustc_attr::{self as attr, SignedInt, UnsignedInt};
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
-use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
-use rustc_hir as hir;
-use rustc_hir::def::DefKind;
-use rustc_hir::def_id::DefId;
-use rustc_macros::HashStable;
-use rustc_span::Span;
-use rustc_target::abi::TargetDataLayout;
-use smallvec::SmallVec;
-use std::{cmp, fmt};
-use syntax::ast;
-
-#[derive(Copy, Clone, Debug)]
-pub struct Discr<'tcx> {
-    /// Bit representation of the discriminant (e.g., `-128i8` is `0xFF_u128`).
-    pub val: u128,
-    pub ty: Ty<'tcx>,
-}
-
-impl<'tcx> fmt::Display for Discr<'tcx> {
-    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match self.ty.kind {
-            ty::Int(ity) => {
-                let size = ty::tls::with(|tcx| Integer::from_attr(&tcx, SignedInt(ity)).size());
-                let x = self.val;
-                // sign extend the raw representation to be an i128
-                let x = sign_extend(x, size) as i128;
-                write!(fmt, "{}", x)
-            }
-            _ => write!(fmt, "{}", self.val),
-        }
-    }
-}
-
-fn signed_min(size: Size) -> i128 {
-    sign_extend(1_u128 << (size.bits() - 1), size) as i128
-}
-
-fn signed_max(size: Size) -> i128 {
-    i128::max_value() >> (128 - size.bits())
-}
-
-fn unsigned_max(size: Size) -> u128 {
-    u128::max_value() >> (128 - size.bits())
-}
-
-fn int_size_and_signed<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> (Size, bool) {
-    let (int, signed) = match ty.kind {
-        Int(ity) => (Integer::from_attr(&tcx, SignedInt(ity)), true),
-        Uint(uty) => (Integer::from_attr(&tcx, UnsignedInt(uty)), false),
-        _ => bug!("non integer discriminant"),
-    };
-    (int.size(), signed)
-}
-
-impl<'tcx> Discr<'tcx> {
-    /// Adds `1` to the value and wraps around if the maximum for the type is reached.
-    pub fn wrap_incr(self, tcx: TyCtxt<'tcx>) -> Self {
-        self.checked_add(tcx, 1).0
-    }
-    pub fn checked_add(self, tcx: TyCtxt<'tcx>, n: u128) -> (Self, bool) {
-        let (size, signed) = int_size_and_signed(tcx, self.ty);
-        let (val, oflo) = if signed {
-            let min = signed_min(size);
-            let max = signed_max(size);
-            let val = sign_extend(self.val, size) as i128;
-            assert!(n < (i128::max_value() as u128));
-            let n = n as i128;
-            let oflo = val > max - n;
-            let val = if oflo { min + (n - (max - val) - 1) } else { val + n };
-            // zero the upper bits
-            let val = val as u128;
-            let val = truncate(val, size);
-            (val, oflo)
-        } else {
-            let max = unsigned_max(size);
-            let val = self.val;
-            let oflo = val > max - n;
-            let val = if oflo { n - (max - val) - 1 } else { val + n };
-            (val, oflo)
-        };
-        (Self { val, ty: self.ty }, oflo)
-    }
-}
-
-pub trait IntTypeExt {
-    fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx>;
-    fn disr_incr<'tcx>(&self, tcx: TyCtxt<'tcx>, val: Option<Discr<'tcx>>) -> Option<Discr<'tcx>>;
-    fn initial_discriminant<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Discr<'tcx>;
-}
-
-impl IntTypeExt for attr::IntType {
-    fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
-        match *self {
-            SignedInt(ast::IntTy::I8) => tcx.types.i8,
-            SignedInt(ast::IntTy::I16) => tcx.types.i16,
-            SignedInt(ast::IntTy::I32) => tcx.types.i32,
-            SignedInt(ast::IntTy::I64) => tcx.types.i64,
-            SignedInt(ast::IntTy::I128) => tcx.types.i128,
-            SignedInt(ast::IntTy::Isize) => tcx.types.isize,
-            UnsignedInt(ast::UintTy::U8) => tcx.types.u8,
-            UnsignedInt(ast::UintTy::U16) => tcx.types.u16,
-            UnsignedInt(ast::UintTy::U32) => tcx.types.u32,
-            UnsignedInt(ast::UintTy::U64) => tcx.types.u64,
-            UnsignedInt(ast::UintTy::U128) => tcx.types.u128,
-            UnsignedInt(ast::UintTy::Usize) => tcx.types.usize,
-        }
-    }
-
-    fn initial_discriminant<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Discr<'tcx> {
-        Discr { val: 0, ty: self.to_ty(tcx) }
-    }
-
-    fn disr_incr<'tcx>(&self, tcx: TyCtxt<'tcx>, val: Option<Discr<'tcx>>) -> Option<Discr<'tcx>> {
-        if let Some(val) = val {
-            assert_eq!(self.to_ty(tcx), val.ty);
-            let (new, oflo) = val.checked_add(tcx, 1);
-            if oflo { None } else { Some(new) }
-        } else {
-            Some(self.initial_discriminant(tcx))
-        }
-    }
-}
-
-/// Describes whether a type is representable. For types that are not
-/// representable, 'SelfRecursive' and 'ContainsRecursive' are used to
-/// distinguish between types that are recursive with themselves and types that
-/// contain a different recursive type. These cases can therefore be treated
-/// differently when reporting errors.
-///
-/// The ordering of the cases is significant. They are sorted so that cmp::max
-/// will keep the "more erroneous" of two values.
-#[derive(Clone, PartialOrd, Ord, Eq, PartialEq, Debug)]
-pub enum Representability {
-    Representable,
-    ContainsRecursive,
-    SelfRecursive(Vec<Span>),
-}
-
-impl<'tcx> TyCtxt<'tcx> {
-    /// Creates a hash of the type `Ty` which will be the same no matter what crate
-    /// context it's calculated within. This is used by the `type_id` intrinsic.
-    pub fn type_id_hash(self, ty: Ty<'tcx>) -> u64 {
-        let mut hasher = StableHasher::new();
-        let mut hcx = self.create_stable_hashing_context();
-
-        // We want the type_id be independent of the types free regions, so we
-        // erase them. The erase_regions() call will also anonymize bound
-        // regions, which is desirable too.
-        let ty = self.erase_regions(&ty);
-
-        hcx.while_hashing_spans(false, |hcx| {
-            hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
-                ty.hash_stable(hcx, &mut hasher);
-            });
-        });
-        hasher.finish()
-    }
-}
-
-impl<'tcx> TyCtxt<'tcx> {
-    pub fn has_error_field(self, ty: Ty<'tcx>) -> bool {
-        if let ty::Adt(def, substs) = ty.kind {
-            for field in def.all_fields() {
-                let field_ty = field.ty(self, substs);
-                if let Error = field_ty.kind {
-                    return true;
-                }
-            }
-        }
-        false
-    }
-
-    /// Attempts to returns the deeply last field of nested structures, but
-    /// does not apply any normalization in its search. Returns the same type
-    /// if input `ty` is not a structure at all.
-    pub fn struct_tail_without_normalization(self, ty: Ty<'tcx>) -> Ty<'tcx> {
-        let tcx = self;
-        tcx.struct_tail_with_normalize(ty, |ty| ty)
-    }
-
-    /// Returns the deeply last field of nested structures, or the same type if
-    /// not a structure at all. Corresponds to the only possible unsized field,
-    /// and its type can be used to determine unsizing strategy.
-    ///
-    /// Should only be called if `ty` has no inference variables and does not
-    /// need its lifetimes preserved (e.g. as part of codegen); otherwise
-    /// normalization attempt may cause compiler bugs.
-    pub fn struct_tail_erasing_lifetimes(
-        self,
-        ty: Ty<'tcx>,
-        param_env: ty::ParamEnv<'tcx>,
-    ) -> Ty<'tcx> {
-        let tcx = self;
-        tcx.struct_tail_with_normalize(ty, |ty| tcx.normalize_erasing_regions(param_env, ty))
-    }
-
-    /// Returns the deeply last field of nested structures, or the same type if
-    /// not a structure at all. Corresponds to the only possible unsized field,
-    /// and its type can be used to determine unsizing strategy.
-    ///
-    /// This is parameterized over the normalization strategy (i.e. how to
-    /// handle `<T as Trait>::Assoc` and `impl Trait`); pass the identity
-    /// function to indicate no normalization should take place.
-    ///
-    /// See also `struct_tail_erasing_lifetimes`, which is suitable for use
-    /// during codegen.
-    pub fn struct_tail_with_normalize(
-        self,
-        mut ty: Ty<'tcx>,
-        normalize: impl Fn(Ty<'tcx>) -> Ty<'tcx>,
-    ) -> Ty<'tcx> {
-        loop {
-            match ty.kind {
-                ty::Adt(def, substs) => {
-                    if !def.is_struct() {
-                        break;
-                    }
-                    match def.non_enum_variant().fields.last() {
-                        Some(f) => ty = f.ty(self, substs),
-                        None => break,
-                    }
-                }
-
-                ty::Tuple(tys) => {
-                    if let Some((&last_ty, _)) = tys.split_last() {
-                        ty = last_ty.expect_ty();
-                    } else {
-                        break;
-                    }
-                }
-
-                ty::Projection(_) | ty::Opaque(..) => {
-                    let normalized = normalize(ty);
-                    if ty == normalized {
-                        return ty;
-                    } else {
-                        ty = normalized;
-                    }
-                }
-
-                _ => {
-                    break;
-                }
-            }
-        }
-        ty
-    }
-
-    /// Same as applying `struct_tail` on `source` and `target`, but only
-    /// keeps going as long as the two types are instances of the same
-    /// structure definitions.
-    /// For `(Foo<Foo<T>>, Foo<dyn Trait>)`, the result will be `(Foo<T>, Trait)`,
-    /// whereas struct_tail produces `T`, and `Trait`, respectively.
-    ///
-    /// Should only be called if the types have no inference variables and do
-    /// not need their lifetimes preserved (e.g., as part of codegen); otherwise,
-    /// normalization attempt may cause compiler bugs.
-    pub fn struct_lockstep_tails_erasing_lifetimes(
-        self,
-        source: Ty<'tcx>,
-        target: Ty<'tcx>,
-        param_env: ty::ParamEnv<'tcx>,
-    ) -> (Ty<'tcx>, Ty<'tcx>) {
-        let tcx = self;
-        tcx.struct_lockstep_tails_with_normalize(source, target, |ty| {
-            tcx.normalize_erasing_regions(param_env, ty)
-        })
-    }
-
-    /// Same as applying `struct_tail` on `source` and `target`, but only
-    /// keeps going as long as the two types are instances of the same
-    /// structure definitions.
-    /// For `(Foo<Foo<T>>, Foo<dyn Trait>)`, the result will be `(Foo<T>, Trait)`,
-    /// whereas struct_tail produces `T`, and `Trait`, respectively.
-    ///
-    /// See also `struct_lockstep_tails_erasing_lifetimes`, which is suitable for use
-    /// during codegen.
-    pub fn struct_lockstep_tails_with_normalize(
-        self,
-        source: Ty<'tcx>,
-        target: Ty<'tcx>,
-        normalize: impl Fn(Ty<'tcx>) -> Ty<'tcx>,
-    ) -> (Ty<'tcx>, Ty<'tcx>) {
-        let (mut a, mut b) = (source, target);
-        loop {
-            match (&a.kind, &b.kind) {
-                (&Adt(a_def, a_substs), &Adt(b_def, b_substs))
-                    if a_def == b_def && a_def.is_struct() =>
-                {
-                    if let Some(f) = a_def.non_enum_variant().fields.last() {
-                        a = f.ty(self, a_substs);
-                        b = f.ty(self, b_substs);
-                    } else {
-                        break;
-                    }
-                }
-                (&Tuple(a_tys), &Tuple(b_tys)) if a_tys.len() == b_tys.len() => {
-                    if let Some(a_last) = a_tys.last() {
-                        a = a_last.expect_ty();
-                        b = b_tys.last().unwrap().expect_ty();
-                    } else {
-                        break;
-                    }
-                }
-                (ty::Projection(_), _)
-                | (ty::Opaque(..), _)
-                | (_, ty::Projection(_))
-                | (_, ty::Opaque(..)) => {
-                    // If either side is a projection, attempt to
-                    // progress via normalization. (Should be safe to
-                    // apply to both sides as normalization is
-                    // idempotent.)
-                    let a_norm = normalize(a);
-                    let b_norm = normalize(b);
-                    if a == a_norm && b == b_norm {
-                        break;
-                    } else {
-                        a = a_norm;
-                        b = b_norm;
-                    }
-                }
-
-                _ => break,
-            }
-        }
-        (a, b)
-    }
-
-    /// Calculate the destructor of a given type.
-    pub fn calculate_dtor(
-        self,
-        adt_did: DefId,
-        validate: &mut dyn FnMut(Self, DefId) -> Result<(), ErrorReported>,
-    ) -> Option<ty::Destructor> {
-        let drop_trait = if let Some(def_id) = self.lang_items().drop_trait() {
-            def_id
-        } else {
-            return None;
-        };
-
-        self.ensure().coherent_trait(drop_trait);
-
-        let mut dtor_did = None;
-        let ty = self.type_of(adt_did);
-        self.for_each_relevant_impl(drop_trait, ty, |impl_did| {
-            if let Some(item) = self.associated_items(impl_did).in_definition_order().nth(0) {
-                if validate(self, impl_did).is_ok() {
-                    dtor_did = Some(item.def_id);
-                }
-            }
-        });
-
-        Some(ty::Destructor { did: dtor_did? })
-    }
-
-    /// Returns the set of types that are required to be alive in
-    /// order to run the destructor of `def` (see RFCs 769 and
-    /// 1238).
-    ///
-    /// Note that this returns only the constraints for the
-    /// destructor of `def` itself. For the destructors of the
-    /// contents, you need `adt_dtorck_constraint`.
-    pub fn destructor_constraints(self, def: &'tcx ty::AdtDef) -> Vec<ty::subst::GenericArg<'tcx>> {
-        let dtor = match def.destructor(self) {
-            None => {
-                debug!("destructor_constraints({:?}) - no dtor", def.did);
-                return vec![];
-            }
-            Some(dtor) => dtor.did,
-        };
-
-        let impl_def_id = self.associated_item(dtor).container.id();
-        let impl_generics = self.generics_of(impl_def_id);
-
-        // We have a destructor - all the parameters that are not
-        // pure_wrt_drop (i.e, don't have a #[may_dangle] attribute)
-        // must be live.
-
-        // We need to return the list of parameters from the ADTs
-        // generics/substs that correspond to impure parameters on the
-        // impl's generics. This is a bit ugly, but conceptually simple:
-        //
-        // Suppose our ADT looks like the following
-        //
-        //     struct S<X, Y, Z>(X, Y, Z);
-        //
-        // and the impl is
-        //
-        //     impl<#[may_dangle] P0, P1, P2> Drop for S<P1, P2, P0>
-        //
-        // We want to return the parameters (X, Y). For that, we match
-        // up the item-substs <X, Y, Z> with the substs on the impl ADT,
-        // <P1, P2, P0>, and then look up which of the impl substs refer to
-        // parameters marked as pure.
-
-        let impl_substs = match self.type_of(impl_def_id).kind {
-            ty::Adt(def_, substs) if def_ == def => substs,
-            _ => bug!(),
-        };
-
-        let item_substs = match self.type_of(def.did).kind {
-            ty::Adt(def_, substs) if def_ == def => substs,
-            _ => bug!(),
-        };
-
-        let result = item_substs
-            .iter()
-            .zip(impl_substs.iter())
-            .filter(|&(_, &k)| {
-                match k.unpack() {
-                    GenericArgKind::Lifetime(&ty::RegionKind::ReEarlyBound(ref ebr)) => {
-                        !impl_generics.region_param(ebr, self).pure_wrt_drop
-                    }
-                    GenericArgKind::Type(&ty::TyS { kind: ty::Param(ref pt), .. }) => {
-                        !impl_generics.type_param(pt, self).pure_wrt_drop
-                    }
-                    GenericArgKind::Const(&ty::Const {
-                        val: ty::ConstKind::Param(ref pc), ..
-                    }) => !impl_generics.const_param(pc, self).pure_wrt_drop,
-                    GenericArgKind::Lifetime(_)
-                    | GenericArgKind::Type(_)
-                    | GenericArgKind::Const(_) => {
-                        // Not a type, const or region param: this should be reported
-                        // as an error.
-                        false
-                    }
-                }
-            })
-            .map(|(&item_param, _)| item_param)
-            .collect();
-        debug!("destructor_constraint({:?}) = {:?}", def.did, result);
-        result
-    }
-
-    /// Returns `true` if `def_id` refers to a closure (e.g., `|x| x * 2`). Note
-    /// that closures have a `DefId`, but the closure *expression* also
-    /// has a `HirId` that is located within the context where the
-    /// closure appears (and, sadly, a corresponding `NodeId`, since
-    /// those are not yet phased out). The parent of the closure's
-    /// `DefId` will also be the context where it appears.
-    pub fn is_closure(self, def_id: DefId) -> bool {
-        self.def_key(def_id).disambiguated_data.data == DefPathData::ClosureExpr
-    }
-
-    /// Returns `true` if `def_id` refers to a trait (i.e., `trait Foo { ... }`).
-    pub fn is_trait(self, def_id: DefId) -> bool {
-        self.def_kind(def_id) == Some(DefKind::Trait)
-    }
-
-    /// Returns `true` if `def_id` refers to a trait alias (i.e., `trait Foo = ...;`),
-    /// and `false` otherwise.
-    pub fn is_trait_alias(self, def_id: DefId) -> bool {
-        self.def_kind(def_id) == Some(DefKind::TraitAlias)
-    }
-
-    /// Returns `true` if this `DefId` refers to the implicit constructor for
-    /// a tuple struct like `struct Foo(u32)`, and `false` otherwise.
-    pub fn is_constructor(self, def_id: DefId) -> bool {
-        self.def_key(def_id).disambiguated_data.data == DefPathData::Ctor
-    }
-
-    /// Given the def-ID of a fn or closure, returns the def-ID of
-    /// the innermost fn item that the closure is contained within.
-    /// This is a significant `DefId` because, when we do
-    /// type-checking, we type-check this fn item and all of its
-    /// (transitive) closures together. Therefore, when we fetch the
-    /// `typeck_tables_of` the closure, for example, we really wind up
-    /// fetching the `typeck_tables_of` the enclosing fn item.
-    pub fn closure_base_def_id(self, def_id: DefId) -> DefId {
-        let mut def_id = def_id;
-        while self.is_closure(def_id) {
-            def_id = self.parent(def_id).unwrap_or_else(|| {
-                bug!("closure {:?} has no parent", def_id);
-            });
-        }
-        def_id
-    }
-
-    /// Given the `DefId` and substs a closure, creates the type of
-    /// `self` argument that the closure expects. For example, for a
-    /// `Fn` closure, this would return a reference type `&T` where
-    /// `T = closure_ty`.
-    ///
-    /// Returns `None` if this closure's kind has not yet been inferred.
-    /// This should only be possible during type checking.
-    ///
-    /// Note that the return value is a late-bound region and hence
-    /// wrapped in a binder.
-    pub fn closure_env_ty(
-        self,
-        closure_def_id: DefId,
-        closure_substs: SubstsRef<'tcx>,
-    ) -> Option<ty::Binder<Ty<'tcx>>> {
-        let closure_ty = self.mk_closure(closure_def_id, closure_substs);
-        let env_region = ty::ReLateBound(ty::INNERMOST, ty::BrEnv);
-        let closure_kind_ty = closure_substs.as_closure().kind_ty(closure_def_id, self);
-        let closure_kind = closure_kind_ty.to_opt_closure_kind()?;
-        let env_ty = match closure_kind {
-            ty::ClosureKind::Fn => self.mk_imm_ref(self.mk_region(env_region), closure_ty),
-            ty::ClosureKind::FnMut => self.mk_mut_ref(self.mk_region(env_region), closure_ty),
-            ty::ClosureKind::FnOnce => closure_ty,
-        };
-        Some(ty::Binder::bind(env_ty))
-    }
-
-    /// Given the `DefId` of some item that has no type or const parameters, make
-    /// a suitable "empty substs" for it.
-    pub fn empty_substs_for_def_id(self, item_def_id: DefId) -> SubstsRef<'tcx> {
-        InternalSubsts::for_item(self, item_def_id, |param, _| match param.kind {
-            GenericParamDefKind::Lifetime => self.lifetimes.re_erased.into(),
-            GenericParamDefKind::Type { .. } => {
-                bug!("empty_substs_for_def_id: {:?} has type parameters", item_def_id)
-            }
-            GenericParamDefKind::Const { .. } => {
-                bug!("empty_substs_for_def_id: {:?} has const parameters", item_def_id)
-            }
-        })
-    }
-
-    /// Returns `true` if the node pointed to by `def_id` is a `static` item.
-    pub fn is_static(&self, def_id: DefId) -> bool {
-        self.static_mutability(def_id).is_some()
-    }
-
-    /// Returns `true` if the node pointed to by `def_id` is a mutable `static` item.
-    pub fn is_mutable_static(&self, def_id: DefId) -> bool {
-        self.static_mutability(def_id) == Some(hir::Mutability::Mut)
-    }
-
-    /// Get the type of the pointer to the static that we use in MIR.
-    pub fn static_ptr_ty(&self, def_id: DefId) -> Ty<'tcx> {
-        // Make sure that any constants in the static's type are evaluated.
-        let static_ty = self.normalize_erasing_regions(ty::ParamEnv::empty(), self.type_of(def_id));
-
-        if self.is_mutable_static(def_id) {
-            self.mk_mut_ptr(static_ty)
-        } else {
-            self.mk_imm_ref(self.lifetimes.re_erased, static_ty)
-        }
-    }
-
-    /// Expands the given impl trait type, stopping if the type is recursive.
-    pub fn try_expand_impl_trait_type(
-        self,
-        def_id: DefId,
-        substs: SubstsRef<'tcx>,
-    ) -> Result<Ty<'tcx>, Ty<'tcx>> {
-        use crate::ty::fold::TypeFolder;
-
-        struct OpaqueTypeExpander<'tcx> {
-            // Contains the DefIds of the opaque types that are currently being
-            // expanded. When we expand an opaque type we insert the DefId of
-            // that type, and when we finish expanding that type we remove the
-            // its DefId.
-            seen_opaque_tys: FxHashSet<DefId>,
-            // Cache of all expansions we've seen so far. This is a critical
-            // optimization for some large types produced by async fn trees.
-            expanded_cache: FxHashMap<(DefId, SubstsRef<'tcx>), Ty<'tcx>>,
-            primary_def_id: DefId,
-            found_recursion: bool,
-            tcx: TyCtxt<'tcx>,
-        }
-
-        impl<'tcx> OpaqueTypeExpander<'tcx> {
-            fn expand_opaque_ty(
-                &mut self,
-                def_id: DefId,
-                substs: SubstsRef<'tcx>,
-            ) -> Option<Ty<'tcx>> {
-                if self.found_recursion {
-                    return None;
-                }
-                let substs = substs.fold_with(self);
-                if self.seen_opaque_tys.insert(def_id) {
-                    let expanded_ty = match self.expanded_cache.get(&(def_id, substs)) {
-                        Some(expanded_ty) => expanded_ty,
-                        None => {
-                            let generic_ty = self.tcx.type_of(def_id);
-                            let concrete_ty = generic_ty.subst(self.tcx, substs);
-                            let expanded_ty = self.fold_ty(concrete_ty);
-                            self.expanded_cache.insert((def_id, substs), expanded_ty);
-                            expanded_ty
-                        }
-                    };
-                    self.seen_opaque_tys.remove(&def_id);
-                    Some(expanded_ty)
-                } else {
-                    // If another opaque type that we contain is recursive, then it
-                    // will report the error, so we don't have to.
-                    self.found_recursion = def_id == self.primary_def_id;
-                    None
-                }
-            }
-        }
-
-        impl<'tcx> TypeFolder<'tcx> for OpaqueTypeExpander<'tcx> {
-            fn tcx(&self) -> TyCtxt<'tcx> {
-                self.tcx
-            }
-
-            fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
-                if let ty::Opaque(def_id, substs) = t.kind {
-                    self.expand_opaque_ty(def_id, substs).unwrap_or(t)
-                } else if t.has_opaque_types() {
-                    t.super_fold_with(self)
-                } else {
-                    t
-                }
-            }
-        }
-
-        let mut visitor = OpaqueTypeExpander {
-            seen_opaque_tys: FxHashSet::default(),
-            expanded_cache: FxHashMap::default(),
-            primary_def_id: def_id,
-            found_recursion: false,
-            tcx: self,
-        };
-        let expanded_type = visitor.expand_opaque_ty(def_id, substs).unwrap();
-        if visitor.found_recursion { Err(expanded_type) } else { Ok(expanded_type) }
-    }
-}
-
-impl<'tcx> ty::TyS<'tcx> {
-    /// Returns the maximum value for the given numeric type (including `char`s)
-    /// or returns `None` if the type is not numeric.
-    pub fn numeric_max_val(&'tcx self, tcx: TyCtxt<'tcx>) -> Option<&'tcx ty::Const<'tcx>> {
-        let val = match self.kind {
-            ty::Int(_) | ty::Uint(_) => {
-                let (size, signed) = int_size_and_signed(tcx, self);
-                let val = if signed { signed_max(size) as u128 } else { unsigned_max(size) };
-                Some(val)
-            }
-            ty::Char => Some(std::char::MAX as u128),
-            ty::Float(fty) => Some(match fty {
-                ast::FloatTy::F32 => ::rustc_apfloat::ieee::Single::INFINITY.to_bits(),
-                ast::FloatTy::F64 => ::rustc_apfloat::ieee::Double::INFINITY.to_bits(),
-            }),
-            _ => None,
-        };
-        val.map(|v| ty::Const::from_bits(tcx, v, ty::ParamEnv::empty().and(self)))
-    }
-
-    /// Returns the minimum value for the given numeric type (including `char`s)
-    /// or returns `None` if the type is not numeric.
-    pub fn numeric_min_val(&'tcx self, tcx: TyCtxt<'tcx>) -> Option<&'tcx ty::Const<'tcx>> {
-        let val = match self.kind {
-            ty::Int(_) | ty::Uint(_) => {
-                let (size, signed) = int_size_and_signed(tcx, self);
-                let val = if signed { truncate(signed_min(size) as u128, size) } else { 0 };
-                Some(val)
-            }
-            ty::Char => Some(0),
-            ty::Float(fty) => Some(match fty {
-                ast::FloatTy::F32 => (-::rustc_apfloat::ieee::Single::INFINITY).to_bits(),
-                ast::FloatTy::F64 => (-::rustc_apfloat::ieee::Double::INFINITY).to_bits(),
-            }),
-            _ => None,
-        };
-        val.map(|v| ty::Const::from_bits(tcx, v, ty::ParamEnv::empty().and(self)))
-    }
-
-    /// Checks whether values of this type `T` are *moved* or *copied*
-    /// when referenced -- this amounts to a check for whether `T:
-    /// Copy`, but note that we **don't** consider lifetimes when
-    /// doing this check. This means that we may generate MIR which
-    /// does copies even when the type actually doesn't satisfy the
-    /// full requirements for the `Copy` trait (cc #29149) -- this
-    /// winds up being reported as an error during NLL borrow check.
-    pub fn is_copy_modulo_regions(
-        &'tcx self,
-        tcx: TyCtxt<'tcx>,
-        param_env: ty::ParamEnv<'tcx>,
-        span: Span,
-    ) -> bool {
-        tcx.at(span).is_copy_raw(param_env.and(self))
-    }
-
-    /// Checks whether values of this type `T` have a size known at
-    /// compile time (i.e., whether `T: Sized`). Lifetimes are ignored
-    /// for the purposes of this check, so it can be an
-    /// over-approximation in generic contexts, where one can have
-    /// strange rules like `<T as Foo<'static>>::Bar: Sized` that
-    /// actually carry lifetime requirements.
-    pub fn is_sized(&'tcx self, tcx_at: TyCtxtAt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool {
-        self.is_trivially_sized(tcx_at.tcx) || tcx_at.is_sized_raw(param_env.and(self))
-    }
-
-    /// Checks whether values of this type `T` implement the `Freeze`
-    /// trait -- frozen types are those that do not contain a
-    /// `UnsafeCell` anywhere. This is a language concept used to
-    /// distinguish "true immutability", which is relevant to
-    /// optimization as well as the rules around static values. Note
-    /// that the `Freeze` trait is not exposed to end users and is
-    /// effectively an implementation detail.
-    pub fn is_freeze(
-        &'tcx self,
-        tcx: TyCtxt<'tcx>,
-        param_env: ty::ParamEnv<'tcx>,
-        span: Span,
-    ) -> bool {
-        self.is_trivially_freeze() || tcx.at(span).is_freeze_raw(param_env.and(self))
-    }
-
-    /// Fast path helper for testing if a type is `Freeze`.
-    ///
-    /// Returning true means the type is known to be `Freeze`. Returning
-    /// `false` means nothing -- could be `Freeze`, might not be.
-    fn is_trivially_freeze(&self) -> bool {
-        match self.kind {
-            ty::Int(_)
-            | ty::Uint(_)
-            | ty::Float(_)
-            | ty::Bool
-            | ty::Char
-            | ty::Str
-            | ty::Never
-            | ty::Ref(..)
-            | ty::RawPtr(_)
-            | ty::FnDef(..)
-            | ty::Error
-            | ty::FnPtr(_) => true,
-            ty::Tuple(_) => self.tuple_fields().all(Self::is_trivially_freeze),
-            ty::Slice(elem_ty) | ty::Array(elem_ty, _) => elem_ty.is_trivially_freeze(),
-            ty::Adt(..)
-            | ty::Bound(..)
-            | ty::Closure(..)
-            | ty::Dynamic(..)
-            | ty::Foreign(_)
-            | ty::Generator(..)
-            | ty::GeneratorWitness(_)
-            | ty::Infer(_)
-            | ty::Opaque(..)
-            | ty::Param(_)
-            | ty::Placeholder(_)
-            | ty::Projection(_)
-            | ty::UnnormalizedProjection(_) => false,
-        }
-    }
-
-    /// If `ty.needs_drop(...)` returns `true`, then `ty` is definitely
-    /// non-copy and *might* have a destructor attached; if it returns
-    /// `false`, then `ty` definitely has no destructor (i.e., no drop glue).
-    ///
-    /// (Note that this implies that if `ty` has a destructor attached,
-    /// then `needs_drop` will definitely return `true` for `ty`.)
-    ///
-    /// Note that this method is used to check eligible types in unions.
-    #[inline]
-    pub fn needs_drop(&'tcx self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool {
-        // Avoid querying in simple cases.
-        match needs_drop_components(self, &tcx.data_layout) {
-            Err(AlwaysRequiresDrop) => true,
-            Ok(components) => {
-                let query_ty = match *components {
-                    [] => return false,
-                    // If we've got a single component, call the query with that
-                    // to increase the chance that we hit the query cache.
-                    [component_ty] => component_ty,
-                    _ => self,
-                };
-                // This doesn't depend on regions, so try to minimize distinct
-                // query keys used.
-                let erased = tcx.normalize_erasing_regions(param_env, query_ty);
-                tcx.needs_drop_raw(param_env.and(erased))
-            }
-        }
-    }
-
-    pub fn same_type(a: Ty<'tcx>, b: Ty<'tcx>) -> bool {
-        match (&a.kind, &b.kind) {
-            (&Adt(did_a, substs_a), &Adt(did_b, substs_b)) => {
-                if did_a != did_b {
-                    return false;
-                }
-
-                substs_a.types().zip(substs_b.types()).all(|(a, b)| Self::same_type(a, b))
-            }
-            _ => a == b,
-        }
-    }
-
-    /// Check whether a type is representable. This means it cannot contain unboxed
-    /// structural recursion. This check is needed for structs and enums.
-    pub fn is_representable(&'tcx self, tcx: TyCtxt<'tcx>, sp: Span) -> Representability {
-        // Iterate until something non-representable is found
-        fn fold_repr<It: Iterator<Item = Representability>>(iter: It) -> Representability {
-            iter.fold(Representability::Representable, |r1, r2| match (r1, r2) {
-                (Representability::SelfRecursive(v1), Representability::SelfRecursive(v2)) => {
-                    Representability::SelfRecursive(v1.into_iter().chain(v2).collect())
-                }
-                (r1, r2) => cmp::max(r1, r2),
-            })
-        }
-
-        fn are_inner_types_recursive<'tcx>(
-            tcx: TyCtxt<'tcx>,
-            sp: Span,
-            seen: &mut Vec<Ty<'tcx>>,
-            representable_cache: &mut FxHashMap<Ty<'tcx>, Representability>,
-            ty: Ty<'tcx>,
-        ) -> Representability {
-            match ty.kind {
-                Tuple(..) => {
-                    // Find non representable
-                    fold_repr(ty.tuple_fields().map(|ty| {
-                        is_type_structurally_recursive(tcx, sp, seen, representable_cache, ty)
-                    }))
-                }
-                // Fixed-length vectors.
-                // FIXME(#11924) Behavior undecided for zero-length vectors.
-                Array(ty, _) => {
-                    is_type_structurally_recursive(tcx, sp, seen, representable_cache, ty)
-                }
-                Adt(def, substs) => {
-                    // Find non representable fields with their spans
-                    fold_repr(def.all_fields().map(|field| {
-                        let ty = field.ty(tcx, substs);
-                        let span = tcx.hir().span_if_local(field.did).unwrap_or(sp);
-                        match is_type_structurally_recursive(
-                            tcx,
-                            span,
-                            seen,
-                            representable_cache,
-                            ty,
-                        ) {
-                            Representability::SelfRecursive(_) => {
-                                Representability::SelfRecursive(vec![span])
-                            }
-                            x => x,
-                        }
-                    }))
-                }
-                Closure(..) => {
-                    // this check is run on type definitions, so we don't expect
-                    // to see closure types
-                    bug!("requires check invoked on inapplicable type: {:?}", ty)
-                }
-                _ => Representability::Representable,
-            }
-        }
-
-        fn same_struct_or_enum<'tcx>(ty: Ty<'tcx>, def: &'tcx ty::AdtDef) -> bool {
-            match ty.kind {
-                Adt(ty_def, _) => ty_def == def,
-                _ => false,
-            }
-        }
-
-        // Does the type `ty` directly (without indirection through a pointer)
-        // contain any types on stack `seen`?
-        fn is_type_structurally_recursive<'tcx>(
-            tcx: TyCtxt<'tcx>,
-            sp: Span,
-            seen: &mut Vec<Ty<'tcx>>,
-            representable_cache: &mut FxHashMap<Ty<'tcx>, Representability>,
-            ty: Ty<'tcx>,
-        ) -> Representability {
-            debug!("is_type_structurally_recursive: {:?} {:?}", ty, sp);
-            if let Some(representability) = representable_cache.get(ty) {
-                debug!(
-                    "is_type_structurally_recursive: {:?} {:?} - (cached) {:?}",
-                    ty, sp, representability
-                );
-                return representability.clone();
-            }
-
-            let representability =
-                is_type_structurally_recursive_inner(tcx, sp, seen, representable_cache, ty);
-
-            representable_cache.insert(ty, representability.clone());
-            representability
-        }
-
-        fn is_type_structurally_recursive_inner<'tcx>(
-            tcx: TyCtxt<'tcx>,
-            sp: Span,
-            seen: &mut Vec<Ty<'tcx>>,
-            representable_cache: &mut FxHashMap<Ty<'tcx>, Representability>,
-            ty: Ty<'tcx>,
-        ) -> Representability {
-            match ty.kind {
-                Adt(def, _) => {
-                    {
-                        // Iterate through stack of previously seen types.
-                        let mut iter = seen.iter();
-
-                        // The first item in `seen` is the type we are actually curious about.
-                        // We want to return SelfRecursive if this type contains itself.
-                        // It is important that we DON'T take generic parameters into account
-                        // for this check, so that Bar<T> in this example counts as SelfRecursive:
-                        //
-                        // struct Foo;
-                        // struct Bar<T> { x: Bar<Foo> }
-
-                        if let Some(&seen_type) = iter.next() {
-                            if same_struct_or_enum(seen_type, def) {
-                                debug!("SelfRecursive: {:?} contains {:?}", seen_type, ty);
-                                return Representability::SelfRecursive(vec![sp]);
-                            }
-                        }
-
-                        // We also need to know whether the first item contains other types
-                        // that are structurally recursive. If we don't catch this case, we
-                        // will recurse infinitely for some inputs.
-                        //
-                        // It is important that we DO take generic parameters into account
-                        // here, so that code like this is considered SelfRecursive, not
-                        // ContainsRecursive:
-                        //
-                        // struct Foo { Option<Option<Foo>> }
-
-                        for &seen_type in iter {
-                            if ty::TyS::same_type(ty, seen_type) {
-                                debug!("ContainsRecursive: {:?} contains {:?}", seen_type, ty);
-                                return Representability::ContainsRecursive;
-                            }
-                        }
-                    }
-
-                    // For structs and enums, track all previously seen types by pushing them
-                    // onto the 'seen' stack.
-                    seen.push(ty);
-                    let out = are_inner_types_recursive(tcx, sp, seen, representable_cache, ty);
-                    seen.pop();
-                    out
-                }
-                _ => {
-                    // No need to push in other cases.
-                    are_inner_types_recursive(tcx, sp, seen, representable_cache, ty)
-                }
-            }
-        }
-
-        debug!("is_type_representable: {:?}", self);
-
-        // To avoid a stack overflow when checking an enum variant or struct that
-        // contains a different, structurally recursive type, maintain a stack
-        // of seen types and check recursion for each of them (issues #3008, #3779).
-        let mut seen: Vec<Ty<'_>> = Vec::new();
-        let mut representable_cache = FxHashMap::default();
-        let r = is_type_structurally_recursive(tcx, sp, &mut seen, &mut representable_cache, self);
-        debug!("is_type_representable: {:?} is {:?}", self, r);
-        r
-    }
-
-    /// Peel off all reference types in this type until there are none left.
-    ///
-    /// This method is idempotent, i.e. `ty.peel_refs().peel_refs() == ty.peel_refs()`.
-    ///
-    /// # Examples
-    ///
-    /// - `u8` -> `u8`
-    /// - `&'a mut u8` -> `u8`
-    /// - `&'a &'b u8` -> `u8`
-    /// - `&'a *const &'b u8 -> *const &'b u8`
-    pub fn peel_refs(&'tcx self) -> Ty<'tcx> {
-        let mut ty = self;
-        while let Ref(_, inner_ty, _) = ty.kind {
-            ty = inner_ty;
-        }
-        ty
-    }
-}
-
-pub enum ExplicitSelf<'tcx> {
-    ByValue,
-    ByReference(ty::Region<'tcx>, hir::Mutability),
-    ByRawPointer(hir::Mutability),
-    ByBox,
-    Other,
-}
-
-impl<'tcx> ExplicitSelf<'tcx> {
-    /// Categorizes an explicit self declaration like `self: SomeType`
-    /// into either `self`, `&self`, `&mut self`, `Box<self>`, or
-    /// `Other`.
-    /// This is mainly used to require the arbitrary_self_types feature
-    /// in the case of `Other`, to improve error messages in the common cases,
-    /// and to make `Other` non-object-safe.
-    ///
-    /// Examples:
-    ///
-    /// ```
-    /// impl<'a> Foo for &'a T {
-    ///     // Legal declarations:
-    ///     fn method1(self: &&'a T); // ExplicitSelf::ByReference
-    ///     fn method2(self: &'a T); // ExplicitSelf::ByValue
-    ///     fn method3(self: Box<&'a T>); // ExplicitSelf::ByBox
-    ///     fn method4(self: Rc<&'a T>); // ExplicitSelf::Other
-    ///
-    ///     // Invalid cases will be caught by `check_method_receiver`:
-    ///     fn method_err1(self: &'a mut T); // ExplicitSelf::Other
-    ///     fn method_err2(self: &'static T) // ExplicitSelf::ByValue
-    ///     fn method_err3(self: &&T) // ExplicitSelf::ByReference
-    /// }
-    /// ```
-    ///
-    pub fn determine<P>(self_arg_ty: Ty<'tcx>, is_self_ty: P) -> ExplicitSelf<'tcx>
-    where
-        P: Fn(Ty<'tcx>) -> bool,
-    {
-        use self::ExplicitSelf::*;
-
-        match self_arg_ty.kind {
-            _ if is_self_ty(self_arg_ty) => ByValue,
-            ty::Ref(region, ty, mutbl) if is_self_ty(ty) => ByReference(region, mutbl),
-            ty::RawPtr(ty::TypeAndMut { ty, mutbl }) if is_self_ty(ty) => ByRawPointer(mutbl),
-            ty::Adt(def, _) if def.is_box() && is_self_ty(self_arg_ty.boxed_ty()) => ByBox,
-            _ => Other,
-        }
-    }
-}
-
-/// Returns a list of types such that the given type needs drop if and only if
-/// *any* of the returned types need drop. Returns `Err(AlwaysRequiresDrop)` if
-/// this type always needs drop.
-pub fn needs_drop_components(
-    ty: Ty<'tcx>,
-    target_layout: &TargetDataLayout,
-) -> Result<SmallVec<[Ty<'tcx>; 2]>, AlwaysRequiresDrop> {
-    match ty.kind {
-        ty::Infer(ty::FreshIntTy(_))
-        | ty::Infer(ty::FreshFloatTy(_))
-        | ty::Bool
-        | ty::Int(_)
-        | ty::Uint(_)
-        | ty::Float(_)
-        | ty::Never
-        | ty::FnDef(..)
-        | ty::FnPtr(_)
-        | ty::Char
-        | ty::GeneratorWitness(..)
-        | ty::RawPtr(_)
-        | ty::Ref(..)
-        | ty::Str => Ok(SmallVec::new()),
-
-        // Foreign types can never have destructors.
-        ty::Foreign(..) => Ok(SmallVec::new()),
-
-        // Pessimistically assume that all generators will require destructors
-        // as we don't know if a destructor is a noop or not until after the MIR
-        // state transformation pass.
-        ty::Generator(..) | ty::Dynamic(..) | ty::Error => Err(AlwaysRequiresDrop),
-
-        ty::Slice(ty) => needs_drop_components(ty, target_layout),
-        ty::Array(elem_ty, size) => {
-            match needs_drop_components(elem_ty, target_layout) {
-                Ok(v) if v.is_empty() => Ok(v),
-                res => match size.val.try_to_bits(target_layout.pointer_size) {
-                    // Arrays of size zero don't need drop, even if their element
-                    // type does.
-                    Some(0) => Ok(SmallVec::new()),
-                    Some(_) => res,
-                    // We don't know which of the cases above we are in, so
-                    // return the whole type and let the caller decide what to
-                    // do.
-                    None => Ok(smallvec![ty]),
-                },
-            }
-        }
-        // If any field needs drop, then the whole tuple does.
-        ty::Tuple(..) => ty.tuple_fields().try_fold(SmallVec::new(), move |mut acc, elem| {
-            acc.extend(needs_drop_components(elem, target_layout)?);
-            Ok(acc)
-        }),
-
-        // These require checking for `Copy` bounds or `Adt` destructors.
-        ty::Adt(..)
-        | ty::Projection(..)
-        | ty::UnnormalizedProjection(..)
-        | ty::Param(_)
-        | ty::Bound(..)
-        | ty::Placeholder(..)
-        | ty::Opaque(..)
-        | ty::Infer(_)
-        | ty::Closure(..) => Ok(smallvec![ty]),
-    }
-}
-
-#[derive(Copy, Clone, Debug, HashStable, RustcEncodable, RustcDecodable)]
-pub struct AlwaysRequiresDrop;
diff --git a/src/librustc/ty/walk.rs b/src/librustc/ty/walk.rs
deleted file mode 100644
index da08fbcf144..00000000000
--- a/src/librustc/ty/walk.rs
+++ /dev/null
@@ -1,138 +0,0 @@
-//! An iterator over the type substructure.
-//! WARNING: this does not keep track of the region depth.
-
-use crate::ty::{self, Ty};
-use smallvec::{self, SmallVec};
-
-// The TypeWalker's stack is hot enough that it's worth going to some effort to
-// avoid heap allocations.
-pub type TypeWalkerArray<'tcx> = [Ty<'tcx>; 8];
-pub type TypeWalkerStack<'tcx> = SmallVec<TypeWalkerArray<'tcx>>;
-
-pub struct TypeWalker<'tcx> {
-    stack: TypeWalkerStack<'tcx>,
-    last_subtree: usize,
-}
-
-impl<'tcx> TypeWalker<'tcx> {
-    pub fn new(ty: Ty<'tcx>) -> TypeWalker<'tcx> {
-        TypeWalker { stack: smallvec![ty], last_subtree: 1 }
-    }
-
-    /// Skips the subtree of types corresponding to the last type
-    /// returned by `next()`.
-    ///
-    /// Example: Imagine you are walking `Foo<Bar<int>, usize>`.
-    ///
-    /// ```
-    /// let mut iter: TypeWalker = ...;
-    /// iter.next(); // yields Foo
-    /// iter.next(); // yields Bar<int>
-    /// iter.skip_current_subtree(); // skips int
-    /// iter.next(); // yields usize
-    /// ```
-    pub fn skip_current_subtree(&mut self) {
-        self.stack.truncate(self.last_subtree);
-    }
-}
-
-impl<'tcx> Iterator for TypeWalker<'tcx> {
-    type Item = Ty<'tcx>;
-
-    fn next(&mut self) -> Option<Ty<'tcx>> {
-        debug!("next(): stack={:?}", self.stack);
-        match self.stack.pop() {
-            None => None,
-            Some(ty) => {
-                self.last_subtree = self.stack.len();
-                push_subtypes(&mut self.stack, ty);
-                debug!("next: stack={:?}", self.stack);
-                Some(ty)
-            }
-        }
-    }
-}
-
-pub fn walk_shallow(ty: Ty<'_>) -> smallvec::IntoIter<TypeWalkerArray<'_>> {
-    let mut stack = SmallVec::new();
-    push_subtypes(&mut stack, ty);
-    stack.into_iter()
-}
-
-// We push types on the stack in reverse order so as to
-// maintain a pre-order traversal. As of the time of this
-// writing, the fact that the traversal is pre-order is not
-// known to be significant to any code, but it seems like the
-// natural order one would expect (basically, the order of the
-// types as they are written).
-fn push_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent_ty: Ty<'tcx>) {
-    match parent_ty.kind {
-        ty::Bool
-        | ty::Char
-        | ty::Int(_)
-        | ty::Uint(_)
-        | ty::Float(_)
-        | ty::Str
-        | ty::Infer(_)
-        | ty::Param(_)
-        | ty::Never
-        | ty::Error
-        | ty::Placeholder(..)
-        | ty::Bound(..)
-        | ty::Foreign(..) => {}
-        ty::Array(ty, len) => {
-            if let ty::ConstKind::Unevaluated(_, substs, promoted) = len.val {
-                assert!(promoted.is_none());
-                stack.extend(substs.types().rev());
-            }
-            stack.push(len.ty);
-            stack.push(ty);
-        }
-        ty::Slice(ty) => {
-            stack.push(ty);
-        }
-        ty::RawPtr(ref mt) => {
-            stack.push(mt.ty);
-        }
-        ty::Ref(_, ty, _) => {
-            stack.push(ty);
-        }
-        ty::Projection(ref data) | ty::UnnormalizedProjection(ref data) => {
-            stack.extend(data.substs.types().rev());
-        }
-        ty::Dynamic(ref obj, ..) => {
-            stack.extend(obj.iter().rev().flat_map(|predicate| {
-                let (substs, opt_ty) = match *predicate.skip_binder() {
-                    ty::ExistentialPredicate::Trait(tr) => (tr.substs, None),
-                    ty::ExistentialPredicate::Projection(p) => (p.substs, Some(p.ty)),
-                    ty::ExistentialPredicate::AutoTrait(_) =>
-                    // Empty iterator
-                    {
-                        (ty::InternalSubsts::empty(), None)
-                    }
-                };
-
-                substs.types().rev().chain(opt_ty)
-            }));
-        }
-        ty::Adt(_, substs) | ty::Opaque(_, substs) => {
-            stack.extend(substs.types().rev());
-        }
-        ty::Closure(_, ref substs) | ty::Generator(_, ref substs, _) => {
-            stack.extend(substs.types().rev());
-        }
-        ty::GeneratorWitness(ts) => {
-            stack.extend(ts.skip_binder().iter().cloned().rev());
-        }
-        ty::Tuple(..) => {
-            stack.extend(parent_ty.tuple_fields().rev());
-        }
-        ty::FnDef(_, substs) => {
-            stack.extend(substs.types().rev());
-        }
-        ty::FnPtr(sig) => {
-            stack.push(sig.skip_binder().output());
-            stack.extend(sig.skip_binder().inputs().iter().cloned().rev());
-        }
-    }
-}
diff --git a/src/librustc/util/bug.rs b/src/librustc/util/bug.rs
deleted file mode 100644
index c12b2859f72..00000000000
--- a/src/librustc/util/bug.rs
+++ /dev/null
@@ -1,41 +0,0 @@
-// These functions are used by macro expansion for bug! and span_bug!
-
-use crate::ty::tls;
-use rustc_span::{MultiSpan, Span};
-use std::fmt;
-
-#[cold]
-#[inline(never)]
-pub fn bug_fmt(file: &'static str, line: u32, args: fmt::Arguments<'_>) -> ! {
-    // this wrapper mostly exists so I don't have to write a fully
-    // qualified path of None::<Span> inside the bug!() macro definition
-    opt_span_bug_fmt(file, line, None::<Span>, args);
-}
-
-#[cold]
-#[inline(never)]
-pub fn span_bug_fmt<S: Into<MultiSpan>>(
-    file: &'static str,
-    line: u32,
-    span: S,
-    args: fmt::Arguments<'_>,
-) -> ! {
-    opt_span_bug_fmt(file, line, Some(span), args);
-}
-
-fn opt_span_bug_fmt<S: Into<MultiSpan>>(
-    file: &'static str,
-    line: u32,
-    span: Option<S>,
-    args: fmt::Arguments<'_>,
-) -> ! {
-    tls::with_opt(move |tcx| {
-        let msg = format!("{}:{}: {}", file, line, args);
-        match (tcx, span) {
-            (Some(tcx), Some(span)) => tcx.sess.diagnostic().span_bug(span, &msg),
-            (Some(tcx), None) => tcx.sess.diagnostic().bug(&msg),
-            (None, _) => panic!(msg),
-        }
-    });
-    unreachable!();
-}
diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs
deleted file mode 100644
index 19b43bfd162..00000000000
--- a/src/librustc/util/common.rs
+++ /dev/null
@@ -1,71 +0,0 @@
-#![allow(non_camel_case_types)]
-
-use rustc_data_structures::sync::Lock;
-
-use std::fmt::Debug;
-use std::time::{Duration, Instant};
-
-#[cfg(test)]
-mod tests;
-
-pub use rustc_errors::ErrorReported;
-
-pub fn to_readable_str(mut val: usize) -> String {
-    let mut groups = vec![];
-    loop {
-        let group = val % 1000;
-
-        val /= 1000;
-
-        if val == 0 {
-            groups.push(group.to_string());
-            break;
-        } else {
-            groups.push(format!("{:03}", group));
-        }
-    }
-
-    groups.reverse();
-
-    groups.join("_")
-}
-
-pub fn record_time<T, F>(accu: &Lock<Duration>, f: F) -> T
-where
-    F: FnOnce() -> T,
-{
-    let start = Instant::now();
-    let rv = f();
-    let duration = start.elapsed();
-    let mut accu = accu.lock();
-    *accu = *accu + duration;
-    rv
-}
-
-pub fn indent<R, F>(op: F) -> R
-where
-    R: Debug,
-    F: FnOnce() -> R,
-{
-    // Use in conjunction with the log post-processor like `src/etc/indenter`
-    // to make debug output more readable.
-    debug!(">>");
-    let r = op();
-    debug!("<< (Result = {:?})", r);
-    r
-}
-
-pub struct Indenter {
-    _cannot_construct_outside_of_this_module: (),
-}
-
-impl Drop for Indenter {
-    fn drop(&mut self) {
-        debug!("<<");
-    }
-}
-
-pub fn indenter() -> Indenter {
-    debug!(">>");
-    Indenter { _cannot_construct_outside_of_this_module: () }
-}
diff --git a/src/librustc/util/common/tests.rs b/src/librustc/util/common/tests.rs
deleted file mode 100644
index 9a9fb203c62..00000000000
--- a/src/librustc/util/common/tests.rs
+++ /dev/null
@@ -1,14 +0,0 @@
-use super::*;
-
-#[test]
-fn test_to_readable_str() {
-    assert_eq!("0", to_readable_str(0));
-    assert_eq!("1", to_readable_str(1));
-    assert_eq!("99", to_readable_str(99));
-    assert_eq!("999", to_readable_str(999));
-    assert_eq!("1_000", to_readable_str(1_000));
-    assert_eq!("1_001", to_readable_str(1_001));
-    assert_eq!("999_999", to_readable_str(999_999));
-    assert_eq!("1_000_000", to_readable_str(1_000_000));
-    assert_eq!("1_234_567", to_readable_str(1_234_567));
-}