about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-03-23 03:10:48 +0000
committerbors <bors@rust-lang.org>2020-03-23 03:10:48 +0000
commit37c945dd6178cb520eb1e450a795f8c3b3cc5a3b (patch)
tree2dbbb36335d426f3c13c4cde0eafaadfb7023968
parente4b01c7791446b2f79a1b1d517223378df2bf5f2 (diff)
parent40cec7854b8422b47a7d917556694e3abbbb2d2e (diff)
downloadrust-37c945dd6178cb520eb1e450a795f8c3b3cc5a3b.tar.gz
rust-37c945dd6178cb520eb1e450a795f8c3b3cc5a3b.zip
Auto merge of #70204 - Centril:unshackled-lowering, r=Zoxc
Liberate `rustc_ast_lowering` from `rustc`

The whole point of this PR is the very last commit, in which we remove `rustc` as one of `rustc_ast_lowering`'s dependencies, thereby improving `./x.py` parallelism and working towards https://github.com/rust-lang/rust/issues/65031.

Noteworthy:
- From `rustc::arena` we move logic into `arena`, in particular `declare_arena!`. This is then used in `rustc_ast_lowering` so that lowering has its own separate arena.
- Some linting code is unfortunately moved to `rustc_session::lint` cause its used both in `rustc_lint` and `rustc_ast_lowering`, and this is their common dependency.
- `rustc_session::CrateDisambiguator` is moved into `rustc_ast` so that `rustc::hir::map::definitions` can be moved into `rustc_hir`, so that `rustc_ast_lowering` can stop referring to `rustc::hir`.

r? @Zoxc
-rw-r--r--Cargo.lock3
-rw-r--r--src/libarena/lib.rs182
-rw-r--r--src/librustc/arena.rs230
-rw-r--r--src/librustc/hir/map/mod.rs7
-rw-r--r--src/librustc/lint.rs44
-rw-r--r--src/librustc/ty/codec.rs1
-rw-r--r--src/librustc_ast/crate_disambiguator.rs35
-rw-r--r--src/librustc_ast/lib.rs1
-rw-r--r--src/librustc_ast_lowering/Cargo.toml2
-rw-r--r--src/librustc_ast_lowering/expr.rs3
-rw-r--r--src/librustc_ast_lowering/item.rs9
-rw-r--r--src/librustc_ast_lowering/lib.rs25
-rw-r--r--src/librustc_ast_lowering/path.rs16
-rw-r--r--src/librustc_hir/Cargo.toml1
-rw-r--r--src/librustc_hir/arena.rs49
-rw-r--r--src/librustc_hir/definitions.rs (renamed from src/librustc/hir/map/definitions.rs)14
-rw-r--r--src/librustc_hir/lib.rs2
-rw-r--r--src/librustc_interface/passes.rs8
-rw-r--r--src/librustc_interface/queries.rs6
-rw-r--r--src/librustc_lint/context.rs5
-rw-r--r--src/librustc_metadata/rmeta/decoder.rs4
-rw-r--r--src/librustc_metadata/rmeta/decoder/cstore_impl.rs4
-rw-r--r--src/librustc_metadata/rmeta/encoder.rs2
-rw-r--r--src/librustc_resolve/def_collector.rs2
-rw-r--r--src/librustc_session/lint.rs43
-rw-r--r--src/librustc_session/session.rs59
-rw-r--r--src/librustc_traits/lowering/mod.rs2
27 files changed, 384 insertions, 375 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 5f6cda66ebf..c65c3a45ec2 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3477,8 +3477,8 @@ dependencies = [
 name = "rustc_ast_lowering"
 version = "0.0.0"
 dependencies = [
+ "arena",
  "log",
- "rustc",
  "rustc_ast",
  "rustc_ast_pretty",
  "rustc_data_structures",
@@ -3725,6 +3725,7 @@ name = "rustc_hir"
 version = "0.0.0"
 dependencies = [
  "lazy_static 1.4.0",
+ "log",
  "rustc_ast",
  "rustc_ast_pretty",
  "rustc_data_structures",
diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs
index 2a3d92edc49..0f0bd617f43 100644
--- a/src/libarena/lib.rs
+++ b/src/libarena/lib.rs
@@ -488,5 +488,187 @@ impl DroplessArena {
     }
 }
 
+/// 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)]
+pub 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]
+    pub 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]
+    pub 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)
+    }
+}
+
+#[macro_export]
+macro_rules! arena_for_type {
+    ([][$ty:ty]) => {
+        $crate::TypedArena<$ty>
+    };
+    ([few $(, $attrs:ident)*][$ty:ty]) => {
+        ::std::marker::PhantomData<$ty>
+    };
+    ([$ignore:ident $(, $attrs:ident)*]$args:tt) => {
+        $crate::arena_for_type!([$($attrs),*]$args)
+    };
+}
+
+#[macro_export]
+macro_rules! which_arena_for_type {
+    ([][$arena:expr]) => {
+        ::std::option::Option::Some($arena)
+    };
+    ([few$(, $attrs:ident)*][$arena:expr]) => {
+        ::std::option::Option::None
+    };
+    ([$ignore:ident$(, $attrs:ident)*]$args:tt) => {
+        $crate::which_arena_for_type!([$($attrs),*]$args)
+    };
+}
+
+#[macro_export]
+macro_rules! declare_arena {
+    ([], [$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) => {
+        #[derive(Default)]
+        pub struct Arena<$tcx> {
+            pub dropless: $crate::DroplessArena,
+            drop: $crate::DropArena,
+            $($name: $crate::arena_for_type!($a[$ty]),)*
+        }
+
+        #[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 $crate::TypedArena<Self>>;
+        }
+
+        unsafe impl<'tcx, T> ArenaField<'tcx> for T {
+            #[inline]
+            default fn arena<'a>(_: &'a Arena<'tcx>) -> Option<&'a $crate::TypedArena<Self>> {
+                panic!()
+            }
+        }
+
+        $(
+            #[allow(unused_lifetimes)]
+            impl<$tcx> ArenaAllocatable for $ty {}
+            unsafe impl<$tcx> ArenaField<$tcx> for $ty {
+                #[inline]
+                fn arena<'a>(_arena: &'a Arena<$tcx>) -> Option<&'a $crate::TypedArena<Self>> {
+                    $crate::which_arena_for_type!($a[&_arena.$name])
+                }
+            }
+        )*
+
+        impl<'tcx> Arena<'tcx> {
+            #[inline]
+            pub fn alloc<T: ArenaAllocatable>(&self, value: T) -> &mut T {
+                if !::std::mem::needs_drop::<T>() {
+                    return self.dropless.alloc(value);
+                }
+                match <T as ArenaField<'tcx>>::arena(self) {
+                    ::std::option::Option::Some(arena) => arena.alloc(value),
+                    ::std::option::Option::None => unsafe { self.drop.alloc(value) },
+                }
+            }
+
+            #[inline]
+            pub fn alloc_slice<T: ::std::marker::Copy>(&self, value: &[T]) -> &mut [T] {
+                if value.is_empty() {
+                    return &mut [];
+                }
+                self.dropless.alloc_slice(value)
+            }
+
+            pub fn alloc_from_iter<'a, T: ArenaAllocatable>(
+                &'a self,
+                iter: impl ::std::iter::IntoIterator<Item = T>,
+            ) -> &'a mut [T] {
+                if !::std::mem::needs_drop::<T>() {
+                    return self.dropless.alloc_from_iter(iter);
+                }
+                match <T as ArenaField<'tcx>>::arena(self) {
+                    ::std::option::Option::Some(arena) => arena.alloc_from_iter(iter),
+                    ::std::option::Option::None => unsafe { self.drop.alloc_from_iter(iter) },
+                }
+            }
+        }
+    }
+}
+
 #[cfg(test)]
 mod tests;
diff --git a/src/librustc/arena.rs b/src/librustc/arena.rs
index bbac5dfd2b8..57c1e5521a9 100644
--- a/src/librustc/arena.rs
+++ b/src/librustc/arena.rs
@@ -1,11 +1,3 @@
-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.
@@ -128,231 +120,13 @@ macro_rules! arena_types {
             // Interned types
             [] tys: rustc::ty::TyS<$tcx>,
 
-            // HIR types
-            [few] hir_krate: rustc_hir::Crate<$tcx>,
-            [] arm: rustc_hir::Arm<$tcx>,
-            [] attribute: rustc_ast::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>,
-
             // HIR query types
             [few] indexed_hir: rustc::hir::map::IndexedHir<$tcx>,
-            [few] hir_definitions: rustc::hir::map::definitions::Definitions,
+            [few] hir_definitions: rustc_hir::definitions::Definitions,
             [] hir_owner: rustc::hir::Owner<$tcx>,
             [] hir_owner_nodes: rustc::hir::OwnerNodes<$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.is_empty() {
-            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)
-    }
-}
+arena_types!(arena::declare_arena, [], 'tcx);
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index cd4b73a3d1f..eb8e57743b8 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -1,7 +1,4 @@
 use self::collector::NodeCollector;
-pub use self::definitions::{
-    DefKey, DefPath, DefPathData, DefPathHash, Definitions, DisambiguatedDefPathData,
-};
 
 use crate::hir::{Owner, OwnerNodes};
 use crate::ty::query::Providers;
@@ -10,6 +7,9 @@ use rustc_ast::ast::{self, Name, NodeId};
 use rustc_data_structures::svh::Svh;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
+pub use rustc_hir::definitions;
+pub use rustc_hir::definitions::{DefKey, DefPath, DefPathData, DefPathHash};
+pub use rustc_hir::definitions::{Definitions, DisambiguatedDefPathData};
 use rustc_hir::intravisit;
 use rustc_hir::itemlikevisit::ItemLikeVisitor;
 use rustc_hir::print::Nested;
@@ -23,7 +23,6 @@ use rustc_target::spec::abi::Abi;
 
 pub mod blocks;
 mod collector;
-pub mod definitions;
 mod hir_id_validator;
 pub use hir_id_validator::check_crate;
 
diff --git a/src/librustc/lint.rs b/src/librustc/lint.rs
index 4dd276d2e03..53061436de0 100644
--- a/src/librustc/lint.rs
+++ b/src/librustc/lint.rs
@@ -3,7 +3,7 @@ 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_errors::{DiagnosticBuilder, DiagnosticId};
 use rustc_hir::HirId;
 use rustc_session::lint::{builtin, Level, Lint, LintId};
 use rustc_session::{DiagnosticMessageId, Session};
@@ -350,45 +350,3 @@ pub fn in_external_macro(sess: &Session, span: Span) -> bool {
         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/ty/codec.rs b/src/librustc/ty/codec.rs
index c305999a64b..cbbc937ed7d 100644
--- a/src/librustc/ty/codec.rs
+++ b/src/librustc/ty/codec.rs
@@ -396,6 +396,7 @@ macro_rules! implement_ty_decoder {
             // the caller to pick any lifetime for `'tcx`, including `'static`,
             // by using the unspecialized proxies to them.
 
+            rustc_hir::arena_types!(impl_arena_allocatable_decoders, [$DecoderName [$($typaram),*]], 'tcx);
             arena_types!(impl_arena_allocatable_decoders, [$DecoderName [$($typaram),*]], 'tcx);
 
             impl<$($typaram),*> SpecializedDecoder<CrateNum>
diff --git a/src/librustc_ast/crate_disambiguator.rs b/src/librustc_ast/crate_disambiguator.rs
new file mode 100644
index 00000000000..95d4c09dac3
--- /dev/null
+++ b/src/librustc_ast/crate_disambiguator.rs
@@ -0,0 +1,35 @@
+// This is here because `rustc_session` wants to refer to it,
+// and so does `rustc_hir`, but `rustc_hir` shouldn't refer to `rustc_session`.
+
+use rustc_data_structures::fingerprint::Fingerprint;
+use rustc_data_structures::{base_n, impl_stable_hash_via_hash};
+
+use std::fmt;
+
+/// Hash value constructed out of all the `-C metadata` arguments passed to the
+/// compiler. Together with the crate-name forms a unique global identifier for
+/// the crate.
+#[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Clone, Copy, RustcEncodable, RustcDecodable)]
+pub struct CrateDisambiguator(Fingerprint);
+
+impl CrateDisambiguator {
+    pub fn to_fingerprint(self) -> Fingerprint {
+        self.0
+    }
+}
+
+impl fmt::Display for CrateDisambiguator {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
+        let (a, b) = self.0.as_value();
+        let as_u128 = a as u128 | ((b as u128) << 64);
+        f.write_str(&base_n::encode(as_u128, base_n::CASE_INSENSITIVE))
+    }
+}
+
+impl From<Fingerprint> for CrateDisambiguator {
+    fn from(fingerprint: Fingerprint) -> CrateDisambiguator {
+        CrateDisambiguator(fingerprint)
+    }
+}
+
+impl_stable_hash_via_hash!(CrateDisambiguator);
diff --git a/src/librustc_ast/lib.rs b/src/librustc_ast/lib.rs
index 2594cc536ac..a93e0fcbd71 100644
--- a/src/librustc_ast/lib.rs
+++ b/src/librustc_ast/lib.rs
@@ -40,6 +40,7 @@ pub mod util {
 pub mod ast;
 pub mod attr;
 pub use attr::{with_default_globals, with_globals, GLOBALS};
+pub mod crate_disambiguator;
 pub mod entry;
 pub mod expand;
 pub mod mut_visit;
diff --git a/src/librustc_ast_lowering/Cargo.toml b/src/librustc_ast_lowering/Cargo.toml
index 23dc80facae..b477b75db5a 100644
--- a/src/librustc_ast_lowering/Cargo.toml
+++ b/src/librustc_ast_lowering/Cargo.toml
@@ -10,8 +10,8 @@ path = "lib.rs"
 doctest = false
 
 [dependencies]
+arena = { path = "../libarena" }
 log = { version = "0.4", features = ["release_max_level_info", "std"] }
-rustc = { path = "../librustc" }
 rustc_ast_pretty = { path = "../librustc_ast_pretty" }
 rustc_hir = { path = "../librustc_hir" }
 rustc_target = { path = "../librustc_target" }
diff --git a/src/librustc_ast_lowering/expr.rs b/src/librustc_ast_lowering/expr.rs
index a212f0a7107..239dec9e974 100644
--- a/src/librustc_ast_lowering/expr.rs
+++ b/src/librustc_ast_lowering/expr.rs
@@ -1,6 +1,5 @@
 use super::{ImplTraitContext, LoweringContext, ParamMode, ParenthesizedGenericArgs};
 
-use rustc::bug;
 use rustc_ast::ast::*;
 use rustc_ast::attr;
 use rustc_ast::ptr::P as AstP;
@@ -757,7 +756,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 Some(movability)
             }
             Some(hir::GeneratorKind::Async(_)) => {
-                bug!("non-`async` closure body turned `async` during lowering");
+                panic!("non-`async` closure body turned `async` during lowering");
             }
             None => {
                 if movability == Movability::Static {
diff --git a/src/librustc_ast_lowering/item.rs b/src/librustc_ast_lowering/item.rs
index c22b2812a9e..e66770a5bee 100644
--- a/src/librustc_ast_lowering/item.rs
+++ b/src/librustc_ast_lowering/item.rs
@@ -1,8 +1,7 @@
 use super::{AnonymousLifetimeMode, LoweringContext, ParamMode};
 use super::{ImplTraitContext, ImplTraitPosition, ImplTraitTypeIdVisitor};
+use crate::Arena;
 
-use rustc::arena::Arena;
-use rustc::bug;
 use rustc_ast::ast::*;
 use rustc_ast::attr;
 use rustc_ast::node_id::NodeMap;
@@ -432,7 +431,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 self.lower_param_bounds(bounds, ImplTraitContext::disallowed()),
             ),
             ItemKind::MacroDef(..) | ItemKind::MacCall(..) => {
-                bug!("`TyMac` should have been expanded by now")
+                panic!("`TyMac` should have been expanded by now")
             }
         }
 
@@ -784,7 +783,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
 
                 (generics, kind)
             }
-            AssocItemKind::MacCall(..) => bug!("macro item shouldn't exist at this point"),
+            AssocItemKind::MacCall(..) => panic!("macro item shouldn't exist at this point"),
         };
 
         hir::TraitItem {
@@ -865,7 +864,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 };
                 (generics, kind)
             }
-            AssocItemKind::MacCall(..) => bug!("`TyMac` should have been expanded by now"),
+            AssocItemKind::MacCall(..) => panic!("`TyMac` should have been expanded by now"),
         };
 
         hir::ImplItem {
diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs
index 24fe51fc4d0..68cb1f8585f 100644
--- a/src/librustc_ast_lowering/lib.rs
+++ b/src/librustc_ast_lowering/lib.rs
@@ -32,12 +32,10 @@
 
 #![feature(array_value_iter)]
 #![feature(crate_visibility_modifier)]
+#![feature(marker_trait_attr)]
+#![feature(specialization)]
 #![recursion_limit = "256"]
 
-use rustc::arena::Arena;
-use rustc::dep_graph::DepGraph;
-use rustc::hir::map::definitions::{DefKey, DefPathData, Definitions};
-use rustc::{bug, span_bug};
 use rustc_ast::ast;
 use rustc_ast::ast::*;
 use rustc_ast::attr;
@@ -54,6 +52,7 @@ use rustc_errors::struct_span_err;
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Namespace, PartialRes, PerNS, Res};
 use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId, CRATE_DEF_INDEX};
+use rustc_hir::definitions::{DefKey, DefPathData, Definitions};
 use rustc_hir::intravisit;
 use rustc_hir::{ConstArg, GenericArg, ParamName};
 use rustc_index::vec::IndexVec;
@@ -85,6 +84,8 @@ mod path;
 
 const HIR_ID_COUNTER_LOCKED: u32 = 0xFFFFFFFF;
 
+rustc_hir::arena_types!(::arena::declare_arena, [], 'tcx);
+
 struct LoweringContext<'a, 'hir: 'a> {
     crate_root: Option<Symbol>,
 
@@ -259,17 +260,11 @@ impl<'a> ImplTraitContext<'_, 'a> {
 
 pub fn lower_crate<'a, 'hir>(
     sess: &'a Session,
-    dep_graph: &'a DepGraph,
     krate: &'a Crate,
     resolver: &'a mut dyn Resolver,
     nt_to_tokenstream: NtToTokenstream,
     arena: &'hir Arena<'hir>,
 ) -> hir::Crate<'hir> {
-    // We're constructing the HIR here; we don't care what we will
-    // read, since we haven't even constructed the *input* to
-    // incr. comp. yet.
-    dep_graph.assert_ignored();
-
     let _prof_timer = sess.prof.verbose_generic_activity("hir_lowering");
 
     LoweringContext {
@@ -672,7 +667,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
     fn expect_full_res(&mut self, id: NodeId) -> Res<NodeId> {
         self.resolver.get_partial_res(id).map_or(Res::Err, |pr| {
             if pr.unresolved_segments() != 0 {
-                bug!("path not fully resolved: {:?}", pr);
+                panic!("path not fully resolved: {:?}", pr);
             }
             pr.base_res()
         })
@@ -1340,7 +1335,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     }
                 }
             }
-            TyKind::MacCall(_) => bug!("`TyKind::MacCall` should have been expanded by now"),
+            TyKind::MacCall(_) => panic!("`TyKind::MacCall` should have been expanded by now"),
             TyKind::CVarArgs => {
                 self.sess.delay_span_bug(
                     t.span,
@@ -1575,7 +1570,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                         hir::LifetimeName::Param(param_name) => {
                             (param_name, hir::LifetimeParamKind::Explicit)
                         }
-                        _ => bug!("expected `LifetimeName::Param` or `ParamName::Plain`"),
+                        _ => panic!("expected `LifetimeName::Param` or `ParamName::Plain`"),
                     };
 
                     self.output_lifetime_params.push(hir::GenericParam {
@@ -2096,7 +2091,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     | hir::LifetimeName::Underscore
                     | hir::LifetimeName::Static => hir::ParamName::Plain(lt.name.ident()),
                     hir::LifetimeName::ImplicitObjectLifetimeDefault => {
-                        span_bug!(
+                        self.sess.diagnostic().span_bug(
                             param.ident.span,
                             "object-lifetime-default should not occur here",
                         );
@@ -2163,7 +2158,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
     ) -> hir::TraitRef<'hir> {
         let path = match self.lower_qpath(p.ref_id, &None, &p.path, ParamMode::Explicit, itctx) {
             hir::QPath::Resolved(None, path) => path,
-            qpath => bug!("lower_trait_ref: unexpected QPath `{:?}`", qpath),
+            qpath => panic!("lower_trait_ref: unexpected QPath `{:?}`", qpath),
         };
         hir::TraitRef { path, hir_ref_id: self.lower_node_id(p.ref_id) }
     }
diff --git a/src/librustc_ast_lowering/path.rs b/src/librustc_ast_lowering/path.rs
index b5b0a3089ce..3c529603d6c 100644
--- a/src/librustc_ast_lowering/path.rs
+++ b/src/librustc_ast_lowering/path.rs
@@ -1,7 +1,6 @@
 use super::{AnonymousLifetimeMode, ImplTraitContext, LoweringContext, ParamMode};
 use super::{GenericArgsCtor, ParenthesizedGenericArgs};
 
-use rustc::span_bug;
 use rustc_ast::ast::{self, *};
 use rustc_errors::{struct_span_err, Applicability};
 use rustc_hir as hir;
@@ -163,12 +162,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         }
 
         // We should've returned in the for loop above.
-        span_bug!(
+
+        self.sess.diagnostic().span_bug(
             p.span,
-            "lower_qpath: no final extension segment in {}..{}",
-            proj_start,
-            p.segments.len()
-        )
+            &format!(
+                "lower_qpath: no final extension segment in {}..{}",
+                proj_start,
+                p.segments.len()
+            ),
+        );
     }
 
     crate fn lower_path_extra(
@@ -304,7 +306,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             E0726,
                             "implicit elided lifetime not allowed here"
                         );
-                        rustc::lint::add_elided_lifetime_in_path_suggestion(
+                        rustc_session::lint::add_elided_lifetime_in_path_suggestion(
                             &self.sess,
                             &mut err,
                             expected_lifetimes,
diff --git a/src/librustc_hir/Cargo.toml b/src/librustc_hir/Cargo.toml
index 872d114fb18..b3682ea5a80 100644
--- a/src/librustc_hir/Cargo.toml
+++ b/src/librustc_hir/Cargo.toml
@@ -20,4 +20,5 @@ rustc_errors = { path = "../librustc_errors" }
 rustc_serialize = { path = "../libserialize", package = "serialize" }
 rustc_ast = { path = "../librustc_ast" }
 lazy_static = "1"
+log = { version = "0.4", features = ["release_max_level_info", "std"] }
 smallvec = { version = "1.0", features = ["union", "may_dangle"] }
diff --git a/src/librustc_hir/arena.rs b/src/librustc_hir/arena.rs
new file mode 100644
index 00000000000..978565a4c39
--- /dev/null
+++ b/src/librustc_hir/arena.rs
@@ -0,0 +1,49 @@
+/// 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, [
+            // HIR types
+            [few] hir_krate: rustc_hir::Crate<$tcx>,
+            [] arm: rustc_hir::Arm<$tcx>,
+            [] attribute: rustc_ast::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);
+    )
+}
diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc_hir/definitions.rs
index aa4742ea891..3b86dd42a68 100644
--- a/src/librustc/hir/map/definitions.rs
+++ b/src/librustc_hir/definitions.rs
@@ -4,22 +4,24 @@
 //! There are also some rather random cases (like const initializer
 //! expressions) that are mostly just leftovers.
 
+pub use crate::def_id::DefPathHash;
+use crate::def_id::{CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
+use crate::hir;
+use crate::hir_id::DUMMY_HIR_ID;
+
 use rustc_ast::ast;
+use rustc_ast::crate_disambiguator::CrateDisambiguator;
 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, LocalDefId, 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 log::debug;
 use std::fmt::Write;
 use std::hash::Hash;
 
-pub use rustc_hir::def_id::DefPathHash;
-
 /// 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.
@@ -345,7 +347,7 @@ impl Definitions {
     pub fn as_local_hir_id(&self, def_id: DefId) -> Option<hir::HirId> {
         if let Some(def_id) = def_id.as_local() {
             let hir_id = self.local_def_id_to_hir_id(def_id);
-            if hir_id != hir::DUMMY_HIR_ID { Some(hir_id) } else { None }
+            if hir_id != DUMMY_HIR_ID { Some(hir_id) } else { None }
         } else {
             None
         }
diff --git a/src/librustc_hir/lib.rs b/src/librustc_hir/lib.rs
index fa5c72b060d..fbb3d6b2af3 100644
--- a/src/librustc_hir/lib.rs
+++ b/src/librustc_hir/lib.rs
@@ -13,7 +13,9 @@
 #[macro_use]
 extern crate rustc_data_structures;
 
+mod arena;
 pub mod def;
+pub mod definitions;
 pub use rustc_span::def_id;
 mod hir;
 pub mod hir_id;
diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs
index 8d9e287cdc9..d3ed2fc89c1 100644
--- a/src/librustc_interface/passes.rs
+++ b/src/librustc_interface/passes.rs
@@ -437,12 +437,16 @@ pub fn lower_to_hir<'res, 'tcx>(
     resolver: &'res mut Resolver<'_>,
     dep_graph: &'res DepGraph,
     krate: &'res ast::Crate,
-    arena: &'tcx Arena<'tcx>,
+    arena: &'tcx rustc_ast_lowering::Arena<'tcx>,
 ) -> Crate<'tcx> {
+    // We're constructing the HIR here; we don't care what we will
+    // read, since we haven't even constructed the *input* to
+    // incr. comp. yet.
+    dep_graph.assert_ignored();
+
     // Lower AST to HIR.
     let hir_crate = rustc_ast_lowering::lower_crate(
         sess,
-        &dep_graph,
         &krate,
         resolver,
         rustc_parse::nt_to_tokenstream,
diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs
index 3ca92216003..b0eeb57173f 100644
--- a/src/librustc_interface/queries.rs
+++ b/src/librustc_interface/queries.rs
@@ -68,6 +68,7 @@ pub struct Queries<'tcx> {
     gcx: Once<GlobalCtxt<'tcx>>,
 
     arena: WorkerLocal<Arena<'tcx>>,
+    hir_arena: WorkerLocal<rustc_ast_lowering::Arena<'tcx>>,
 
     dep_graph_future: Query<Option<DepGraphFuture>>,
     parse: Query<ast::Crate>,
@@ -87,6 +88,7 @@ impl<'tcx> Queries<'tcx> {
             compiler,
             gcx: Once::new(),
             arena: WorkerLocal::new(|_| Arena::default()),
+            hir_arena: WorkerLocal::new(|_| rustc_ast_lowering::Arena::default()),
             dep_graph_future: Default::default(),
             parse: Default::default(),
             crate_name: Default::default(),
@@ -218,10 +220,10 @@ impl<'tcx> Queries<'tcx> {
                     resolver,
                     &*self.dep_graph()?.peek(),
                     &krate,
-                    &self.arena,
+                    &self.hir_arena,
                 ))
             })?;
-            let hir = self.arena.alloc(hir);
+            let hir = self.hir_arena.alloc(hir);
             Ok((hir, Steal::new(BoxedResolver::to_resolver_outputs(resolver))))
         })
     }
diff --git a/src/librustc_lint/context.rs b/src/librustc_lint/context.rs
index 5b7b73b48ec..257b179d6ba 100644
--- a/src/librustc_lint/context.rs
+++ b/src/librustc_lint/context.rs
@@ -18,8 +18,6 @@ use self::TargetLint::*;
 
 use crate::levels::LintLevelsBuilder;
 use crate::passes::{EarlyLintPassObject, LateLintPassObject};
-use rustc::hir::map::definitions::{DefPathData, DisambiguatedDefPathData};
-use rustc::lint::add_elided_lifetime_in_path_suggestion;
 use rustc::lint::LintDiagnosticBuilder;
 use rustc::middle::privacy::AccessLevels;
 use rustc::middle::stability;
@@ -32,7 +30,8 @@ use rustc_data_structures::sync;
 use rustc_errors::{struct_span_err, Applicability};
 use rustc_hir as hir;
 use rustc_hir::def_id::{CrateNum, DefId};
-use rustc_session::lint::BuiltinLintDiagnostics;
+use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
+use rustc_session::lint::{add_elided_lifetime_in_path_suggestion, BuiltinLintDiagnostics};
 use rustc_session::lint::{FutureIncompatibleInfo, Level, Lint, LintBuffer, LintId};
 use rustc_session::Session;
 use rustc_span::{symbol::Symbol, MultiSpan, Span, DUMMY_SP};
diff --git a/src/librustc_metadata/rmeta/decoder.rs b/src/librustc_metadata/rmeta/decoder.rs
index 2bf74fe272e..e7e05097a54 100644
--- a/src/librustc_metadata/rmeta/decoder.rs
+++ b/src/librustc_metadata/rmeta/decoder.rs
@@ -6,8 +6,6 @@ use crate::rmeta::*;
 
 use rustc::dep_graph::{self, DepNode, DepNodeIndex};
 use rustc::hir::exports::Export;
-use rustc::hir::map::definitions::DefPathTable;
-use rustc::hir::map::{DefKey, DefPath, DefPathData, DefPathHash};
 use rustc::middle::cstore::{CrateSource, ExternCrate};
 use rustc::middle::cstore::{ForeignModule, LinkagePreference, NativeLibrary};
 use rustc::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel};
@@ -29,6 +27,8 @@ use rustc_expand::proc_macro::{AttrProcMacro, BangProcMacro, ProcMacroDerive};
 use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
 use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
+use rustc_hir::definitions::DefPathTable;
+use rustc_hir::definitions::{DefKey, DefPath, DefPathData, DefPathHash};
 use rustc_index::vec::{Idx, IndexVec};
 use rustc_serialize::{opaque, Decodable, Decoder, SpecializedDecoder};
 use rustc_session::Session;
diff --git a/src/librustc_metadata/rmeta/decoder/cstore_impl.rs b/src/librustc_metadata/rmeta/decoder/cstore_impl.rs
index 1b15646ff9b..1ac5caf138c 100644
--- a/src/librustc_metadata/rmeta/decoder/cstore_impl.rs
+++ b/src/librustc_metadata/rmeta/decoder/cstore_impl.rs
@@ -5,8 +5,6 @@ use crate::native_libs;
 use crate::rmeta::{self, encoder};
 
 use rustc::hir::exports::Export;
-use rustc::hir::map::definitions::DefPathTable;
-use rustc::hir::map::{DefKey, DefPath, DefPathHash};
 use rustc::middle::cstore::{CrateSource, CrateStore, EncodedMetadata, NativeLibraryKind};
 use rustc::middle::exported_symbols::ExportedSymbol;
 use rustc::middle::stability::DeprecationEntry;
@@ -19,6 +17,8 @@ use rustc_ast::expand::allocator::AllocatorKind;
 use rustc_data_structures::svh::Svh;
 use rustc_hir as hir;
 use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, CRATE_DEF_INDEX, LOCAL_CRATE};
+use rustc_hir::definitions::DefPathTable;
+use rustc_hir::definitions::{DefKey, DefPath, DefPathHash};
 use rustc_session::{CrateDisambiguator, Session};
 use rustc_span::source_map::{self, Span, Spanned};
 use rustc_span::symbol::Symbol;
diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs
index 5963047fc76..a3803bc0707 100644
--- a/src/librustc_metadata/rmeta/encoder.rs
+++ b/src/librustc_metadata/rmeta/encoder.rs
@@ -2,7 +2,6 @@ use crate::rmeta::table::FixedSizeEncoding;
 use crate::rmeta::*;
 
 use log::{debug, trace};
-use rustc::hir::map::definitions::DefPathTable;
 use rustc::hir::map::Map;
 use rustc::middle::cstore::{EncodedMetadata, ForeignModule, LinkagePreference, NativeLibrary};
 use rustc::middle::dependency_format::Linkage;
@@ -23,6 +22,7 @@ use rustc_hir as hir;
 use rustc_hir::def::CtorKind;
 use rustc_hir::def_id::DefIdSet;
 use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
+use rustc_hir::definitions::DefPathTable;
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc_hir::itemlikevisit::{ItemLikeVisitor, ParItemLikeVisitor};
 use rustc_hir::{AnonConst, GenericParamKind};
diff --git a/src/librustc_resolve/def_collector.rs b/src/librustc_resolve/def_collector.rs
index 0dee997f2ed..6253f183cc4 100644
--- a/src/librustc_resolve/def_collector.rs
+++ b/src/librustc_resolve/def_collector.rs
@@ -1,10 +1,10 @@
 use log::debug;
-use rustc::hir::map::definitions::*;
 use rustc_ast::ast::*;
 use rustc_ast::token::{self, Token};
 use rustc_ast::visit::{self, FnKind};
 use rustc_expand::expand::AstFragment;
 use rustc_hir::def_id::LocalDefId;
+use rustc_hir::definitions::*;
 use rustc_span::hygiene::ExpnId;
 use rustc_span::symbol::{kw, sym};
 use rustc_span::Span;
diff --git a/src/librustc_session/lint.rs b/src/librustc_session/lint.rs
index 3b79972ccbf..1162cff4e0b 100644
--- a/src/librustc_session/lint.rs
+++ b/src/librustc_session/lint.rs
@@ -1,6 +1,7 @@
 pub use self::Level::*;
 use rustc_ast::node_id::{NodeId, NodeMap};
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
+use rustc_errors::{pluralize, Applicability, DiagnosticBuilder};
 use rustc_span::edition::Edition;
 use rustc_span::{sym, symbol::Ident, MultiSpan, Span, Symbol};
 
@@ -367,3 +368,45 @@ macro_rules! declare_lint_pass {
         $crate::impl_lint_pass!($name => [$($lint),*]);
     };
 }
+
+pub fn add_elided_lifetime_in_path_suggestion(
+    sess: &crate::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_session/session.rs b/src/librustc_session/session.rs
index 81281857dbc..80f59aff691 100644
--- a/src/librustc_session/session.rs
+++ b/src/librustc_session/session.rs
@@ -1,41 +1,30 @@
+use crate::cgu_reuse_tracker::CguReuseTracker;
 use crate::code_stats::CodeStats;
 pub use crate::code_stats::{DataTypeKind, FieldInfo, SizeKind, VariantInfo};
-
-use crate::cgu_reuse_tracker::CguReuseTracker;
-use rustc_data_structures::fingerprint::Fingerprint;
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
-
 use crate::config::{self, OutputType, PrintRequest, Sanitizer, SwitchWithOptPath};
 use crate::filesearch;
 use crate::lint;
+use crate::parse::ParseSess;
 use crate::search_paths::{PathKind, SearchPath};
-use rustc_data_structures::profiling::duration_to_secs_str;
-use rustc_errors::ErrorReported;
 
-use rustc_data_structures::base_n;
-use rustc_data_structures::impl_stable_hash_via_hash;
+pub use rustc_ast::crate_disambiguator::CrateDisambiguator;
+use rustc_data_structures::flock;
+use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_data_structures::jobserver::{self, Client};
+use rustc_data_structures::profiling::{duration_to_secs_str, SelfProfiler, SelfProfilerRef};
 use rustc_data_structures::sync::{
     self, AtomicU64, AtomicUsize, Lock, Lrc, Once, OneThread, Ordering, Ordering::SeqCst,
 };
-
-use crate::parse::ParseSess;
 use rustc_errors::annotate_snippet_emitter_writer::AnnotateSnippetEmitterWriter;
-use rustc_errors::emitter::HumanReadableErrorType;
-use rustc_errors::emitter::{Emitter, EmitterWriter};
+use rustc_errors::emitter::{Emitter, EmitterWriter, HumanReadableErrorType};
 use rustc_errors::json::JsonEmitter;
-use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticId};
+use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticId, ErrorReported};
 use rustc_span::edition::Edition;
-use rustc_span::source_map;
-use rustc_span::{MultiSpan, Span};
-
-use rustc_data_structures::flock;
-use rustc_data_structures::jobserver::{self, Client};
-use rustc_data_structures::profiling::{SelfProfiler, SelfProfilerRef};
+use rustc_span::source_map::{self, MultiSpan, Span};
 use rustc_target::spec::{PanicStrategy, RelroLevel, Target, TargetTriple};
 
 use std::cell::{self, RefCell};
 use std::env;
-use std::fmt;
 use std::io::Write;
 use std::num::NonZeroU32;
 use std::path::PathBuf;
@@ -1193,34 +1182,6 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
     }
 }
 
-/// Hash value constructed out of all the `-C metadata` arguments passed to the
-/// compiler. Together with the crate-name forms a unique global identifier for
-/// the crate.
-#[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Clone, Copy, RustcEncodable, RustcDecodable)]
-pub struct CrateDisambiguator(Fingerprint);
-
-impl CrateDisambiguator {
-    pub fn to_fingerprint(self) -> Fingerprint {
-        self.0
-    }
-}
-
-impl fmt::Display for CrateDisambiguator {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
-        let (a, b) = self.0.as_value();
-        let as_u128 = a as u128 | ((b as u128) << 64);
-        f.write_str(&base_n::encode(as_u128, base_n::CASE_INSENSITIVE))
-    }
-}
-
-impl From<Fingerprint> for CrateDisambiguator {
-    fn from(fingerprint: Fingerprint) -> CrateDisambiguator {
-        CrateDisambiguator(fingerprint)
-    }
-}
-
-impl_stable_hash_via_hash!(CrateDisambiguator);
-
 /// Holds data on the current incremental compilation session, if there is one.
 #[derive(Debug)]
 pub enum IncrCompSession {
diff --git a/src/librustc_traits/lowering/mod.rs b/src/librustc_traits/lowering/mod.rs
index 3a0c36a84ae..e3f9bd78073 100644
--- a/src/librustc_traits/lowering/mod.rs
+++ b/src/librustc_traits/lowering/mod.rs
@@ -1,6 +1,5 @@
 mod environment;
 
-use rustc::hir::map::definitions::DefPathData;
 use rustc::hir::map::Map;
 use rustc::traits::{
     Clause, Clauses, DomainGoal, FromEnv, GoalKind, PolyDomainGoal, ProgramClause,
@@ -13,6 +12,7 @@ use rustc_ast::ast;
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
+use rustc_hir::definitions::DefPathData;
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc_span::symbol::sym;