about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJohn Kåre Alsaker <john.kare.alsaker@gmail.com>2018-12-03 01:14:35 +0100
committerJohn Kåre Alsaker <john.kare.alsaker@gmail.com>2019-03-13 00:03:13 +0100
commit3936aff2169a1f61633de2bc475face3a2682efb (patch)
tree0acd56359a94980bef3519e0d39123e8d0d4a8af
parent48757a70a382afe27d5469fdcfbe5d434c9d4097 (diff)
downloadrust-3936aff2169a1f61633de2bc475face3a2682efb.tar.gz
rust-3936aff2169a1f61633de2bc475face3a2682efb.zip
Use derive macro for HashStable
-rw-r--r--src/librustc/hir/def.rs9
-rw-r--r--src/librustc/hir/mod.rs197
-rw-r--r--src/librustc/ich/impls_cstore.rs53
-rw-r--r--src/librustc/ich/impls_hir.rs753
-rw-r--r--src/librustc/ich/impls_mir.rs504
-rw-r--r--src/librustc/ich/impls_misc.rs9
-rw-r--r--src/librustc/ich/impls_ty.rs1050
-rw-r--r--src/librustc/ich/mod.rs2
-rw-r--r--src/librustc/infer/canonical/mod.rs15
-rw-r--r--src/librustc/middle/cstore.rs19
-rw-r--r--src/librustc/middle/lang_items.rs2
-rw-r--r--src/librustc/middle/lib_features.rs2
-rw-r--r--src/librustc/middle/privacy.rs3
-rw-r--r--src/librustc/middle/reachable.rs3
-rw-r--r--src/librustc/middle/region.rs7
-rw-r--r--src/librustc/middle/resolve_lifetime.rs7
-rw-r--r--src/librustc/mir/interpret/allocation.rs3
-rw-r--r--src/librustc/mir/interpret/error.rs7
-rw-r--r--src/librustc/mir/interpret/mod.rs5
-rw-r--r--src/librustc/mir/interpret/pointer.rs4
-rw-r--r--src/librustc/mir/interpret/value.rs9
-rw-r--r--src/librustc/mir/mod.rs92
-rw-r--r--src/librustc/session/search_paths.rs3
-rw-r--r--src/librustc/traits/mod.rs41
-rw-r--r--src/librustc/traits/project.rs3
-rw-r--r--src/librustc/ty/adjustment.rs17
-rw-r--r--src/librustc/ty/cast.rs3
-rw-r--r--src/librustc/ty/context.rs8
-rw-r--r--src/librustc/ty/instance.rs5
-rw-r--r--src/librustc/ty/mod.rs64
-rw-r--r--src/librustc/ty/sty.rs54
-rw-r--r--src/librustc/ty/subst.rs7
-rw-r--r--src/librustc/ty/trait_def.rs4
-rw-r--r--src/librustc/ty/util.rs3
-rw-r--r--src/librustc/util/common.rs3
-rw-r--r--src/librustc_data_structures/thin_vec.rs10
36 files changed, 358 insertions, 2622 deletions
diff --git a/src/librustc/hir/def.rs b/src/librustc/hir/def.rs
index f6d864f5b40..b45fc3ffd82 100644
--- a/src/librustc/hir/def.rs
+++ b/src/librustc/hir/def.rs
@@ -3,12 +3,13 @@ use crate::util::nodemap::{NodeMap, DefIdMap};
 use syntax::ast;
 use syntax::ext::base::MacroKind;
 use syntax_pos::Span;
+use rustc_macros::HashStable;
 use crate::hir;
 use crate::ty;
 
 use self::Namespace::*;
 
-#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, HashStable)]
 pub enum CtorKind {
     /// Constructor function automatically created by a tuple struct/variant.
     Fn,
@@ -18,7 +19,7 @@ pub enum CtorKind {
     Fictive,
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, HashStable)]
 pub enum NonMacroAttrKind {
     /// Single-segment attribute defined by the language (`#[inline]`)
     Builtin,
@@ -32,7 +33,7 @@ pub enum NonMacroAttrKind {
     Custom,
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, HashStable)]
 pub enum Def {
     // Type namespace
     Mod(DefId),
@@ -209,7 +210,7 @@ pub type ExportMap = DefIdMap<Vec<Export>>;
 /// namespace.
 pub type ImportMap = NodeMap<PerNS<Option<PathResolution>>>;
 
-#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
 pub struct Export {
     /// The name of the target.
     pub ident: ast::Ident,
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index e47bc3d1c25..14e39748eb0 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -122,6 +122,7 @@ impl fmt::Display for HirId {
 // hack to ensure that we don't try to access the private parts of `ItemLocalId` in this module
 mod item_local_id_inner {
     use rustc_data_structures::indexed_vec::Idx;
+    use rustc_macros::HashStable;
     newtype_index! {
         /// An `ItemLocalId` uniquely identifies something within a given "item-like",
         /// that is within a hir::Item, hir::TraitItem, or hir::ImplItem. There is no
@@ -131,7 +132,9 @@ mod item_local_id_inner {
         /// integers starting at zero, so a mapping that maps all or most nodes within
         /// an "item-like" to something else can be implement by a `Vec` instead of a
         /// tree or hash map.
-        pub struct ItemLocalId { .. }
+        pub struct ItemLocalId {
+            derive [HashStable]
+        }
     }
 }
 
@@ -164,7 +167,7 @@ pub struct Lifetime {
     pub name: LifetimeName,
 }
 
-#[derive(Debug, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
+#[derive(Debug, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy, HashStable)]
 pub enum ParamName {
     /// Some user-given name like `T` or `'x`.
     Plain(Ident),
@@ -207,7 +210,7 @@ impl ParamName {
     }
 }
 
-#[derive(Debug, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
+#[derive(Debug, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy, HashStable)]
 pub enum LifetimeName {
     /// User-given names or fresh (synthetic) names.
     Param(ParamName),
@@ -290,7 +293,7 @@ impl Lifetime {
 /// A `Path` is essentially Rust's notion of a name; for instance,
 /// `std::cmp::PartialEq`. It's represented as a sequence of identifiers,
 /// along with a bunch of supporting information.
-#[derive(Clone, RustcEncodable, RustcDecodable)]
+#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
 pub struct Path {
     pub span: Span,
     /// The definition that the path resolved to.
@@ -319,9 +322,10 @@ impl fmt::Display for Path {
 
 /// A segment of a path: an identifier, an optional lifetime, and a set of
 /// types.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct PathSegment {
     /// The identifier portion of this path segment.
+    #[stable_hasher(project(name))]
     pub ident: Ident,
     // `id` and `def` are optional. We currently only use these in save-analysis,
     // any path segments without these will not have save-analysis info and
@@ -391,13 +395,13 @@ impl PathSegment {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct ConstArg {
     pub value: AnonConst,
     pub span: Span,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum GenericArg {
     Lifetime(Lifetime),
     Type(Ty),
@@ -422,7 +426,7 @@ impl GenericArg {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct GenericArgs {
     /// The generic arguments for this path segment.
     pub args: HirVec<GenericArg>,
@@ -486,7 +490,7 @@ impl GenericArgs {
 
 /// A modifier on a bound, currently this is only used for `?Sized`, where the
 /// modifier is `Maybe`. Negative bounds should also be handled here.
-#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, HashStable)]
 pub enum TraitBoundModifier {
     None,
     Maybe,
@@ -496,7 +500,7 @@ pub enum TraitBoundModifier {
 /// `typeck::collect::compute_bounds` matches these against
 /// the "special" built-in traits (see `middle::lang_items`) and
 /// detects `Copy`, `Send` and `Sync`.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum GenericBound {
     Trait(PolyTraitRef, TraitBoundModifier),
     Outlives(Lifetime),
@@ -513,7 +517,7 @@ impl GenericBound {
 
 pub type GenericBounds = HirVec<GenericBound>;
 
-#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum LifetimeParamKind {
     // Indicates that the lifetime definition was explicitly declared (e.g., in
     // `fn foo<'a>(x: &'a u8) -> &'a u8 { x }`).
@@ -532,7 +536,7 @@ pub enum LifetimeParamKind {
     Error,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum GenericParamKind {
     /// A lifetime definition (e.g., `'a: 'b + 'c + 'd`).
     Lifetime {
@@ -547,7 +551,7 @@ pub enum GenericParamKind {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct GenericParam {
     pub hir_id: HirId,
     pub name: ParamName,
@@ -568,7 +572,7 @@ pub struct GenericParamCount {
 
 /// Represents lifetimes and type parameters attached to a declaration
 /// of a function, enum, trait, etc.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct Generics {
     pub params: HirVec<GenericParam>,
     pub where_clause: WhereClause,
@@ -616,13 +620,13 @@ impl Generics {
 
 /// Synthetic type parameters are converted to another form during lowering; this allows
 /// us to track the original form they had, and is useful for error messages.
-#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, HashStable)]
 pub enum SyntheticTyParamKind {
     ImplTrait
 }
 
 /// A where-clause in a definition.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct WhereClause {
     pub hir_id: HirId,
     pub predicates: HirVec<WherePredicate>,
@@ -641,7 +645,7 @@ impl WhereClause {
 }
 
 /// A single predicate in a where-clause.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum WherePredicate {
     /// A type binding (e.g., `for<'c> Foo: Send + Clone + 'c`).
     BoundPredicate(WhereBoundPredicate),
@@ -662,7 +666,7 @@ impl WherePredicate {
 }
 
 /// A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`).
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct WhereBoundPredicate {
     pub span: Span,
     /// Any generics from a `for` binding.
@@ -674,7 +678,7 @@ pub struct WhereBoundPredicate {
 }
 
 /// A lifetime predicate (e.g., `'a: 'b + 'c`).
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct WhereRegionPredicate {
     pub span: Span,
     pub lifetime: Lifetime,
@@ -682,7 +686,7 @@ pub struct WhereRegionPredicate {
 }
 
 /// An equality predicate (e.g., `T = int`); currently unsupported.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct WhereEqPredicate {
     pub hir_id: HirId,
     pub span: Span,
@@ -801,7 +805,7 @@ impl Crate {
 /// A macro definition, in this crate or imported from another.
 ///
 /// Not parsed directly, but created on macro import or `macro_rules!` expansion.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct MacroDef {
     pub name: Name,
     pub vis: Visibility,
@@ -812,13 +816,14 @@ pub struct MacroDef {
     pub legacy: bool,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct Block {
     /// Statements in a block.
     pub stmts: HirVec<Stmt>,
     /// An expression at the end of the block
     /// without a semicolon, if any.
     pub expr: Option<P<Expr>>,
+    #[stable_hasher(ignore)]
     pub hir_id: HirId,
     /// Distinguishes between `unsafe { ... }` and `{ ... }`.
     pub rules: BlockCheckMode,
@@ -829,8 +834,9 @@ pub struct Block {
     pub targeted_by_break: bool,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable)]
+#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
 pub struct Pat {
+    #[stable_hasher(ignore)]
     pub hir_id: HirId,
     pub node: PatKind,
     pub span: Span,
@@ -891,10 +897,12 @@ impl Pat {
 /// Patterns like the fields of Foo `{ x, ref y, ref mut z }`
 /// are treated the same as` x: x, y: ref y, z: ref mut z`,
 /// except `is_shorthand` is true.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct FieldPat {
+    #[stable_hasher(ignore)]
     pub hir_id: HirId,
     /// The identifier for the field.
+    #[stable_hasher(project(name))]
     pub ident: Ident,
     /// The pattern the field is destructured to.
     pub pat: P<Pat>,
@@ -904,7 +912,7 @@ pub struct FieldPat {
 /// Explicit binding annotations given in the HIR for a binding. Note
 /// that this is not the final binding *mode* that we infer after type
 /// inference.
-#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)]
+#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy, HashStable)]
 pub enum BindingAnnotation {
     /// No binding annotation given: this means that the final binding mode
     /// will depend on whether we have skipped through a `&` reference
@@ -925,13 +933,13 @@ pub enum BindingAnnotation {
     RefMut,
 }
 
-#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum RangeEnd {
     Included,
     Excluded,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum PatKind {
     /// Represents a wildcard pattern (i.e., `_`).
     Wild,
@@ -976,7 +984,8 @@ pub enum PatKind {
     Slice(HirVec<P<Pat>>, Option<P<Pat>>, HirVec<P<Pat>>),
 }
 
-#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
+#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, HashStable,
+         RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
 pub enum Mutability {
     MutMutable,
     MutImmutable,
@@ -992,7 +1001,7 @@ impl Mutability {
     }
 }
 
-#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy, Hash)]
+#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy, Hash, HashStable)]
 pub enum BinOpKind {
     /// The `+` operator (addition).
     Add,
@@ -1126,7 +1135,7 @@ impl Into<ast::BinOpKind> for BinOpKind {
 
 pub type BinOp = Spanned<BinOpKind>;
 
-#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy, Hash)]
+#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy, Hash, HashStable)]
 pub enum UnOp {
     /// The `*` operator (deferencing).
     UnDeref,
@@ -1169,7 +1178,7 @@ impl fmt::Debug for Stmt {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable)]
+#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
 pub enum StmtKind {
     /// A local (`let`) binding.
     Local(P<Local>),
@@ -1196,7 +1205,7 @@ impl StmtKind {
 }
 
 /// Represents a `let` statement (i.e., `let <pat>:<ty> = <expr>;`).
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct Local {
     pub pat: P<Pat>,
     pub ty: Option<P<Ty>>,
@@ -1209,7 +1218,7 @@ pub struct Local {
 }
 
 /// Represents a single arm of a `match` expression.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct Arm {
     pub attrs: HirVec<Attribute>,
     pub pats: HirVec<P<Pat>>,
@@ -1217,13 +1226,14 @@ pub struct Arm {
     pub body: P<Expr>,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum Guard {
     If(P<Expr>),
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct Field {
+    #[stable_hasher(ignore)]
     pub hir_id: HirId,
     pub ident: Ident,
     pub expr: P<Expr>,
@@ -1231,7 +1241,7 @@ pub struct Field {
     pub is_shorthand: bool,
 }
 
-#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)]
+#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy, HashStable)]
 pub enum BlockCheckMode {
     DefaultBlock,
     UnsafeBlock(UnsafeSource),
@@ -1239,7 +1249,7 @@ pub enum BlockCheckMode {
     PopUnsafeBlock(UnsafeSource),
 }
 
-#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)]
+#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy, HashStable)]
 pub enum UnsafeSource {
     CompilerGenerated,
     UserProvided,
@@ -1315,7 +1325,7 @@ impl BodyOwnerKind {
 /// These are usually found nested inside types (e.g., array lengths)
 /// or expressions (e.g., repeat counts), and also used to define
 /// explicit discriminant values for enum variants.
-#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct AnonConst {
     pub hir_id: HirId,
     pub body: BodyId,
@@ -1431,7 +1441,7 @@ impl fmt::Debug for Expr {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum ExprKind {
     /// A `box x` expression.
     Box(P<Expr>),
@@ -1537,7 +1547,7 @@ pub enum ExprKind {
 }
 
 /// Optionally `Self`-qualified value/type path or associated extension.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum QPath {
     /// Path to a definition, optionally "fully-qualified" with a `Self`
     /// type, if the path points to an associated item in a trait.
@@ -1557,7 +1567,7 @@ pub enum QPath {
 }
 
 /// Hints at the original code for a let statement.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy, HashStable)]
 pub enum LocalSource {
     /// A `match _ { .. }`.
     Normal,
@@ -1566,7 +1576,7 @@ pub enum LocalSource {
 }
 
 /// Hints at the original code for a `match _ { .. }`.
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy, HashStable)]
 pub enum MatchSource {
     /// A `match _ { .. }`.
     Normal,
@@ -1584,7 +1594,7 @@ pub enum MatchSource {
 }
 
 /// The loop type that yielded an `ExprKind::Loop`.
-#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)]
+#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy, HashStable)]
 pub enum LoopSource {
     /// A `loop { .. }` loop.
     Loop,
@@ -1594,7 +1604,7 @@ pub enum LoopSource {
     ForLoop,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy, HashStable)]
 pub enum LoopIdError {
     OutsideLoopScope,
     UnlabeledCfInWhileCondition,
@@ -1612,7 +1622,7 @@ impl fmt::Display for LoopIdError {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy, HashStable)]
 pub struct Destination {
     // This is `Some(_)` iff there is an explicit user-specified `label
     pub label: Option<Label>,
@@ -1622,13 +1632,14 @@ pub struct Destination {
     pub target_id: Result<HirId, LoopIdError>,
 }
 
-#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
+#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, HashStable,
+         RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
 pub enum GeneratorMovability {
     Static,
     Movable,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy, HashStable)]
 pub enum CaptureClause {
     CaptureByValue,
     CaptureByRef,
@@ -1636,14 +1647,14 @@ pub enum CaptureClause {
 
 // N.B., if you change this, you'll probably want to change the corresponding
 // type structure in middle/ty.rs as well.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct MutTy {
     pub ty: P<Ty>,
     pub mutbl: Mutability,
 }
 
 /// Represents a method's signature in a trait declaration or implementation.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct MethodSig {
     pub header: FnHeader,
     pub decl: P<FnDecl>,
@@ -1672,7 +1683,7 @@ pub struct TraitItem {
 }
 
 /// A trait method's body (or just argument names).
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum TraitMethod {
     /// No default body in the trait, just a signature.
     Required(HirVec<Ident>),
@@ -1682,7 +1693,7 @@ pub enum TraitMethod {
 }
 
 /// Represents a trait method or associated constant or type
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum TraitItemKind {
     /// An associated constant with an optional value (otherwise `impl`s
     /// must contain a value)
@@ -1716,7 +1727,7 @@ pub struct ImplItem {
 }
 
 /// Represents different contents within `impl`s
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum ImplItemKind {
     /// An associated constant of the given type, set to the constant result
     /// of the expression
@@ -1730,9 +1741,10 @@ pub enum ImplItemKind {
 }
 
 // Bind a type to an associated type: `A=Foo`.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct TypeBinding {
     pub hir_id: HirId,
+    #[stable_hasher(project(name))]
     pub ident: Ident,
     pub ty: P<Ty>,
     pub span: Span,
@@ -1753,7 +1765,7 @@ impl fmt::Debug for Ty {
 }
 
 /// Not represented directly in the AST; referred to by name through a `ty_path`.
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy, HashStable)]
 pub enum PrimTy {
     Int(IntTy),
     Uint(UintTy),
@@ -1763,7 +1775,7 @@ pub enum PrimTy {
     Char,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct BareFnTy {
     pub unsafety: Unsafety,
     pub abi: Abi,
@@ -1772,7 +1784,7 @@ pub struct BareFnTy {
     pub arg_names: HirVec<Ident>,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct ExistTy {
     pub generics: Generics,
     pub bounds: GenericBounds,
@@ -1780,7 +1792,7 @@ pub struct ExistTy {
 }
 
 /// The various kinds of types recognized by the compiler.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum TyKind {
     /// A variable length slice (i.e., `[T]`).
     Slice(P<Ty>),
@@ -1822,7 +1834,7 @@ pub enum TyKind {
     CVarArgs(Lifetime),
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct InlineAsmOutput {
     pub constraint: Symbol,
     pub is_rw: bool,
@@ -1830,7 +1842,7 @@ pub struct InlineAsmOutput {
     pub span: Span,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct InlineAsm {
     pub asm: Symbol,
     pub asm_str_style: StrStyle,
@@ -1840,18 +1852,19 @@ pub struct InlineAsm {
     pub volatile: bool,
     pub alignstack: bool,
     pub dialect: AsmDialect,
+    #[stable_hasher(ignore)] // This is used for error reporting
     pub ctxt: SyntaxContext,
 }
 
 /// Represents an argument in a function header.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct Arg {
     pub pat: P<Pat>,
     pub hir_id: HirId,
 }
 
 /// Represents the header (not the body) of a function declaration.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct FnDecl {
     pub inputs: HirVec<Ty>,
     pub output: FunctionRetTy,
@@ -1861,7 +1874,7 @@ pub struct FnDecl {
 }
 
 /// Represents what type of implicit self a function has, if any.
-#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum ImplicitSelfKind {
     /// Represents a `fn x(self);`.
     Imm,
@@ -1887,31 +1900,33 @@ impl ImplicitSelfKind {
 }
 
 /// Is the trait definition an auto trait?
-#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum IsAuto {
     Yes,
     No
 }
 
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, HashStable,
+         Ord, RustcEncodable, RustcDecodable, Debug)]
 pub enum IsAsync {
     Async,
     NotAsync,
 }
 
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, HashStable,
+         RustcEncodable, RustcDecodable, Hash, Debug)]
 pub enum Unsafety {
     Unsafe,
     Normal,
 }
 
-#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum Constness {
     Const,
     NotConst,
 }
 
-#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum Defaultness {
     Default { has_value: bool },
     Final,
@@ -1947,7 +1962,7 @@ impl fmt::Display for Unsafety {
     }
 }
 
-#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, HashStable)]
 pub enum ImplPolarity {
     /// `impl Trait for Type`
     Positive,
@@ -1965,7 +1980,7 @@ impl fmt::Debug for ImplPolarity {
 }
 
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum FunctionRetTy {
     /// Return type is not specified.
     ///
@@ -2004,24 +2019,25 @@ pub struct Mod {
     pub item_ids: HirVec<ItemId>,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct ForeignMod {
     pub abi: Abi,
     pub items: HirVec<ForeignItem>,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct GlobalAsm {
     pub asm: Symbol,
+    #[stable_hasher(ignore)] // This is used for error reporting
     pub ctxt: SyntaxContext,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct EnumDef {
     pub variants: HirVec<Variant>,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct VariantKind {
     pub ident: Ident,
     pub attrs: HirVec<Attribute>,
@@ -2032,7 +2048,7 @@ pub struct VariantKind {
 
 pub type Variant = Spanned<VariantKind>;
 
-#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum UseKind {
     /// One import, e.g., `use foo::bar` or `use foo::bar as baz`.
     /// Also produced for each element of a list `use`, e.g.
@@ -2054,9 +2070,11 @@ pub enum UseKind {
 /// that the ref_id is for. Note that ref_id's value is not the NodeId of the
 /// trait being referred to but just a unique NodeId that serves as a key
 /// within the DefMap.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct TraitRef {
     pub path: Path,
+    // Don't hash the ref_id. It is tracked via the thing it is used to access
+    #[stable_hasher(ignore)]
     pub hir_ref_id: HirId,
 }
 
@@ -2074,7 +2092,7 @@ impl TraitRef {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct PolyTraitRef {
     /// The `'a` in `<'a> Foo<&'a T>`.
     pub bound_generic_params: HirVec<GenericParam>,
@@ -2122,9 +2140,10 @@ impl VisibilityKind {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct StructField {
     pub span: Span,
+    #[stable_hasher(project(name))]
     pub ident: Ident,
     pub vis: Visibility,
     pub hir_id: HirId,
@@ -2151,7 +2170,7 @@ impl StructField {
 /// used for `Struct`-structs (but still present). Structures don't have an analogue of "Id of
 /// the variant itself" from enum variants.
 /// Id of the whole struct lives in `Item`.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum VariantData {
     Struct(HirVec<StructField>, HirId),
     Tuple(HirVec<StructField>, HirId),
@@ -2216,7 +2235,7 @@ pub struct Item {
     pub span: Span,
 }
 
-#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct FnHeader {
     pub unsafety: Unsafety,
     pub constness: Constness,
@@ -2224,7 +2243,7 @@ pub struct FnHeader {
     pub abi: Abi,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum ItemKind {
     /// An `extern crate` item, with optional *original* crate name if the crate was renamed.
     ///
@@ -2327,9 +2346,10 @@ impl ItemKind {
 /// type or method, and whether it is public). This allows other
 /// passes to find the impl they want without loading the ID (which
 /// means fewer edges in the incremental compilation graph).
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct TraitItemRef {
     pub id: TraitItemId,
+    #[stable_hasher(project(name))]
     pub ident: Ident,
     pub kind: AssociatedItemKind,
     pub span: Span,
@@ -2342,9 +2362,10 @@ pub struct TraitItemRef {
 /// type or method, and whether it is public). This allows other
 /// passes to find the impl they want without loading the ID (which
 /// means fewer edges in the incremental compilation graph).
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct ImplItemRef {
     pub id: ImplItemId,
+    #[stable_hasher(project(name))]
     pub ident: Ident,
     pub kind: AssociatedItemKind,
     pub span: Span,
@@ -2352,7 +2373,7 @@ pub struct ImplItemRef {
     pub defaultness: Defaultness,
 }
 
-#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum AssociatedItemKind {
     Const,
     Method { has_self: bool },
@@ -2360,7 +2381,7 @@ pub enum AssociatedItemKind {
     Existential,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct ForeignItem {
     pub ident: Ident,
     pub attrs: HirVec<Attribute>,
@@ -2371,7 +2392,7 @@ pub struct ForeignItem {
 }
 
 /// An item within an `extern` block.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum ForeignItemKind {
     /// A foreign function.
     Fn(P<FnDecl>, HirVec<Ident>, Generics),
@@ -2393,7 +2414,7 @@ impl ForeignItemKind {
 }
 
 /// A free variable referred to in a function.
-#[derive(Debug, Copy, Clone, RustcEncodable, RustcDecodable)]
+#[derive(Debug, Copy, Clone, RustcEncodable, RustcDecodable, HashStable)]
 pub struct Freevar {
     /// The variable being accessed free.
     pub def: Def,
@@ -2434,7 +2455,7 @@ pub fn provide(providers: &mut Providers<'_>) {
     providers.describe_def = map::describe_def;
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable)]
+#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
 pub struct CodegenFnAttrs {
     pub flags: CodegenFnAttrFlags,
     /// Parsed representation of the `#[inline]` attribute
@@ -2460,7 +2481,7 @@ pub struct CodegenFnAttrs {
 }
 
 bitflags! {
-    #[derive(RustcEncodable, RustcDecodable)]
+    #[derive(RustcEncodable, RustcDecodable, HashStable)]
     pub struct CodegenFnAttrFlags: u32 {
         /// `#[cold]`: a hint to LLVM that this function, when called, is never on
         /// the hot path.
diff --git a/src/librustc/ich/impls_cstore.rs b/src/librustc/ich/impls_cstore.rs
deleted file mode 100644
index 17ed1a79d45..00000000000
--- a/src/librustc/ich/impls_cstore.rs
+++ /dev/null
@@ -1,53 +0,0 @@
-//! This module contains `HashStable` implementations for various data types
-//! from rustc::middle::cstore in no particular order.
-
-impl_stable_hash_for!(enum crate::middle::cstore::DepKind {
-    UnexportedMacrosOnly,
-    MacrosOnly,
-    Implicit,
-    Explicit
-});
-
-impl_stable_hash_for!(enum crate::middle::cstore::NativeLibraryKind {
-    NativeStatic,
-    NativeStaticNobundle,
-    NativeFramework,
-    NativeUnknown
-});
-
-impl_stable_hash_for!(struct crate::middle::cstore::NativeLibrary {
-    kind,
-    name,
-    cfg,
-    foreign_module,
-    wasm_import_module
-});
-
-impl_stable_hash_for!(struct crate::middle::cstore::ForeignModule {
-    foreign_items,
-    def_id
-});
-
-impl_stable_hash_for!(enum crate::middle::cstore::LinkagePreference {
-    RequireDynamic,
-    RequireStatic
-});
-
-impl_stable_hash_for!(struct crate::middle::cstore::ExternCrate {
-    src,
-    span,
-    path_len,
-    direct
-});
-
-impl_stable_hash_for!(enum crate::middle::cstore::ExternCrateSource {
-    Extern(def_id),
-    Use,
-    Path,
-});
-
-impl_stable_hash_for!(struct crate::middle::cstore::CrateSource {
-    dylib,
-    rlib,
-    rmeta
-});
diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs
index 6fff1653804..9491a073b8f 100644
--- a/src/librustc/ich/impls_hir.rs
+++ b/src/librustc/ich/impls_hir.rs
@@ -69,15 +69,6 @@ impl<'a> ToStableHashKey<StableHashingContext<'a>> for CrateNum {
     }
 }
 
-impl<'a> HashStable<StableHashingContext<'a>> for hir::ItemLocalId {
-    #[inline]
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        self.as_u32().hash_stable(hcx, hasher);
-    }
-}
-
 impl<'a> ToStableHashKey<StableHashingContext<'a>>
 for hir::ItemLocalId {
     type KeyType = hir::ItemLocalId;
@@ -139,167 +130,11 @@ impl<'a> HashStable<StableHashingContext<'a>> for hir::ImplItemId {
     }
 }
 
-impl_stable_hash_for!(enum hir::ParamName {
-    Plain(name),
-    Fresh(index),
-    Error,
-});
-
-impl_stable_hash_for!(enum hir::LifetimeName {
-    Param(param_name),
-    Implicit,
-    Underscore,
-    Static,
-    Error,
-});
 
 impl_stable_hash_for!(struct ast::Label {
     ident
 });
 
-impl_stable_hash_for!(struct hir::Path {
-    span,
-    def,
-    segments
-});
-
-impl_stable_hash_for!(struct hir::PathSegment {
-    ident -> (ident.name),
-    hir_id,
-    def,
-    infer_types,
-    args
-});
-
-impl_stable_hash_for!(struct hir::ConstArg {
-    value,
-    span,
-});
-
-impl_stable_hash_for!(enum hir::GenericArg {
-    Lifetime(lt),
-    Type(ty),
-    Const(ct),
-});
-
-impl_stable_hash_for!(struct hir::GenericArgs {
-    args,
-    bindings,
-    parenthesized
-});
-
-impl_stable_hash_for!(enum hir::GenericBound {
-    Trait(poly_trait_ref, trait_bound_modifier),
-    Outlives(lifetime)
-});
-
-impl_stable_hash_for!(enum hir::TraitBoundModifier {
-    None,
-    Maybe
-});
-
-impl_stable_hash_for!(struct hir::GenericParam {
-    hir_id,
-    name,
-    pure_wrt_drop,
-    attrs,
-    bounds,
-    span,
-    kind
-});
-
-impl_stable_hash_for!(enum hir::LifetimeParamKind {
-    Explicit,
-    InBand,
-    Elided,
-    Error,
-});
-
-impl<'a> HashStable<StableHashingContext<'a>> for hir::GenericParamKind {
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        mem::discriminant(self).hash_stable(hcx, hasher);
-        match self {
-            hir::GenericParamKind::Lifetime { kind } => {
-                kind.hash_stable(hcx, hasher);
-            }
-            hir::GenericParamKind::Type { ref default, synthetic } => {
-                default.hash_stable(hcx, hasher);
-                synthetic.hash_stable(hcx, hasher);
-            }
-            hir::GenericParamKind::Const { ref ty } => {
-                ty.hash_stable(hcx, hasher);
-            }
-        }
-    }
-}
-
-impl_stable_hash_for!(struct hir::Generics {
-    params,
-    where_clause,
-    span
-});
-
-impl_stable_hash_for!(enum hir::SyntheticTyParamKind {
-    ImplTrait
-});
-
-impl_stable_hash_for!(struct hir::WhereClause {
-    hir_id,
-    predicates
-});
-
-impl_stable_hash_for!(enum hir::WherePredicate {
-    BoundPredicate(pred),
-    RegionPredicate(pred),
-    EqPredicate(pred)
-});
-
-impl_stable_hash_for!(struct hir::WhereBoundPredicate {
-    span,
-    bound_generic_params,
-    bounded_ty,
-    bounds
-});
-
-impl_stable_hash_for!(struct hir::WhereRegionPredicate {
-    span,
-    lifetime,
-    bounds
-});
-
-impl_stable_hash_for!(struct hir::WhereEqPredicate {
-    hir_id,
-    span,
-    lhs_ty,
-    rhs_ty
-});
-
-impl_stable_hash_for!(struct hir::MutTy {
-    ty,
-    mutbl
-});
-
-impl_stable_hash_for!(struct hir::MethodSig {
-    header,
-    decl
-});
-
-impl_stable_hash_for!(struct hir::TypeBinding {
-    hir_id,
-    ident -> (ident.name),
-    ty,
-    span
-});
-
-impl_stable_hash_for!(struct hir::FnHeader {
-    unsafety,
-    constness,
-    asyncness,
-    abi
-});
-
 impl<'a> HashStable<StableHashingContext<'a>> for hir::Ty {
     fn hash_stable<W: StableHasherResult>(&self,
                                           hcx: &mut StableHashingContext<'a>,
@@ -317,172 +152,10 @@ impl<'a> HashStable<StableHashingContext<'a>> for hir::Ty {
     }
 }
 
-impl_stable_hash_for!(enum hir::PrimTy {
-    Int(int_ty),
-    Uint(uint_ty),
-    Float(float_ty),
-    Str,
-    Bool,
-    Char
-});
-
-impl_stable_hash_for!(struct hir::BareFnTy {
-    unsafety,
-    abi,
-    generic_params,
-    decl,
-    arg_names
-});
-
-impl_stable_hash_for!(struct hir::ExistTy {
-    generics,
-    impl_trait_fn,
-    bounds
-});
-
-impl_stable_hash_for!(enum hir::TyKind {
-    Slice(t),
-    Array(t, body_id),
-    Ptr(t),
-    Rptr(lifetime, t),
-    BareFn(t),
-    Never,
-    Tup(ts),
-    Path(qpath),
-    Def(it, lt),
-    TraitObject(trait_refs, lifetime),
-    Typeof(body_id),
-    Err,
-    Infer,
-    CVarArgs(lt),
-});
-
-impl_stable_hash_for!(struct hir::FnDecl {
-    inputs,
-    output,
-    c_variadic,
-    implicit_self
-});
-
-impl_stable_hash_for!(enum hir::FunctionRetTy {
-    DefaultReturn(span),
-    Return(t)
-});
-
-impl_stable_hash_for!(enum hir::ImplicitSelfKind {
-    Imm,
-    Mut,
-    ImmRef,
-    MutRef,
-    None
-});
-
-impl_stable_hash_for!(struct hir::TraitRef {
-    // Don't hash the hir_ref_id. It is tracked via the thing it is used to access
-    hir_ref_id -> _,
-    path,
-});
-
-impl_stable_hash_for!(struct hir::PolyTraitRef {
-    bound_generic_params,
-    trait_ref,
-    span
-});
-
-impl_stable_hash_for!(enum hir::QPath {
-    Resolved(t, path),
-    TypeRelative(t, path_segment)
-});
-
-impl_stable_hash_for!(struct hir::MacroDef {
-    name,
-    vis,
-    attrs,
-    hir_id,
-    span,
-    legacy,
-    body
-});
-
-impl_stable_hash_for!(struct hir::Block {
-    stmts,
-    expr,
-    hir_id -> _,
-    rules,
-    span,
-    targeted_by_break,
-});
-
-impl_stable_hash_for!(struct hir::Pat {
-    hir_id -> _,
-    node,
-    span,
-});
-
 impl_stable_hash_for_spanned!(hir::FieldPat);
 
-impl_stable_hash_for!(struct hir::FieldPat {
-    hir_id -> _,
-    ident -> (ident.name),
-    pat,
-    is_shorthand,
-});
-
-impl_stable_hash_for!(enum hir::BindingAnnotation {
-    Unannotated,
-    Mutable,
-    Ref,
-    RefMut
-});
-
-impl_stable_hash_for!(enum hir::RangeEnd {
-    Included,
-    Excluded
-});
-
-impl_stable_hash_for!(enum hir::PatKind {
-    Wild,
-    Binding(binding_mode, hir_id, name, sub),
-    Struct(path, field_pats, dotdot),
-    TupleStruct(path, field_pats, dotdot),
-    Path(path),
-    Tuple(field_pats, dotdot),
-    Box(sub),
-    Ref(sub, mutability),
-    Lit(expr),
-    Range(start, end, end_kind),
-    Slice(one, two, three)
-});
-
-impl_stable_hash_for!(enum hir::BinOpKind {
-    Add,
-    Sub,
-    Mul,
-    Div,
-    Rem,
-    And,
-    Or,
-    BitXor,
-    BitAnd,
-    BitOr,
-    Shl,
-    Shr,
-    Eq,
-    Lt,
-    Le,
-    Ne,
-    Ge,
-    Gt
-});
-
 impl_stable_hash_for_spanned!(hir::BinOpKind);
 
-impl_stable_hash_for!(enum hir::UnOp {
-    UnDeref,
-    UnNot,
-    UnNeg
-});
-
 impl_stable_hash_for!(struct hir::Stmt {
     hir_id,
     node,
@@ -490,55 +163,8 @@ impl_stable_hash_for!(struct hir::Stmt {
 });
 
 
-impl_stable_hash_for!(struct hir::Local {
-    pat,
-    ty,
-    init,
-    hir_id,
-    span,
-    attrs,
-    source
-});
-
-impl_stable_hash_for!(struct hir::Arm {
-    attrs,
-    pats,
-    guard,
-    body
-});
-
-impl_stable_hash_for!(enum hir::Guard {
-    If(expr),
-});
-
-impl_stable_hash_for!(struct hir::Field {
-    hir_id -> _,
-    ident,
-    expr,
-    span,
-    is_shorthand,
-});
-
 impl_stable_hash_for_spanned!(ast::Name);
 
-
-impl_stable_hash_for!(enum hir::BlockCheckMode {
-    DefaultBlock,
-    UnsafeBlock(src),
-    PushUnsafeBlock(src),
-    PopUnsafeBlock(src)
-});
-
-impl_stable_hash_for!(enum hir::UnsafeSource {
-    CompilerGenerated,
-    UserProvided
-});
-
-impl_stable_hash_for!(struct hir::AnonConst {
-    hir_id,
-    body
-});
-
 impl<'a> HashStable<StableHashingContext<'a>> for hir::Expr {
     fn hash_stable<W: StableHasherResult>(&self,
                                           hcx: &mut StableHashingContext<'a>,
@@ -558,96 +184,10 @@ impl<'a> HashStable<StableHashingContext<'a>> for hir::Expr {
     }
 }
 
-impl_stable_hash_for!(enum hir::ExprKind {
-    Box(sub),
-    Array(subs),
-    Call(callee, args),
-    MethodCall(segment, span, args),
-    Tup(fields),
-    Binary(op, lhs, rhs),
-    Unary(op, operand),
-    Lit(value),
-    Cast(expr, t),
-    Type(expr, t),
-    If(cond, then, els),
-    While(cond, body, label),
-    Loop(body, label, loop_src),
-    Match(matchee, arms, match_src),
-    Closure(capture_clause, decl, body_id, span, gen),
-    Block(blk, label),
-    Assign(lhs, rhs),
-    AssignOp(op, lhs, rhs),
-    Field(owner, ident),
-    Index(lhs, rhs),
-    Path(path),
-    AddrOf(mutability, sub),
-    Break(destination, sub),
-    Continue(destination),
-    Ret(val),
-    InlineAsm(asm, inputs, outputs),
-    Struct(path, fields, base),
-    Repeat(val, times),
-    Yield(val),
-    Err
-});
-
-impl_stable_hash_for!(enum hir::LocalSource {
-    Normal,
-    ForLoopDesugar
-});
-
-impl_stable_hash_for!(enum hir::LoopSource {
-    Loop,
-    WhileLet,
-    ForLoop
-});
-
-impl<'a> HashStable<StableHashingContext<'a>> for hir::MatchSource {
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        use crate::hir::MatchSource;
-
-        mem::discriminant(self).hash_stable(hcx, hasher);
-        match *self {
-            MatchSource::Normal |
-            MatchSource::WhileLetDesugar |
-            MatchSource::ForLoopDesugar |
-            MatchSource::TryDesugar => {
-                // No fields to hash.
-            }
-            MatchSource::IfLetDesugar { contains_else_clause } => {
-                contains_else_clause.hash_stable(hcx, hasher);
-            }
-        }
-    }
-}
-
-impl_stable_hash_for!(enum hir::GeneratorMovability {
-    Static,
-    Movable
-});
-
-impl_stable_hash_for!(enum hir::CaptureClause {
-    CaptureByValue,
-    CaptureByRef
-});
-
 impl_stable_hash_for_spanned!(usize);
 
-impl_stable_hash_for!(struct hir::Destination {
-    label,
-    target_id
-});
-
 impl_stable_hash_for_spanned!(ast::Ident);
 
-impl_stable_hash_for!(enum hir::LoopIdError {
-    OutsideLoopScope,
-    UnlabeledCfInWhileCondition,
-    UnresolvedLabel
-});
-
 impl_stable_hash_for!(struct ast::Ident {
     name,
     span,
@@ -676,16 +216,6 @@ impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitItem {
     }
 }
 
-impl_stable_hash_for!(enum hir::TraitMethod {
-    Required(name),
-    Provided(body)
-});
-
-impl_stable_hash_for!(enum hir::TraitItemKind {
-    Const(t, body),
-    Method(sig, method),
-    Type(bounds, rhs)
-});
 
 impl<'a> HashStable<StableHashingContext<'a>> for hir::ImplItem {
     fn hash_stable<W: StableHasherResult>(&self,
@@ -714,13 +244,6 @@ impl<'a> HashStable<StableHashingContext<'a>> for hir::ImplItem {
     }
 }
 
-impl_stable_hash_for!(enum hir::ImplItemKind {
-    Const(t, body),
-    Method(sig, body),
-    Existential(bounds),
-    Type(t)
-});
-
 impl_stable_hash_for!(enum ::syntax::ast::CrateSugar {
     JustCrate,
     PubCrate,
@@ -751,27 +274,6 @@ impl<'a> HashStable<StableHashingContext<'a>> for hir::VisibilityKind {
 
 impl_stable_hash_for_spanned!(hir::VisibilityKind);
 
-impl<'a> HashStable<StableHashingContext<'a>> for hir::Defaultness {
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        mem::discriminant(self).hash_stable(hcx, hasher);
-        match *self {
-            hir::Defaultness::Final => {
-                // No fields to hash.
-            }
-            hir::Defaultness::Default { has_value } => {
-                has_value.hash_stable(hcx, hasher);
-            }
-        }
-    }
-}
-
-impl_stable_hash_for!(enum hir::ImplPolarity {
-    Positive,
-    Negative
-});
-
 impl<'a> HashStable<StableHashingContext<'a>> for hir::Mod {
     fn hash_stable<W: StableHasherResult>(&self,
                                           hcx: &mut StableHashingContext<'a>,
@@ -801,44 +303,8 @@ impl<'a> HashStable<StableHashingContext<'a>> for hir::Mod {
     }
 }
 
-impl_stable_hash_for!(struct hir::ForeignMod {
-    abi,
-    items
-});
-
-impl_stable_hash_for!(struct hir::EnumDef {
-    variants
-});
-
-impl_stable_hash_for!(struct hir::VariantKind {
-    ident -> (ident.name),
-    attrs,
-    data,
-    disr_expr
-});
-
 impl_stable_hash_for_spanned!(hir::VariantKind);
 
-impl_stable_hash_for!(enum hir::UseKind {
-    Single,
-    Glob,
-    ListStem
-});
-
-impl_stable_hash_for!(struct hir::StructField {
-    span,
-    ident -> (ident.name),
-    vis,
-    hir_id,
-    ty,
-    attrs
-});
-
-impl_stable_hash_for!(enum hir::VariantData {
-    Struct(fields, hir_id),
-    Tuple(fields, hir_id),
-    Unit(hir_id)
-});
 
 impl<'a> HashStable<StableHashingContext<'a>> for hir::Item {
     fn hash_stable<W: StableHasherResult>(&self,
@@ -863,87 +329,6 @@ impl<'a> HashStable<StableHashingContext<'a>> for hir::Item {
     }
 }
 
-impl_stable_hash_for!(enum hir::ItemKind {
-    ExternCrate(orig_name),
-    Use(path, use_kind),
-    Static(ty, mutability, body_id),
-    Const(ty, body_id),
-    Fn(fn_decl, header, generics, body_id),
-    Mod(module),
-    ForeignMod(foreign_mod),
-    GlobalAsm(global_asm),
-    Ty(ty, generics),
-    Existential(exist),
-    Enum(enum_def, generics),
-    Struct(variant_data, generics),
-    Union(variant_data, generics),
-    Trait(is_auto, unsafety, generics, bounds, item_refs),
-    TraitAlias(generics, bounds),
-    Impl(unsafety, impl_polarity, impl_defaultness, generics, trait_ref, ty, impl_item_refs)
-});
-
-impl_stable_hash_for!(struct hir::TraitItemRef {
-    id,
-    ident -> (ident.name),
-    kind,
-    span,
-    defaultness
-});
-
-impl_stable_hash_for!(struct hir::ImplItemRef {
-    id,
-    ident -> (ident.name),
-    kind,
-    span,
-    vis,
-    defaultness
-});
-
-impl<'a> HashStable<StableHashingContext<'a>> for hir::AssociatedItemKind {
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        mem::discriminant(self).hash_stable(hcx, hasher);
-        match *self {
-            hir::AssociatedItemKind::Const |
-            hir::AssociatedItemKind::Existential |
-            hir::AssociatedItemKind::Type => {
-                // No fields to hash.
-            }
-            hir::AssociatedItemKind::Method { has_self } => {
-                has_self.hash_stable(hcx, hasher);
-            }
-        }
-    }
-}
-
-impl_stable_hash_for!(struct hir::ForeignItem {
-    ident -> (ident.name),
-    attrs,
-    node,
-    hir_id,
-    span,
-    vis
-});
-
-impl_stable_hash_for!(enum hir::ForeignItemKind {
-    Fn(fn_decl, arg_names, generics),
-    Static(ty, is_mutbl),
-    Type
-});
-
-impl_stable_hash_for!(enum hir::StmtKind {
-    Local(local),
-    Item(item_id),
-    Expr(expr),
-    Semi(expr)
-});
-
-impl_stable_hash_for!(struct hir::Arg {
-    pat,
-    hir_id
-});
-
 impl<'a> HashStable<StableHashingContext<'a>> for hir::Body {
     fn hash_stable<W: StableHasherResult>(&self,
                                           hcx: &mut StableHashingContext<'a>,
@@ -974,103 +359,6 @@ impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::BodyId {
     }
 }
 
-impl_stable_hash_for!(struct hir::InlineAsmOutput {
-    constraint,
-    is_rw,
-    is_indirect,
-    span
-});
-
-impl_stable_hash_for!(struct hir::GlobalAsm {
-    asm,
-    ctxt -> _, // This is used for error reporting
-});
-
-impl_stable_hash_for!(struct hir::InlineAsm {
-    asm,
-    asm_str_style,
-    outputs,
-    inputs,
-    clobbers,
-    volatile,
-    alignstack,
-    dialect,
-    ctxt -> _, // This is used for error reporting
-});
-
-impl_stable_hash_for!(enum hir::def::CtorKind {
-    Fn,
-    Const,
-    Fictive
-});
-
-impl_stable_hash_for!(enum hir::def::NonMacroAttrKind {
-    Builtin,
-    Tool,
-    DeriveHelper,
-    LegacyPluginHelper,
-    Custom,
-});
-
-impl_stable_hash_for!(enum hir::def::Def {
-    Mod(def_id),
-    Struct(def_id),
-    Union(def_id),
-    Enum(def_id),
-    Existential(def_id),
-    Variant(def_id),
-    Trait(def_id),
-    TyAlias(def_id),
-    TraitAlias(def_id),
-    AssociatedTy(def_id),
-    AssociatedExistential(def_id),
-    PrimTy(prim_ty),
-    TyParam(def_id),
-    ConstParam(def_id),
-    SelfTy(trait_def_id, impl_def_id),
-    ForeignTy(def_id),
-    Fn(def_id),
-    Const(def_id),
-    Static(def_id, is_mutbl),
-    StructCtor(def_id, ctor_kind),
-    SelfCtor(impl_def_id),
-    VariantCtor(def_id, ctor_kind),
-    Method(def_id),
-    AssociatedConst(def_id),
-    Local(def_id),
-    Upvar(def_id, index, expr_id),
-    Label(node_id),
-    Macro(def_id, macro_kind),
-    ToolMod,
-    NonMacroAttr(attr_kind),
-    Err
-});
-
-impl_stable_hash_for!(enum hir::Mutability {
-    MutMutable,
-    MutImmutable
-});
-
-impl_stable_hash_for!(enum hir::IsAuto {
-    Yes,
-    No
-});
-
-impl_stable_hash_for!(enum hir::Unsafety {
-    Unsafe,
-    Normal
-});
-
-impl_stable_hash_for!(enum hir::IsAsync {
-    Async,
-    NotAsync
-});
-
-impl_stable_hash_for!(enum hir::Constness {
-    Const,
-    NotConst
-});
-
 impl<'a> HashStable<StableHashingContext<'a>> for hir::def_id::DefIndex {
 
     fn hash_stable<W: StableHasherResult>(&self,
@@ -1090,18 +378,6 @@ for hir::def_id::DefIndex {
     }
 }
 
-impl_stable_hash_for!(struct hir::def::Export {
-    ident,
-    def,
-    vis,
-    span
-});
-
-impl_stable_hash_for!(struct crate::middle::lib_features::LibFeatures {
-    stable,
-    unstable
-});
-
 impl<'a> HashStable<StableHashingContext<'a>> for crate::middle::lang_items::LangItem {
     fn hash_stable<W: StableHasherResult>(&self,
                                           _: &mut StableHashingContext<'a>,
@@ -1110,11 +386,6 @@ impl<'a> HashStable<StableHashingContext<'a>> for crate::middle::lang_items::Lan
     }
 }
 
-impl_stable_hash_for!(struct crate::middle::lang_items::LanguageItems {
-    items,
-    missing
-});
-
 impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitCandidate {
     fn hash_stable<W: StableHasherResult>(&self,
                                           hcx: &mut StableHashingContext<'a>,
@@ -1149,26 +420,6 @@ impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::TraitCandidate {
     }
 }
 
-impl_stable_hash_for!(struct hir::CodegenFnAttrs {
-    flags,
-    inline,
-    optimize,
-    export_name,
-    link_name,
-    target_features,
-    linkage,
-    link_section,
-});
-
-impl<'hir> HashStable<StableHashingContext<'hir>> for hir::CodegenFnAttrFlags
-{
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'hir>,
-                                          hasher: &mut StableHasher<W>) {
-        self.bits().hash_stable(hcx, hasher);
-    }
-}
-
 impl<'hir> HashStable<StableHashingContext<'hir>> for attr::InlineAttr {
     fn hash_stable<W: StableHasherResult>(&self,
                                           hcx: &mut StableHashingContext<'hir>,
@@ -1185,7 +436,3 @@ impl<'hir> HashStable<StableHashingContext<'hir>> for attr::OptimizeAttr {
     }
 }
 
-impl_stable_hash_for!(struct hir::Freevar {
-    def,
-    span
-});
diff --git a/src/librustc/ich/impls_mir.rs b/src/librustc/ich/impls_mir.rs
deleted file mode 100644
index ba47116434f..00000000000
--- a/src/librustc/ich/impls_mir.rs
+++ /dev/null
@@ -1,504 +0,0 @@
-//! This module contains `HashStable` implementations for various MIR data
-//! types in no particular order.
-
-use crate::ich::StableHashingContext;
-use crate::mir;
-use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
-                                           StableHasherResult};
-use std::mem;
-
-impl_stable_hash_for!(struct mir::GeneratorLayout<'tcx> { fields });
-impl_stable_hash_for!(struct mir::SourceInfo { span, scope });
-impl_stable_hash_for!(enum mir::Mutability { Mut, Not });
-impl_stable_hash_for!(enum mir::LocalKind { Var, Temp, Arg, ReturnPointer });
-impl_stable_hash_for!(struct mir::LocalDecl<'tcx> {
-    mutability,
-    ty,
-    user_ty,
-    name,
-    source_info,
-    visibility_scope,
-    internal,
-    is_block_tail,
-    is_user_variable
-});
-impl_stable_hash_for!(struct mir::UpvarDecl { debug_name, var_hir_id, by_ref, mutability });
-impl_stable_hash_for!(struct mir::BasicBlockData<'tcx> { statements, terminator, is_cleanup });
-impl_stable_hash_for!(struct mir::UnsafetyViolation { source_info, description, details, kind });
-impl_stable_hash_for!(struct mir::UnsafetyCheckResult { violations, unsafe_blocks });
-
-impl_stable_hash_for!(enum mir::BorrowKind {
-    Shared,
-    Shallow,
-    Unique,
-    Mut { allow_two_phase_borrow },
-});
-
-impl_stable_hash_for!(enum mir::UnsafetyViolationKind {
-    General,
-    GeneralAndConstFn,
-    ExternStatic(lint_node_id),
-    BorrowPacked(lint_node_id),
-});
-
-impl_stable_hash_for!(struct mir::Terminator<'tcx> {
-    kind,
-    source_info
-});
-
-impl_stable_hash_for!(
-    impl<T> for enum mir::ClearCrossCrate<T> [ mir::ClearCrossCrate ] {
-        Clear,
-        Set(value),
-    }
-);
-
-impl<'a> HashStable<StableHashingContext<'a>> for mir::Local {
-    #[inline]
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        self.index().hash_stable(hcx, hasher);
-    }
-}
-
-impl<'a> HashStable<StableHashingContext<'a>> for mir::BasicBlock {
-    #[inline]
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        self.index().hash_stable(hcx, hasher);
-    }
-}
-
-impl<'a> HashStable<StableHashingContext<'a>> for mir::Field {
-    #[inline]
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        self.index().hash_stable(hcx, hasher);
-    }
-}
-
-impl<'a> HashStable<StableHashingContext<'a>>
-for mir::SourceScope {
-    #[inline]
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        self.index().hash_stable(hcx, hasher);
-    }
-}
-
-impl<'a> HashStable<StableHashingContext<'a>> for mir::Promoted {
-    #[inline]
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        self.index().hash_stable(hcx, hasher);
-    }
-}
-
-impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
-for mir::TerminatorKind<'gcx> {
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        mem::discriminant(self).hash_stable(hcx, hasher);
-
-        match *self {
-            mir::TerminatorKind::Goto { ref target } => {
-                target.hash_stable(hcx, hasher);
-            }
-            mir::TerminatorKind::SwitchInt { ref discr,
-                                             switch_ty,
-                                             ref values,
-                                             ref targets } => {
-                discr.hash_stable(hcx, hasher);
-                switch_ty.hash_stable(hcx, hasher);
-                values.hash_stable(hcx, hasher);
-                targets.hash_stable(hcx, hasher);
-            }
-            mir::TerminatorKind::Resume |
-            mir::TerminatorKind::Abort |
-            mir::TerminatorKind::Return |
-            mir::TerminatorKind::GeneratorDrop |
-            mir::TerminatorKind::Unreachable => {}
-            mir::TerminatorKind::Drop { ref location, target, unwind } => {
-                location.hash_stable(hcx, hasher);
-                target.hash_stable(hcx, hasher);
-                unwind.hash_stable(hcx, hasher);
-            }
-            mir::TerminatorKind::DropAndReplace { ref location,
-                                                  ref value,
-                                                  target,
-                                                  unwind, } => {
-                location.hash_stable(hcx, hasher);
-                value.hash_stable(hcx, hasher);
-                target.hash_stable(hcx, hasher);
-                unwind.hash_stable(hcx, hasher);
-            }
-            mir::TerminatorKind::Yield { ref value,
-                                        resume,
-                                        drop } => {
-                value.hash_stable(hcx, hasher);
-                resume.hash_stable(hcx, hasher);
-                drop.hash_stable(hcx, hasher);
-            }
-            mir::TerminatorKind::Call { ref func,
-                                        ref args,
-                                        ref destination,
-                                        cleanup,
-                                        from_hir_call, } => {
-                func.hash_stable(hcx, hasher);
-                args.hash_stable(hcx, hasher);
-                destination.hash_stable(hcx, hasher);
-                cleanup.hash_stable(hcx, hasher);
-                from_hir_call.hash_stable(hcx, hasher);
-            }
-            mir::TerminatorKind::Assert { ref cond,
-                                          expected,
-                                          ref msg,
-                                          target,
-                                          cleanup } => {
-                cond.hash_stable(hcx, hasher);
-                expected.hash_stable(hcx, hasher);
-                msg.hash_stable(hcx, hasher);
-                target.hash_stable(hcx, hasher);
-                cleanup.hash_stable(hcx, hasher);
-            }
-            mir::TerminatorKind::FalseEdges { ref real_target, ref imaginary_targets } => {
-                real_target.hash_stable(hcx, hasher);
-                for target in imaginary_targets {
-                    target.hash_stable(hcx, hasher);
-                }
-            }
-            mir::TerminatorKind::FalseUnwind { ref real_target, ref unwind } => {
-                real_target.hash_stable(hcx, hasher);
-                unwind.hash_stable(hcx, hasher);
-            }
-        }
-    }
-}
-
-impl_stable_hash_for!(struct mir::Statement<'tcx> { source_info, kind });
-
-impl_stable_hash_for!(impl<'gcx> for enum mir::StatementKind<'gcx> [ mir::StatementKind ] {
-    Assign(place, rvalue),
-    FakeRead(cause, place),
-    SetDiscriminant { place, variant_index },
-    StorageLive(place),
-    StorageDead(place),
-    Retag(retag_kind, place),
-    AscribeUserType(place, variance, c_ty),
-    Nop,
-    InlineAsm { asm, outputs, inputs },
-});
-
-impl_stable_hash_for!(enum mir::RetagKind { FnEntry, TwoPhase, Raw, Default });
-impl_stable_hash_for!(enum mir::FakeReadCause {
-    ForMatchGuard,
-    ForMatchedPlace,
-    ForGuardBinding,
-    ForLet
-});
-
-impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for mir::Place<'gcx> {
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        mem::discriminant(self).hash_stable(hcx, hasher);
-        match *self {
-            mir::Place::Base(mir::PlaceBase::Local(ref local)) => {
-                local.hash_stable(hcx, hasher);
-            }
-            mir::Place::Base(mir::PlaceBase::Static(ref statik)) => {
-                statik.hash_stable(hcx, hasher);
-            }
-            mir::Place::Base(mir::PlaceBase::Promoted(ref promoted)) => {
-                promoted.hash_stable(hcx, hasher);
-            }
-            mir::Place::Projection(ref place_projection) => {
-                place_projection.hash_stable(hcx, hasher);
-            }
-        }
-    }
-}
-
-impl<'a, 'gcx, B, V, T> HashStable<StableHashingContext<'a>>
-for mir::Projection<'gcx, B, V, T>
-    where B: HashStable<StableHashingContext<'a>>,
-          V: HashStable<StableHashingContext<'a>>,
-          T: HashStable<StableHashingContext<'a>>
-{
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        let mir::Projection {
-            ref base,
-            ref elem,
-        } = *self;
-
-        base.hash_stable(hcx, hasher);
-        elem.hash_stable(hcx, hasher);
-    }
-}
-
-impl<'a, 'gcx, V, T> HashStable<StableHashingContext<'a>>
-for mir::ProjectionElem<'gcx, V, T>
-    where V: HashStable<StableHashingContext<'a>>,
-          T: HashStable<StableHashingContext<'a>>
-{
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        mem::discriminant(self).hash_stable(hcx, hasher);
-        match *self {
-            mir::ProjectionElem::Deref => {}
-            mir::ProjectionElem::Field(field, ref ty) => {
-                field.hash_stable(hcx, hasher);
-                ty.hash_stable(hcx, hasher);
-            }
-            mir::ProjectionElem::Index(ref value) => {
-                value.hash_stable(hcx, hasher);
-            }
-            mir::ProjectionElem::ConstantIndex { offset, min_length, from_end } => {
-                offset.hash_stable(hcx, hasher);
-                min_length.hash_stable(hcx, hasher);
-                from_end.hash_stable(hcx, hasher);
-            }
-            mir::ProjectionElem::Subslice { from, to } => {
-                from.hash_stable(hcx, hasher);
-                to.hash_stable(hcx, hasher);
-            }
-            mir::ProjectionElem::Downcast(adt_def, variant) => {
-                adt_def.hash_stable(hcx, hasher);
-                variant.hash_stable(hcx, hasher);
-            }
-        }
-    }
-}
-
-impl_stable_hash_for!(struct mir::SourceScopeData { span, parent_scope });
-impl_stable_hash_for!(struct mir::SourceScopeLocalData {
-    lint_root, safety
-});
-
-impl<'a> HashStable<StableHashingContext<'a>> for mir::Safety {
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        mem::discriminant(self).hash_stable(hcx, hasher);
-
-        match *self {
-            mir::Safety::Safe |
-            mir::Safety::BuiltinUnsafe |
-            mir::Safety::FnUnsafe => {}
-            mir::Safety::ExplicitUnsafe(node_id) => {
-                node_id.hash_stable(hcx, hasher);
-            }
-        }
-    }
-}
-
-impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for mir::Operand<'gcx> {
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        mem::discriminant(self).hash_stable(hcx, hasher);
-
-        match *self {
-            mir::Operand::Copy(ref place) => {
-                place.hash_stable(hcx, hasher);
-            }
-            mir::Operand::Move(ref place) => {
-                place.hash_stable(hcx, hasher);
-            }
-            mir::Operand::Constant(ref constant) => {
-                constant.hash_stable(hcx, hasher);
-            }
-        }
-    }
-}
-
-impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for mir::Rvalue<'gcx> {
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        mem::discriminant(self).hash_stable(hcx, hasher);
-
-        match *self {
-            mir::Rvalue::Use(ref operand) => {
-                operand.hash_stable(hcx, hasher);
-            }
-            mir::Rvalue::Repeat(ref operand, ref val) => {
-                operand.hash_stable(hcx, hasher);
-                val.hash_stable(hcx, hasher);
-            }
-            mir::Rvalue::Ref(region, borrow_kind, ref place) => {
-                region.hash_stable(hcx, hasher);
-                borrow_kind.hash_stable(hcx, hasher);
-                place.hash_stable(hcx, hasher);
-            }
-            mir::Rvalue::Len(ref place) => {
-                place.hash_stable(hcx, hasher);
-            }
-            mir::Rvalue::Cast(cast_kind, ref operand, ty) => {
-                cast_kind.hash_stable(hcx, hasher);
-                operand.hash_stable(hcx, hasher);
-                ty.hash_stable(hcx, hasher);
-            }
-            mir::Rvalue::BinaryOp(op, ref operand1, ref operand2) |
-            mir::Rvalue::CheckedBinaryOp(op, ref operand1, ref operand2) => {
-                op.hash_stable(hcx, hasher);
-                operand1.hash_stable(hcx, hasher);
-                operand2.hash_stable(hcx, hasher);
-            }
-            mir::Rvalue::UnaryOp(op, ref operand) => {
-                op.hash_stable(hcx, hasher);
-                operand.hash_stable(hcx, hasher);
-            }
-            mir::Rvalue::Discriminant(ref place) => {
-                place.hash_stable(hcx, hasher);
-            }
-            mir::Rvalue::NullaryOp(op, ty) => {
-                op.hash_stable(hcx, hasher);
-                ty.hash_stable(hcx, hasher);
-            }
-            mir::Rvalue::Aggregate(ref kind, ref operands) => {
-                kind.hash_stable(hcx, hasher);
-                operands.hash_stable(hcx, hasher);
-            }
-        }
-    }
-}
-
-impl_stable_hash_for!(enum mir::CastKind {
-    Misc,
-    ReifyFnPointer,
-    ClosureFnPointer,
-    UnsafeFnPointer,
-    MutToConstPointer,
-    Unsize
-});
-
-impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
-for mir::AggregateKind<'gcx> {
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        mem::discriminant(self).hash_stable(hcx, hasher);
-        match *self {
-            mir::AggregateKind::Tuple => {}
-            mir::AggregateKind::Array(t) => {
-                t.hash_stable(hcx, hasher);
-            }
-            mir::AggregateKind::Adt(adt_def, idx, substs, user_substs, active_field) => {
-                adt_def.hash_stable(hcx, hasher);
-                idx.hash_stable(hcx, hasher);
-                substs.hash_stable(hcx, hasher);
-                user_substs.hash_stable(hcx, hasher);
-                active_field.hash_stable(hcx, hasher);
-            }
-            mir::AggregateKind::Closure(def_id, ref substs) => {
-                def_id.hash_stable(hcx, hasher);
-                substs.hash_stable(hcx, hasher);
-            }
-            mir::AggregateKind::Generator(def_id, ref substs, movability) => {
-                def_id.hash_stable(hcx, hasher);
-                substs.hash_stable(hcx, hasher);
-                movability.hash_stable(hcx, hasher);
-            }
-        }
-    }
-}
-
-impl_stable_hash_for!(enum mir::BinOp {
-    Add,
-    Sub,
-    Mul,
-    Div,
-    Rem,
-    BitXor,
-    BitAnd,
-    BitOr,
-    Shl,
-    Shr,
-    Eq,
-    Lt,
-    Le,
-    Ne,
-    Ge,
-    Gt,
-    Offset
-});
-
-impl_stable_hash_for!(enum mir::UnOp {
-    Not,
-    Neg
-});
-
-impl_stable_hash_for!(enum mir::NullOp {
-    Box,
-    SizeOf
-});
-
-impl_stable_hash_for!(struct mir::Constant<'tcx> { span, ty, user_ty, literal });
-
-impl_stable_hash_for!(struct mir::Location { block, statement_index });
-
-impl_stable_hash_for!(struct mir::BorrowCheckResult<'tcx> {
-    closure_requirements,
-    used_mut_upvars
-});
-
-impl_stable_hash_for!(struct mir::ClosureRegionRequirements<'tcx> {
-    num_external_vids,
-    outlives_requirements
-});
-
-impl_stable_hash_for!(struct mir::ClosureOutlivesRequirement<'tcx> {
-    subject,
-    outlived_free_region,
-    blame_span,
-    category
-});
-
-impl_stable_hash_for!(enum mir::ConstraintCategory {
-    Return,
-    Yield,
-    UseAsConst,
-    UseAsStatic,
-    TypeAnnotation,
-    Cast,
-    ClosureBounds,
-    CallArgument,
-    CopyBound,
-    SizedBound,
-    Assignment,
-    OpaqueType,
-    Boring,
-    BoringNoLocation,
-    Internal,
-});
-
-impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for mir::ClosureOutlivesSubject<'gcx> {
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        mem::discriminant(self).hash_stable(hcx, hasher);
-        match *self {
-            mir::ClosureOutlivesSubject::Ty(ref ty) => {
-                ty.hash_stable(hcx, hasher);
-            }
-            mir::ClosureOutlivesSubject::Region(ref region) => {
-                region.hash_stable(hcx, hasher);
-            }
-        }
-    }
-}
-
-impl_stable_hash_for!(struct mir::interpret::GlobalId<'tcx> { instance, promoted });
-
-impl_stable_hash_for!(struct mir::UserTypeProjection<'tcx> { base, projs });
-impl_stable_hash_for!(struct mir::UserTypeProjections<'tcx> { contents });
diff --git a/src/librustc/ich/impls_misc.rs b/src/librustc/ich/impls_misc.rs
index 8a388fafce5..417305139e4 100644
--- a/src/librustc/ich/impls_misc.rs
+++ b/src/librustc/ich/impls_misc.rs
@@ -1,15 +1,6 @@
 //! This module contains `HashStable` implementations for various data types
 //! that don't fit into any of the other impls_xxx modules.
 
-impl_stable_hash_for!(enum crate::session::search_paths::PathKind {
-    Native,
-    Crate,
-    Dependency,
-    Framework,
-    ExternFlag,
-    All
-});
-
 impl_stable_hash_for!(enum ::rustc_target::spec::PanicStrategy {
     Abort,
     Unwind
diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs
index 7e0abf75230..ec1b0da6810 100644
--- a/src/librustc/ich/impls_ty.rs
+++ b/src/librustc/ich/impls_ty.rs
@@ -6,11 +6,8 @@ use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey,
                                            StableHasher, StableHasherResult};
 use std::cell::RefCell;
-use std::hash as std_hash;
 use std::mem;
 use crate::middle::region;
-use crate::infer;
-use crate::traits;
 use crate::ty;
 use crate::mir;
 
@@ -65,20 +62,6 @@ impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for ty::subst::Kind<'gcx> {
     }
 }
 
-impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
-for ty::subst::UnpackedKind<'gcx> {
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        mem::discriminant(self).hash_stable(hcx, hasher);
-        match self {
-            ty::subst::UnpackedKind::Lifetime(lt) => lt.hash_stable(hcx, hasher),
-            ty::subst::UnpackedKind::Type(ty) => ty.hash_stable(hcx, hasher),
-            ty::subst::UnpackedKind::Const(ct) => ct.hash_stable(hcx, hasher),
-        }
-    }
-}
-
 impl<'a> HashStable<StableHashingContext<'a>>
 for ty::RegionKind {
     fn hash_stable<W: StableHasherResult>(&self,
@@ -153,105 +136,6 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for ty::BoundVar {
     }
 }
 
-impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
-for ty::adjustment::AutoBorrow<'gcx> {
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        mem::discriminant(self).hash_stable(hcx, hasher);
-        match *self {
-            ty::adjustment::AutoBorrow::Ref(ref region, mutability) => {
-                region.hash_stable(hcx, hasher);
-                mutability.hash_stable(hcx, hasher);
-            }
-            ty::adjustment::AutoBorrow::RawPtr(mutability) => {
-                mutability.hash_stable(hcx, hasher);
-            }
-        }
-    }
-}
-
-impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
-for ty::adjustment::Adjust<'gcx> {
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        mem::discriminant(self).hash_stable(hcx, hasher);
-        match *self {
-            ty::adjustment::Adjust::NeverToAny |
-            ty::adjustment::Adjust::ReifyFnPointer |
-            ty::adjustment::Adjust::UnsafeFnPointer |
-            ty::adjustment::Adjust::ClosureFnPointer |
-            ty::adjustment::Adjust::MutToConstPointer |
-            ty::adjustment::Adjust::Unsize => {}
-            ty::adjustment::Adjust::Deref(ref overloaded) => {
-                overloaded.hash_stable(hcx, hasher);
-            }
-            ty::adjustment::Adjust::Borrow(ref autoref) => {
-                autoref.hash_stable(hcx, hasher);
-            }
-        }
-    }
-}
-
-impl_stable_hash_for!(struct ty::adjustment::Adjustment<'tcx> { kind, target });
-impl_stable_hash_for!(struct ty::adjustment::OverloadedDeref<'tcx> { region, mutbl });
-impl_stable_hash_for!(struct ty::UpvarBorrow<'tcx> { kind, region });
-impl_stable_hash_for!(enum ty::adjustment::AllowTwoPhase {
-    Yes,
-    No
-});
-
-impl<'gcx> HashStable<StableHashingContext<'gcx>> for ty::adjustment::AutoBorrowMutability {
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'gcx>,
-                                          hasher: &mut StableHasher<W>) {
-        mem::discriminant(self).hash_stable(hcx, hasher);
-        match *self {
-            ty::adjustment::AutoBorrowMutability::Mutable { ref allow_two_phase_borrow } => {
-                allow_two_phase_borrow.hash_stable(hcx, hasher);
-            }
-            ty::adjustment::AutoBorrowMutability::Immutable => {}
-        }
-    }
-}
-
-impl_stable_hash_for!(tuple_struct ty::util::NeedsDrop { value });
-
-impl_stable_hash_for!(tuple_struct ty::AdtSizedConstraint<'tcx> { list });
-
-impl_stable_hash_for!(struct ty::UpvarPath { hir_id });
-
-impl_stable_hash_for!(struct ty::UpvarId { var_path, closure_expr_id });
-
-impl_stable_hash_for!(enum ty::BorrowKind {
-    ImmBorrow,
-    UniqueImmBorrow,
-    MutBorrow
-});
-
-impl_stable_hash_for!(impl<'gcx> for enum ty::UpvarCapture<'gcx> [ ty::UpvarCapture ] {
-    ByValue,
-    ByRef(up_var_borrow),
-});
-
-impl_stable_hash_for!(struct ty::GenSig<'tcx> {
-    yield_ty,
-    return_ty
-});
-
-impl_stable_hash_for!(struct ty::FnSig<'tcx> {
-    inputs_and_output,
-    c_variadic,
-    unsafety,
-    abi
-});
-
-impl_stable_hash_for!(struct ty::ResolvedOpaqueTy<'tcx> {
-    concrete_type,
-    substs
-});
-
 impl<'a, 'gcx, T> HashStable<StableHashingContext<'a>> for ty::Binder<T>
     where T: HashStable<StableHashingContext<'a>>
 {
@@ -262,108 +146,6 @@ impl<'a, 'gcx, T> HashStable<StableHashingContext<'a>> for ty::Binder<T>
     }
 }
 
-impl_stable_hash_for!(enum ty::ClosureKind { Fn, FnMut, FnOnce });
-
-impl_stable_hash_for!(enum ty::Visibility {
-    Public,
-    Restricted(def_id),
-    Invisible
-});
-
-impl_stable_hash_for!(struct ty::TraitRef<'tcx> { def_id, substs });
-impl_stable_hash_for!(struct ty::TraitPredicate<'tcx> { trait_ref });
-impl_stable_hash_for!(struct ty::SubtypePredicate<'tcx> { a_is_expected, a, b });
-impl_stable_hash_for!(impl<A, B> for tuple_struct ty::OutlivesPredicate<A, B> { a, b });
-impl_stable_hash_for!(struct ty::ProjectionPredicate<'tcx> { projection_ty, ty });
-impl_stable_hash_for!(struct ty::ProjectionTy<'tcx> { substs, item_def_id });
-
-impl_stable_hash_for!(
-    impl<'tcx> for enum ty::Predicate<'tcx> [ ty::Predicate ] {
-        Trait(pred),
-        Subtype(pred),
-        RegionOutlives(pred),
-        TypeOutlives(pred),
-        Projection(pred),
-        WellFormed(ty),
-        ObjectSafe(def_id),
-        ClosureKind(def_id, closure_substs, closure_kind),
-        ConstEvaluatable(def_id, substs),
-    }
-);
-
-impl<'a> HashStable<StableHashingContext<'a>> for ty::AdtFlags {
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          _: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        std_hash::Hash::hash(self, hasher);
-    }
-}
-
-impl<'a> HashStable<StableHashingContext<'a>> for ty::VariantFlags {
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          _: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        std_hash::Hash::hash(self, hasher);
-    }
-}
-
-impl_stable_hash_for!(
-    impl<'tcx> for enum ty::InferConst<'tcx> [ ty::InferConst ] {
-        Var(vid),
-        Fresh(i),
-        Canonical(debruijn, var),
-    }
-);
-
-impl_stable_hash_for!(enum ty::VariantDiscr {
-    Explicit(def_id),
-    Relative(distance)
-});
-
-impl_stable_hash_for!(struct ty::FieldDef {
-    did,
-    ident -> (ident.name),
-    vis,
-});
-
-impl_stable_hash_for!(
-    impl<'tcx> for enum mir::interpret::ConstValue<'tcx> [ mir::interpret::ConstValue ] {
-        Param(param),
-        Infer(infer),
-        Scalar(val),
-        Slice(a, b),
-        ByRef(ptr, alloc),
-    }
-);
-
-impl_stable_hash_for!(struct crate::mir::interpret::RawConst<'tcx> {
-    alloc_id,
-    ty,
-});
-
-impl_stable_hash_for! {
-    impl<Tag> for struct mir::interpret::Pointer<Tag> {
-        alloc_id,
-        offset,
-        tag,
-    }
-}
-
-impl_stable_hash_for!(
-    impl<Tag> for enum mir::interpret::Scalar<Tag> [ mir::interpret::Scalar ] {
-        Bits { bits, size },
-        Ptr(ptr),
-    }
-);
-
-impl_stable_hash_for!(
-    impl<'tcx> for enum mir::interpret::AllocKind<'tcx> [ mir::interpret::AllocKind ] {
-        Function(instance),
-        Static(def_id),
-        Memory(mem),
-    }
-);
-
 // AllocIds get resolved to whatever they point to (to be stable)
 impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::AllocId {
     fn hash_stable<W: StableHasherResult>(
@@ -402,194 +184,6 @@ impl_stable_hash_for!(enum ::syntax::ast::Mutability {
     Mutable
 });
 
-impl_stable_hash_for!(struct ty::Const<'tcx> {
-    ty,
-    val
-});
-
-impl_stable_hash_for!(impl<'tcx> for enum ty::LazyConst<'tcx> [ty::LazyConst] {
-    Unevaluated(did, substs),
-    Evaluated(c)
-});
-
-impl_stable_hash_for!(enum mir::interpret::ErrorHandled {
-    Reported,
-    TooGeneric
-});
-
-impl_stable_hash_for!(struct mir::interpret::FrameInfo<'tcx> {
-    call_site,
-    lint_root,
-    instance
-});
-
-impl_stable_hash_for!(struct ty::ClosureSubsts<'tcx> { substs });
-impl_stable_hash_for!(struct ty::GeneratorSubsts<'tcx> { substs });
-
-impl_stable_hash_for!(struct ty::GenericPredicates<'tcx> {
-    parent,
-    predicates
-});
-
-impl_stable_hash_for!(
-    impl<'tcx, O> for enum mir::interpret::EvalErrorKind<'tcx, O>
-        [ mir::interpret::EvalErrorKind ]
-    {
-        FunctionArgCountMismatch,
-        DanglingPointerDeref,
-        DoubleFree,
-        InvalidMemoryAccess,
-        InvalidFunctionPointer,
-        InvalidBool,
-        InvalidNullPointerUsage,
-        ReadPointerAsBytes,
-        ReadBytesAsPointer,
-        ReadForeignStatic,
-        InvalidPointerMath,
-        DeadLocal,
-        StackFrameLimitReached,
-        OutOfTls,
-        TlsOutOfBounds,
-        CalledClosureAsFunction,
-        VtableForArgumentlessMethod,
-        ModifiedConstantMemory,
-        ModifiedStatic,
-        AssumptionNotHeld,
-        InlineAsm,
-        ReallocateNonBasePtr,
-        DeallocateNonBasePtr,
-        HeapAllocZeroBytes,
-        Unreachable,
-        ReadFromReturnPointer,
-        UnimplementedTraitSelection,
-        TypeckError,
-        TooGeneric,
-        DerefFunctionPointer,
-        ExecuteMemory,
-        OverflowNeg,
-        RemainderByZero,
-        DivisionByZero,
-        GeneratorResumedAfterReturn,
-        GeneratorResumedAfterPanic,
-        ReferencedConstant,
-        InfiniteLoop,
-        ReadUndefBytes(offset),
-        InvalidDiscriminant(val),
-        Panic { msg, file, line, col },
-        MachineError(err),
-        FunctionAbiMismatch(a, b),
-        FunctionArgMismatch(a, b),
-        FunctionRetMismatch(a, b),
-        NoMirFor(s),
-        UnterminatedCString(ptr),
-        PointerOutOfBounds { ptr, check, allocation_size },
-        InvalidBoolOp(bop),
-        Unimplemented(s),
-        BoundsCheck { len, index },
-        Intrinsic(s),
-        InvalidChar(c),
-        AbiViolation(s),
-        AlignmentCheckFailed { required, has },
-        ValidationFailure(s),
-        TypeNotPrimitive(ty),
-        ReallocatedWrongMemoryKind(a, b),
-        DeallocatedWrongMemoryKind(a, b),
-        IncorrectAllocationInformation(a, b, c, d),
-        Layout(lay),
-        HeapAllocNonPowerOfTwoAlignment(n),
-        PathNotFound(v),
-        Overflow(op),
-    }
-);
-
-impl_stable_hash_for!(enum mir::interpret::InboundsCheck {
-    Live,
-    MaybeDead
-});
-
-impl_stable_hash_for!(enum ty::Variance {
-    Covariant,
-    Invariant,
-    Contravariant,
-    Bivariant
-});
-
-impl_stable_hash_for!(enum ty::adjustment::CustomCoerceUnsized {
-    Struct(index)
-});
-
-impl_stable_hash_for!(struct ty::Generics {
-    parent,
-    parent_count,
-    params,
-    // Reverse map to each param's `index` field, from its `def_id`.
-    param_def_id_to_index -> _, // Don't hash this
-    has_self,
-    has_late_bound_regions,
-});
-
-impl_stable_hash_for!(struct ty::GenericParamDef {
-    name,
-    def_id,
-    index,
-    pure_wrt_drop,
-    kind
-});
-
-impl_stable_hash_for!(enum ty::GenericParamDefKind {
-    Lifetime,
-    Type { has_default, object_lifetime_default, synthetic },
-    Const,
-});
-
-impl_stable_hash_for!(
-    impl<T> for enum crate::middle::resolve_lifetime::Set1<T>
-        [ crate::middle::resolve_lifetime::Set1 ]
-    {
-        Empty,
-        Many,
-        One(value),
-    }
-);
-
-impl_stable_hash_for!(enum crate::middle::resolve_lifetime::LifetimeDefOrigin {
-    ExplicitOrElided,
-    InBand,
-    Error,
-});
-
-impl_stable_hash_for!(enum crate::middle::resolve_lifetime::Region {
-    Static,
-    EarlyBound(index, decl, is_in_band),
-    LateBound(db_index, decl, is_in_band),
-    LateBoundAnon(db_index, anon_index),
-    Free(call_site_scope_data, decl)
-});
-
-impl_stable_hash_for!(enum ty::cast::CastKind {
-    CoercionCast,
-    PtrPtrCast,
-    PtrAddrCast,
-    AddrPtrCast,
-    NumericCast,
-    EnumCast,
-    PrimIntCast,
-    U8CharCast,
-    ArrayPtrCast,
-    FnPtrPtrCast,
-    FnPtrAddrCast
-});
-
-impl_stable_hash_for!(struct crate::middle::region::Scope { id, data });
-
-impl_stable_hash_for!(enum crate::middle::region::ScopeData {
-    Node,
-    CallSite,
-    Arguments,
-    Destruction,
-    Remainder(first_statement_index)
-});
-
 impl<'a> ToStableHashKey<StableHashingContext<'a>> for region::Scope {
     type KeyType = region::Scope;
 
@@ -599,129 +193,6 @@ impl<'a> ToStableHashKey<StableHashingContext<'a>> for region::Scope {
     }
 }
 
-impl_stable_hash_for!(struct ty::adjustment::CoerceUnsizedInfo {
-    custom_kind
-});
-
-impl_stable_hash_for!(struct ty::FreeRegion {
-    scope,
-    bound_region
-});
-
-impl_stable_hash_for!(enum ty::BoundRegion {
-    BrAnon(index),
-    BrNamed(def_id, name),
-    BrFresh(index),
-    BrEnv
-});
-
-impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
-for ty::TyKind<'gcx>
-{
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        use crate::ty::TyKind::*;
-
-        mem::discriminant(self).hash_stable(hcx, hasher);
-        match *self {
-            Bool  |
-            Char  |
-            Str   |
-            Error |
-            Never => {
-                // Nothing more to hash.
-            }
-            Int(int_ty) => {
-                int_ty.hash_stable(hcx, hasher);
-            }
-            Uint(uint_ty) => {
-                uint_ty.hash_stable(hcx, hasher);
-            }
-            Float(float_ty)  => {
-                float_ty.hash_stable(hcx, hasher);
-            }
-            Adt(adt_def, substs) => {
-                adt_def.hash_stable(hcx, hasher);
-                substs.hash_stable(hcx, hasher);
-            }
-            Array(inner_ty, len) => {
-                inner_ty.hash_stable(hcx, hasher);
-                len.hash_stable(hcx, hasher);
-            }
-            Slice(inner_ty) => {
-                inner_ty.hash_stable(hcx, hasher);
-            }
-            RawPtr(pointee_ty) => {
-                pointee_ty.hash_stable(hcx, hasher);
-            }
-            Ref(region, pointee_ty, mutbl) => {
-                region.hash_stable(hcx, hasher);
-                pointee_ty.hash_stable(hcx, hasher);
-                mutbl.hash_stable(hcx, hasher);
-            }
-            FnDef(def_id, substs) => {
-                def_id.hash_stable(hcx, hasher);
-                substs.hash_stable(hcx, hasher);
-            }
-            FnPtr(ref sig) => {
-                sig.hash_stable(hcx, hasher);
-            }
-            Dynamic(ref existential_predicates, region) => {
-                existential_predicates.hash_stable(hcx, hasher);
-                region.hash_stable(hcx, hasher);
-            }
-            Closure(def_id, closure_substs) => {
-                def_id.hash_stable(hcx, hasher);
-                closure_substs.hash_stable(hcx, hasher);
-            }
-            Generator(def_id, generator_substs, movability) => {
-                def_id.hash_stable(hcx, hasher);
-                generator_substs.hash_stable(hcx, hasher);
-                movability.hash_stable(hcx, hasher);
-            }
-            GeneratorWitness(types) => {
-                types.hash_stable(hcx, hasher)
-            }
-            Tuple(inner_tys) => {
-                inner_tys.hash_stable(hcx, hasher);
-            }
-            Projection(ref data) | UnnormalizedProjection(ref data) => {
-                data.hash_stable(hcx, hasher);
-            }
-            Opaque(def_id, substs) => {
-                def_id.hash_stable(hcx, hasher);
-                substs.hash_stable(hcx, hasher);
-            }
-            Param(param_ty) => {
-                param_ty.hash_stable(hcx, hasher);
-            }
-            Bound(debruijn, bound_ty) => {
-                debruijn.hash_stable(hcx, hasher);
-                bound_ty.hash_stable(hcx, hasher);
-            }
-            ty::Placeholder(placeholder_ty) => {
-                placeholder_ty.hash_stable(hcx, hasher);
-            }
-            Foreign(def_id) => {
-                def_id.hash_stable(hcx, hasher);
-            }
-            Infer(infer_ty) => {
-                infer_ty.hash_stable(hcx, hasher);
-            }
-        }
-    }
-}
-
-impl_stable_hash_for!(enum ty::InferTy {
-    TyVar(a),
-    IntVar(a),
-    FloatVar(a),
-    FreshTy(a),
-    FreshIntTy(a),
-    FreshFloatTy(a),
-});
-
 impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
 for ty::TyVid
 {
@@ -758,146 +229,6 @@ for ty::FloatVid
     }
 }
 
-impl_stable_hash_for!(struct ty::ParamConst {
-    index,
-    name
-});
-
-impl_stable_hash_for!(struct ty::ParamTy {
-    idx,
-    name
-});
-
-impl_stable_hash_for!(struct ty::TypeAndMut<'tcx> {
-    ty,
-    mutbl
-});
-
-impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
-for ty::ExistentialPredicate<'gcx>
-{
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        mem::discriminant(self).hash_stable(hcx, hasher);
-        match *self {
-            ty::ExistentialPredicate::Trait(ref trait_ref) => {
-                trait_ref.hash_stable(hcx, hasher);
-            }
-            ty::ExistentialPredicate::Projection(ref projection) => {
-                projection.hash_stable(hcx, hasher);
-            }
-            ty::ExistentialPredicate::AutoTrait(def_id) => {
-                def_id.hash_stable(hcx, hasher);
-            }
-        }
-    }
-}
-
-impl_stable_hash_for!(struct ty::ExistentialTraitRef<'tcx> {
-    def_id,
-    substs
-});
-
-impl_stable_hash_for!(struct ty::ExistentialProjection<'tcx> {
-    item_def_id,
-    substs,
-    ty
-});
-
-impl_stable_hash_for!(struct ty::Instance<'tcx> {
-    def,
-    substs
-});
-
-impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for ty::InstanceDef<'gcx> {
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        mem::discriminant(self).hash_stable(hcx, hasher);
-
-        match *self {
-            ty::InstanceDef::Item(def_id) => {
-                def_id.hash_stable(hcx, hasher);
-            }
-            ty::InstanceDef::VtableShim(def_id) => {
-                def_id.hash_stable(hcx, hasher);
-            }
-            ty::InstanceDef::Intrinsic(def_id) => {
-                def_id.hash_stable(hcx, hasher);
-            }
-            ty::InstanceDef::FnPtrShim(def_id, ty) => {
-                def_id.hash_stable(hcx, hasher);
-                ty.hash_stable(hcx, hasher);
-            }
-            ty::InstanceDef::Virtual(def_id, n) => {
-                def_id.hash_stable(hcx, hasher);
-                n.hash_stable(hcx, hasher);
-            }
-            ty::InstanceDef::ClosureOnceShim { call_once } => {
-                call_once.hash_stable(hcx, hasher);
-            }
-            ty::InstanceDef::DropGlue(def_id, ty) => {
-                def_id.hash_stable(hcx, hasher);
-                ty.hash_stable(hcx, hasher);
-            }
-            ty::InstanceDef::CloneShim(def_id, ty) => {
-                def_id.hash_stable(hcx, hasher);
-                ty.hash_stable(hcx, hasher);
-            }
-        }
-    }
-}
-
-impl_stable_hash_for!(struct ty::TraitDef {
-    // We already have the def_path_hash below, no need to hash it twice
-    def_id -> _,
-    unsafety,
-    paren_sugar,
-    has_auto_impl,
-    is_marker,
-    def_path_hash,
-});
-
-impl_stable_hash_for!(struct ty::Destructor {
-    did
-});
-
-impl_stable_hash_for!(struct ty::CrateVariancesMap {
-    variances,
-    // This is just an irrelevant helper value.
-    empty_variance -> _,
-});
-
-impl_stable_hash_for!(struct ty::CratePredicatesMap<'tcx> {
-    predicates,
-    // This is just an irrelevant helper value.
-    empty_predicate -> _,
-});
-
-impl_stable_hash_for!(struct ty::AssociatedItem {
-    def_id,
-    ident -> (ident.name),
-    kind,
-    vis,
-    defaultness,
-    container,
-    method_has_self_argument
-});
-
-impl_stable_hash_for!(enum ty::AssociatedKind {
-    Const,
-    Method,
-    Existential,
-    Type
-});
-
-impl_stable_hash_for!(enum ty::AssociatedItemContainer {
-    TraitContainer(def_id),
-    ImplContainer(def_id)
-});
-
-
 impl<'a, 'gcx, T> HashStable<StableHashingContext<'a>>
 for ty::steal::Steal<T>
     where T: HashStable<StableHashingContext<'a>>
@@ -909,24 +240,6 @@ for ty::steal::Steal<T>
     }
 }
 
-impl_stable_hash_for!(struct ty::ParamEnv<'tcx> {
-    caller_bounds,
-    reveal,
-    def_id
-});
-
-impl_stable_hash_for!(enum traits::Reveal {
-    UserFacing,
-    All
-});
-
-impl_stable_hash_for!(enum crate::middle::privacy::AccessLevel {
-    ReachableFromImplTrait,
-    Reachable,
-    Exported,
-    Public
-});
-
 impl<'a> HashStable<StableHashingContext<'a>>
 for crate::middle::privacy::AccessLevels {
     fn hash_stable<W: StableHasherResult>(&self,
@@ -941,366 +254,3 @@ for crate::middle::privacy::AccessLevels {
         });
     }
 }
-
-impl_stable_hash_for!(struct ty::CrateInherentImpls {
-    inherent_impls
-});
-
-impl_stable_hash_for!(struct crate::util::common::ErrorReported {});
-
-impl_stable_hash_for!(tuple_struct crate::middle::reachable::ReachableSet {
-    reachable_set
-});
-
-impl<'a, 'gcx, N> HashStable<StableHashingContext<'a>>
-for traits::Vtable<'gcx, N> where N: HashStable<StableHashingContext<'a>> {
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        use crate::traits::Vtable::*;
-
-        mem::discriminant(self).hash_stable(hcx, hasher);
-
-        match self {
-            &VtableImpl(ref table_impl) => table_impl.hash_stable(hcx, hasher),
-            &VtableAutoImpl(ref table_def_impl) => table_def_impl.hash_stable(hcx, hasher),
-            &VtableParam(ref table_param) => table_param.hash_stable(hcx, hasher),
-            &VtableObject(ref table_obj) => table_obj.hash_stable(hcx, hasher),
-            &VtableBuiltin(ref table_builtin) => table_builtin.hash_stable(hcx, hasher),
-            &VtableClosure(ref table_closure) => table_closure.hash_stable(hcx, hasher),
-            &VtableFnPointer(ref table_fn_pointer) => table_fn_pointer.hash_stable(hcx, hasher),
-            &VtableGenerator(ref table_generator) => table_generator.hash_stable(hcx, hasher),
-            &VtableTraitAlias(ref table_alias) => table_alias.hash_stable(hcx, hasher),
-        }
-    }
-}
-
-impl<'a, 'gcx, N> HashStable<StableHashingContext<'a>>
-for traits::VtableImplData<'gcx, N> where N: HashStable<StableHashingContext<'a>> {
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        let traits::VtableImplData {
-            impl_def_id,
-            substs,
-            ref nested,
-        } = *self;
-        impl_def_id.hash_stable(hcx, hasher);
-        substs.hash_stable(hcx, hasher);
-        nested.hash_stable(hcx, hasher);
-    }
-}
-
-impl<'a, 'gcx, N> HashStable<StableHashingContext<'a>>
-for traits::VtableAutoImplData<N> where N: HashStable<StableHashingContext<'a>> {
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        let traits::VtableAutoImplData {
-            trait_def_id,
-            ref nested,
-        } = *self;
-        trait_def_id.hash_stable(hcx, hasher);
-        nested.hash_stable(hcx, hasher);
-    }
-}
-
-impl<'a, 'gcx, N> HashStable<StableHashingContext<'a>>
-for traits::VtableObjectData<'gcx, N> where N: HashStable<StableHashingContext<'a>> {
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        let traits::VtableObjectData {
-            upcast_trait_ref,
-            vtable_base,
-            ref nested,
-        } = *self;
-        upcast_trait_ref.hash_stable(hcx, hasher);
-        vtable_base.hash_stable(hcx, hasher);
-        nested.hash_stable(hcx, hasher);
-    }
-}
-
-impl<'a, 'gcx, N> HashStable<StableHashingContext<'a>>
-for traits::VtableBuiltinData<N> where N: HashStable<StableHashingContext<'a>> {
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        let traits::VtableBuiltinData {
-            ref nested,
-        } = *self;
-        nested.hash_stable(hcx, hasher);
-    }
-}
-
-impl<'a, 'gcx, N> HashStable<StableHashingContext<'a>>
-for traits::VtableClosureData<'gcx, N> where N: HashStable<StableHashingContext<'a>> {
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        let traits::VtableClosureData {
-            closure_def_id,
-            substs,
-            ref nested,
-        } = *self;
-        closure_def_id.hash_stable(hcx, hasher);
-        substs.hash_stable(hcx, hasher);
-        nested.hash_stable(hcx, hasher);
-    }
-}
-
-impl<'a, 'gcx, N> HashStable<StableHashingContext<'a>>
-for traits::VtableFnPointerData<'gcx, N> where N: HashStable<StableHashingContext<'a>> {
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        let traits::VtableFnPointerData {
-            fn_ty,
-            ref nested,
-        } = *self;
-        fn_ty.hash_stable(hcx, hasher);
-        nested.hash_stable(hcx, hasher);
-    }
-}
-
-impl<'a, 'gcx, N> HashStable<StableHashingContext<'a>>
-for traits::VtableGeneratorData<'gcx, N> where N: HashStable<StableHashingContext<'a>> {
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        let traits::VtableGeneratorData {
-            generator_def_id,
-            substs,
-            ref nested,
-        } = *self;
-        generator_def_id.hash_stable(hcx, hasher);
-        substs.hash_stable(hcx, hasher);
-        nested.hash_stable(hcx, hasher);
-    }
-}
-
-impl<'a, 'gcx, N> HashStable<StableHashingContext<'a>>
-for traits::VtableTraitAliasData<'gcx, N> where N: HashStable<StableHashingContext<'a>> {
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        let traits::VtableTraitAliasData {
-            alias_def_id,
-            substs,
-            ref nested,
-        } = *self;
-        alias_def_id.hash_stable(hcx, hasher);
-        substs.hash_stable(hcx, hasher);
-        nested.hash_stable(hcx, hasher);
-    }
-}
-
-impl_stable_hash_for!(
-    impl<'tcx, V> for struct infer::canonical::Canonical<'tcx, V> {
-        max_universe, variables, value
-    }
-);
-
-impl_stable_hash_for!(
-    struct infer::canonical::CanonicalVarValues<'tcx> {
-        var_values
-    }
-);
-
-impl_stable_hash_for!(struct infer::canonical::CanonicalVarInfo {
-    kind
-});
-
-impl_stable_hash_for!(enum infer::canonical::CanonicalVarKind {
-    Ty(k),
-    PlaceholderTy(placeholder),
-    Region(ui),
-    PlaceholderRegion(placeholder),
-});
-
-impl_stable_hash_for!(enum infer::canonical::CanonicalTyVarKind {
-    General(ui),
-    Int,
-    Float
-});
-
-impl_stable_hash_for!(
-    impl<'tcx, R> for struct infer::canonical::QueryResponse<'tcx, R> {
-        var_values, region_constraints, certainty, value
-    }
-);
-
-impl_stable_hash_for!(enum infer::canonical::Certainty {
-    Proven, Ambiguous
-});
-
-impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for traits::WhereClause<'tcx> {
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        use crate::traits::WhereClause::*;
-
-        mem::discriminant(self).hash_stable(hcx, hasher);
-        match self {
-            Implemented(trait_ref) => trait_ref.hash_stable(hcx, hasher),
-            ProjectionEq(projection) => projection.hash_stable(hcx, hasher),
-            TypeOutlives(ty_outlives) => ty_outlives.hash_stable(hcx, hasher),
-            RegionOutlives(region_outlives) => region_outlives.hash_stable(hcx, hasher),
-        }
-    }
-}
-
-impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for traits::WellFormed<'tcx> {
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        use crate::traits::WellFormed::*;
-
-        mem::discriminant(self).hash_stable(hcx, hasher);
-        match self {
-            Trait(trait_ref) => trait_ref.hash_stable(hcx, hasher),
-            Ty(ty) => ty.hash_stable(hcx, hasher),
-        }
-    }
-}
-
-impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for traits::FromEnv<'tcx> {
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        use crate::traits::FromEnv::*;
-
-        mem::discriminant(self).hash_stable(hcx, hasher);
-        match self {
-            Trait(trait_ref) => trait_ref.hash_stable(hcx, hasher),
-            Ty(ty) => ty.hash_stable(hcx, hasher),
-        }
-    }
-}
-
-impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for traits::DomainGoal<'tcx> {
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        use crate::traits::DomainGoal::*;
-
-        mem::discriminant(self).hash_stable(hcx, hasher);
-        match self {
-            Holds(wc) => wc.hash_stable(hcx, hasher),
-            WellFormed(wf) => wf.hash_stable(hcx, hasher),
-            FromEnv(from_env) => from_env.hash_stable(hcx, hasher),
-            Normalize(projection) => projection.hash_stable(hcx, hasher),
-        }
-    }
-}
-
-impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for traits::Goal<'tcx> {
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        use crate::traits::GoalKind::*;
-
-        mem::discriminant(self).hash_stable(hcx, hasher);
-        match self {
-            Implies(hypotheses, goal) => {
-                hypotheses.hash_stable(hcx, hasher);
-                goal.hash_stable(hcx, hasher);
-            },
-            And(goal1, goal2) => {
-                goal1.hash_stable(hcx, hasher);
-                goal2.hash_stable(hcx, hasher);
-            }
-            Not(goal) => goal.hash_stable(hcx, hasher),
-            DomainGoal(domain_goal) => domain_goal.hash_stable(hcx, hasher),
-            Quantified(quantifier, goal) => {
-                quantifier.hash_stable(hcx, hasher);
-                goal.hash_stable(hcx, hasher);
-            },
-            Subtype(a, b) => {
-                a.hash_stable(hcx, hasher);
-                b.hash_stable(hcx, hasher);
-            }
-            CannotProve => { },
-        }
-    }
-}
-
-impl_stable_hash_for!(
-    struct traits::ProgramClause<'tcx> {
-        goal, hypotheses, category
-    }
-);
-
-impl_stable_hash_for!(enum traits::ProgramClauseCategory {
-    ImpliedBound,
-    WellFormed,
-    Other,
-});
-
-impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for traits::Clause<'tcx> {
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        use crate::traits::Clause::*;
-
-        mem::discriminant(self).hash_stable(hcx, hasher);
-        match self {
-            Implies(clause) => clause.hash_stable(hcx, hasher),
-            ForAll(clause) => clause.hash_stable(hcx, hasher),
-        }
-    }
-}
-
-impl_stable_hash_for!(enum traits::QuantifierKind {
-    Universal,
-    Existential
-});
-
-impl_stable_hash_for!(struct ty::subst::UserSubsts<'tcx> { substs, user_self_ty });
-
-impl_stable_hash_for!(struct ty::subst::UserSelfTy<'tcx> { impl_def_id, self_ty });
-
-impl_stable_hash_for!(
-    struct traits::Environment<'tcx> {
-        clauses,
-    }
-);
-
-impl_stable_hash_for!(
-    impl<'tcx, G> for struct traits::InEnvironment<'tcx, G> {
-        environment,
-        goal,
-    }
-);
-
-impl_stable_hash_for!(
-    struct ty::CanonicalUserTypeAnnotation<'tcx> {
-        user_ty, span, inferred_ty
-    }
-);
-
-impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for ty::UserType<'gcx> {
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        mem::discriminant(self).hash_stable(hcx, hasher);
-        match *self {
-            ty::UserType::Ty(ref ty) => {
-                ty.hash_stable(hcx, hasher);
-            }
-            ty::UserType::TypeOf(ref def_id, ref substs) => {
-                def_id.hash_stable(hcx, hasher);
-                substs.hash_stable(hcx, hasher);
-            }
-        }
-    }
-}
-
-impl<'a> HashStable<StableHashingContext<'a>> for ty::UserTypeAnnotationIndex {
-    #[inline]
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        self.index().hash_stable(hcx, hasher);
-    }
-}
diff --git a/src/librustc/ich/mod.rs b/src/librustc/ich/mod.rs
index a3a4c541780..b407b75e68c 100644
--- a/src/librustc/ich/mod.rs
+++ b/src/librustc/ich/mod.rs
@@ -7,9 +7,7 @@ pub use self::hcx::{StableHashingContextProvider, StableHashingContext, NodeIdHa
 mod caching_source_map_view;
 mod hcx;
 
-mod impls_cstore;
 mod impls_hir;
-mod impls_mir;
 mod impls_misc;
 mod impls_ty;
 mod impls_syntax;
diff --git a/src/librustc/infer/canonical/mod.rs b/src/librustc/infer/canonical/mod.rs
index 0d067d1de85..95fdd6f01e2 100644
--- a/src/librustc/infer/canonical/mod.rs
+++ b/src/librustc/infer/canonical/mod.rs
@@ -24,6 +24,7 @@
 use crate::infer::{InferCtxt, RegionVariableOrigin, TypeVariableOrigin};
 use rustc_data_structures::indexed_vec::IndexVec;
 use rustc_data_structures::sync::Lrc;
+use rustc_macros::HashStable;
 use serialize::UseSpecializedDecodable;
 use smallvec::SmallVec;
 use std::ops::Index;
@@ -41,7 +42,7 @@ mod substitute;
 /// 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(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable, HashStable)]
 pub struct Canonical<'gcx, V> {
     pub max_universe: ty::UniverseIndex,
     pub variables: CanonicalVarInfos<'gcx>,
@@ -61,7 +62,7 @@ impl<'gcx> UseSpecializedDecodable for CanonicalVarInfos<'gcx> {}
 /// 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(Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable, HashStable)]
 pub struct CanonicalVarValues<'tcx> {
     pub var_values: IndexVec<BoundVar, Kind<'tcx>>,
 }
@@ -99,7 +100,7 @@ impl Default for OriginalQueryValues<'tcx> {
 /// 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)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable, HashStable)]
 pub struct CanonicalVarInfo {
     pub kind: CanonicalVarKind,
 }
@@ -122,7 +123,7 @@ impl CanonicalVarInfo {
 /// 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)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable, HashStable)]
 pub enum CanonicalVarKind {
     /// Some kind of type inference variable.
     Ty(CanonicalTyVarKind),
@@ -159,7 +160,7 @@ impl CanonicalVarKind {
 /// 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)]
+#[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),
@@ -174,7 +175,7 @@ pub enum CanonicalTyVarKind {
 /// 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)]
+#[derive(Clone, Debug, HashStable)]
 pub struct QueryResponse<'tcx, R> {
     pub var_values: CanonicalVarValues<'tcx>,
     pub region_constraints: Vec<QueryRegionConstraint<'tcx>>,
@@ -189,7 +190,7 @@ pub type CanonicalizedQueryResponse<'gcx, T> =
 
 /// Indicates whether or not we were able to prove the query to be
 /// true.
-#[derive(Copy, Clone, Debug)]
+#[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.
diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs
index 6e9552a1e92..e4890977c9b 100644
--- a/src/librustc/middle/cstore.rs
+++ b/src/librustc/middle/cstore.rs
@@ -17,6 +17,7 @@ use syntax::symbol::Symbol;
 use syntax_pos::Span;
 use rustc_target::spec::Target;
 use rustc_data_structures::sync::{self, MetadataRef, Lrc};
+use rustc_macros::HashStable;
 
 pub use self::NativeLibraryKind::*;
 
@@ -24,14 +25,15 @@ pub use self::NativeLibraryKind::*;
 
 /// Where a crate came from on the local filesystem. One of these three options
 /// must be non-None.
-#[derive(PartialEq, Clone, Debug)]
+#[derive(PartialEq, Clone, Debug, HashStable)]
 pub struct CrateSource {
     pub dylib: Option<(PathBuf, PathKind)>,
     pub rlib: Option<(PathBuf, PathKind)>,
     pub rmeta: Option<(PathBuf, PathKind)>,
 }
 
-#[derive(RustcEncodable, RustcDecodable, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Debug)]
+#[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.
@@ -79,13 +81,14 @@ impl LibSource {
     }
 }
 
-#[derive(Copy, Debug, PartialEq, Clone, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Debug, PartialEq, Clone, RustcEncodable, RustcDecodable, HashStable)]
 pub enum LinkagePreference {
     RequireDynamic,
     RequireStatic,
 }
 
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash,
+         RustcEncodable, RustcDecodable, HashStable)]
 pub enum NativeLibraryKind {
     /// native static library (.a archive)
     NativeStatic,
@@ -97,7 +100,7 @@ pub enum NativeLibraryKind {
     NativeUnknown,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable)]
+#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
 pub struct NativeLibrary {
     pub kind: NativeLibraryKind,
     pub name: Option<Symbol>,
@@ -106,13 +109,13 @@ pub struct NativeLibrary {
     pub wasm_import_module: Option<Symbol>,
 }
 
-#[derive(Clone, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Hash, RustcEncodable, RustcDecodable, HashStable)]
 pub struct ForeignModule {
     pub foreign_items: Vec<DefId>,
     pub def_id: DefId,
 }
 
-#[derive(Copy, Clone, Debug)]
+#[derive(Copy, Clone, Debug, HashStable)]
 pub struct ExternCrate {
     pub src: ExternCrateSource,
 
@@ -129,7 +132,7 @@ pub struct ExternCrate {
     pub direct: bool,
 }
 
-#[derive(Copy, Clone, Debug)]
+#[derive(Copy, Clone, Debug, HashStable)]
 pub enum ExternCrateSource {
     /// Crate is loaded by `extern crate`.
     Extern(
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index 7626310ea4e..5d809f14071 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -20,6 +20,7 @@ use crate::util::nodemap::FxHashMap;
 use syntax::ast;
 use syntax::symbol::Symbol;
 use syntax_pos::Span;
+use rustc_macros::HashStable;
 use crate::hir::itemlikevisit::ItemLikeVisitor;
 use crate::hir;
 
@@ -45,6 +46,7 @@ impl LangItem {
     }
 }
 
+#[derive(HashStable)]
 pub struct LanguageItems {
     pub items: Vec<Option<DefId>>,
     pub missing: Vec<LangItem>,
diff --git a/src/librustc/middle/lib_features.rs b/src/librustc/middle/lib_features.rs
index 331343e052d..9d15b0543cb 100644
--- a/src/librustc/middle/lib_features.rs
+++ b/src/librustc/middle/lib_features.rs
@@ -10,8 +10,10 @@ use syntax::symbol::Symbol;
 use syntax::ast::{Attribute, MetaItem, MetaItemKind};
 use syntax_pos::Span;
 use rustc_data_structures::fx::{FxHashSet, FxHashMap};
+use rustc_macros::HashStable;
 use errors::DiagnosticId;
 
+#[derive(HashStable)]
 pub struct LibFeatures {
     // A map from feature to stabilisation version.
     pub stable: FxHashMap<Symbol, Symbol>,
diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs
index 1655d8356a5..6ba55f882f8 100644
--- a/src/librustc/middle/privacy.rs
+++ b/src/librustc/middle/privacy.rs
@@ -7,9 +7,10 @@ use crate::util::nodemap::{DefIdSet, FxHashMap};
 use std::hash::Hash;
 use std::fmt;
 use syntax::ast::NodeId;
+use rustc_macros::HashStable;
 
 // Accessibility levels, sorted in ascending order
-#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
+#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, HashStable)]
 pub enum AccessLevel {
     /// Superset of `AccessLevel::Reachable` used to mark impl Trait items.
     ReachableFromImplTrait,
diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs
index 8ccf52b4efb..72f6d22b696 100644
--- a/src/librustc/middle/reachable.rs
+++ b/src/librustc/middle/reachable.rs
@@ -17,6 +17,7 @@ use crate::session::config;
 use crate::util::nodemap::{HirIdSet, FxHashSet};
 
 use rustc_target::spec::abi::Abi;
+use rustc_macros::HashStable;
 use crate::hir;
 use crate::hir::def_id::LOCAL_CRATE;
 use crate::hir::intravisit::{Visitor, NestedVisitorMap};
@@ -388,7 +389,7 @@ impl<'a, 'tcx: 'a> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a,
 
 // We introduce a new-type here, so we can have a specialized HashStable
 // implementation for it.
-#[derive(Clone)]
+#[derive(Clone, HashStable)]
 pub struct ReachableSet(pub Lrc<HirIdSet>);
 
 fn reachable_set<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum) -> ReachableSet {
diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs
index 93030c98f35..42e253273ab 100644
--- a/src/librustc/middle/region.rs
+++ b/src/librustc/middle/region.rs
@@ -13,6 +13,7 @@ use crate::ty;
 use std::mem;
 use std::fmt;
 use rustc_data_structures::sync::Lrc;
+use rustc_macros::HashStable;
 use syntax::source_map;
 use syntax::ast;
 use syntax_pos::{Span, DUMMY_SP};
@@ -90,7 +91,8 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
 // 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)]
+#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Copy,
+         RustcEncodable, RustcDecodable, HashStable)]
 pub struct Scope {
     pub id: hir::ItemLocalId,
     pub data: ScopeData,
@@ -113,7 +115,8 @@ impl fmt::Debug for Scope {
     }
 }
 
-#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Debug, Copy, RustcEncodable, RustcDecodable)]
+#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Debug, Copy,
+         RustcEncodable, RustcDecodable, HashStable)]
 pub enum ScopeData {
     Node,
 
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index f862b690f88..96f0beafa00 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -16,6 +16,7 @@ use crate::session::Session;
 use crate::util::nodemap::{DefIdMap, FxHashMap, FxHashSet, HirIdMap, HirIdSet};
 use errors::{Applicability, DiagnosticBuilder};
 use rustc_data_structures::sync::Lrc;
+use rustc_macros::HashStable;
 use std::borrow::Cow;
 use std::cell::Cell;
 use std::mem::replace;
@@ -31,7 +32,7 @@ use crate::hir::{self, GenericParamKind, LifetimeParamKind};
 /// 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)]
+#[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,
@@ -62,7 +63,7 @@ pub enum LifetimeUseSet<'tcx> {
     Many,
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum Region {
     Static,
     EarlyBound(
@@ -161,7 +162,7 @@ impl Region {
 /// 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)]
+#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum Set1<T> {
     Empty,
     One(T),
diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs
index e96392edd64..d4ee60eee63 100644
--- a/src/librustc/mir/interpret/allocation.rs
+++ b/src/librustc/mir/interpret/allocation.rs
@@ -11,11 +11,12 @@ use std::iter;
 use crate::mir;
 use std::ops::{Deref, DerefMut};
 use rustc_data_structures::sorted_map::SortedMap;
+use rustc_macros::HashStable;
 use rustc_target::abi::HasDataLayout;
 
 /// Used by `check_bounds` to indicate whether the pointer needs to be just inbounds
 /// or also inbounds of a *live* allocation.
-#[derive(Debug, Copy, Clone, RustcEncodable, RustcDecodable)]
+#[derive(Debug, Copy, Clone, RustcEncodable, RustcDecodable, HashStable)]
 pub enum InboundsCheck {
     Live,
     MaybeDead,
diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs
index c4e1860bd83..819c65e2503 100644
--- a/src/librustc/mir/interpret/error.rs
+++ b/src/librustc/mir/interpret/error.rs
@@ -6,6 +6,7 @@ use crate::mir;
 use crate::ty::{self, Ty, layout};
 use crate::ty::layout::{Size, Align, LayoutError};
 use rustc_target::spec::abi::Abi;
+use rustc_macros::HashStable;
 
 use super::{RawConst, Pointer, InboundsCheck, ScalarMaybeUndef};
 
@@ -17,7 +18,7 @@ use errors::DiagnosticBuilder;
 use syntax_pos::{Pos, Span};
 use syntax::symbol::Symbol;
 
-#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable)]
 pub enum ErrorHandled {
     /// Already reported a lint or an error for this evaluation.
     Reported,
@@ -46,7 +47,7 @@ pub struct ConstEvalErr<'tcx> {
     pub stacktrace: Vec<FrameInfo<'tcx>>,
 }
 
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
 pub struct FrameInfo<'tcx> {
     pub call_site: Span, // this span is in the caller!
     pub instance: ty::Instance<'tcx>,
@@ -209,7 +210,7 @@ impl<'tcx> From<EvalErrorKind<'tcx, u64>> for EvalError<'tcx> {
 
 pub type AssertMessage<'tcx> = EvalErrorKind<'tcx, mir::Operand<'tcx>>;
 
-#[derive(Clone, RustcEncodable, RustcDecodable)]
+#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
 pub enum EvalErrorKind<'tcx, O> {
     /// This variant is used by machines to signal their own errors that do not
     /// match an existing variant.
diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs
index 0c43fe4a79f..9fb02315602 100644
--- a/src/librustc/mir/interpret/mod.rs
+++ b/src/librustc/mir/interpret/mod.rs
@@ -34,13 +34,14 @@ use crate::rustc_serialize::{Encoder, Decodable, Encodable};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync::{Lock as Mutex, HashMapExt};
 use rustc_data_structures::tiny_list::TinyList;
+use rustc_macros::HashStable;
 use byteorder::{WriteBytesExt, ReadBytesExt, LittleEndian, BigEndian};
 use crate::ty::codec::TyDecoder;
 use std::sync::atomic::{AtomicU32, Ordering};
 use std::num::NonZeroU32;
 
 /// Uniquely identifies a specific constant or static.
-#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, RustcEncodable, RustcDecodable, HashStable)]
 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.
@@ -258,7 +259,7 @@ impl fmt::Display for AllocId {
     }
 }
 
-#[derive(Debug, Clone, Eq, PartialEq, Hash, RustcDecodable, RustcEncodable)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash, RustcDecodable, RustcEncodable, HashStable)]
 pub enum AllocKind<'tcx> {
     /// The alloc ID is used as a function pointer
     Function(Instance<'tcx>),
diff --git a/src/librustc/mir/interpret/pointer.rs b/src/librustc/mir/interpret/pointer.rs
index 551e7b2fd41..9216cb494ce 100644
--- a/src/librustc/mir/interpret/pointer.rs
+++ b/src/librustc/mir/interpret/pointer.rs
@@ -1,5 +1,6 @@
 use crate::mir;
 use crate::ty::layout::{self, HasDataLayout, Size};
+use rustc_macros::HashStable;
 
 use super::{
     AllocId, EvalResult, InboundsCheck,
@@ -69,7 +70,8 @@ impl<T: layout::HasDataLayout> PointerArithmetic for T {}
 ///
 /// Pointer is also generic over the `Tag` associated with each pointer,
 /// which is used to do provenance tracking during execution.
-#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, RustcEncodable, RustcDecodable, Hash)]
+#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd,
+         RustcEncodable, RustcDecodable, Hash, HashStable)]
 pub struct Pointer<Tag=(),Id=AllocId> {
     pub alloc_id: Id,
     pub offset: Size,
diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs
index dbbeda3e578..9620ac95d86 100644
--- a/src/librustc/mir/interpret/value.rs
+++ b/src/librustc/mir/interpret/value.rs
@@ -1,11 +1,12 @@
 use std::fmt;
+use rustc_macros::HashStable;
 
 use crate::ty::{Ty, InferConst, ParamConst, layout::{HasDataLayout, Size}};
 
 use super::{EvalResult, Pointer, PointerArithmetic, Allocation, AllocId, sign_extend, truncate};
 
 /// Represents the result of a raw const operation, pre-validation.
-#[derive(Copy, Clone, Debug, Eq, PartialEq, RustcEncodable, RustcDecodable, Hash)]
+#[derive(Copy, Clone, Debug, Eq, PartialEq, RustcEncodable, RustcDecodable, Hash, 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`).
@@ -15,7 +16,8 @@ pub struct RawConst<'tcx> {
 
 /// Represents a constant value in Rust. `Scalar` and `ScalarPair` are optimizations that
 /// match the `LocalState` optimizations for easy conversions between `Value` and `ConstValue`.
-#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash)]
+#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord,
+         RustcEncodable, RustcDecodable, Hash, HashStable)]
 pub enum ConstValue<'tcx> {
     /// A const generic parameter.
     Param(ParamConst),
@@ -80,7 +82,8 @@ impl<'tcx> ConstValue<'tcx> {
 /// `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, Debug, Eq, PartialEq, Ord, PartialOrd, RustcEncodable, RustcDecodable, Hash)]
+#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd,
+         RustcEncodable, RustcDecodable, Hash, HashStable)]
 pub enum Scalar<Tag=(), Id=AllocId> {
     /// The raw bytes of a simple value.
     Bits {
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index 7a91059b6bf..3a4422a6239 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -15,6 +15,7 @@ use rustc_data_structures::graph::{self, GraphPredecessors, GraphSuccessors};
 use rustc_data_structures::indexed_vec::{Idx, IndexVec};
 use rustc_data_structures::sync::Lrc;
 use rustc_data_structures::sync::MappedReadGuard;
+use rustc_macros::HashStable;
 use crate::rustc_serialize::{self as serialize};
 use smallvec::SmallVec;
 use std::borrow::Cow;
@@ -405,7 +406,7 @@ impl<'tcx> Mir<'tcx> {
     }
 }
 
-#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
 pub enum Safety {
     Safe,
     /// Unsafe because of a PushUnsafeBlock
@@ -451,7 +452,7 @@ impl<'tcx> IndexMut<BasicBlock> for Mir<'tcx> {
     }
 }
 
-#[derive(Copy, Clone, Debug)]
+#[derive(Copy, Clone, Debug, HashStable)]
 pub enum ClearCrossCrate<T> {
     Clear,
     Set(T),
@@ -472,7 +473,7 @@ impl<T: serialize::Decodable> serialize::UseSpecializedDecodable for ClearCrossC
 /// 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.
-#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, HashStable)]
 pub struct SourceInfo {
     /// Source span for the AST pertaining to this MIR entity.
     pub span: Span,
@@ -485,7 +486,7 @@ pub struct SourceInfo {
 ///////////////////////////////////////////////////////////////////////////
 // Mutability and borrow kinds
 
-#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
 pub enum Mutability {
     Mut,
     Not,
@@ -500,7 +501,8 @@ impl From<Mutability> for hir::Mutability {
     }
 }
 
-#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd,
+         Ord, RustcEncodable, RustcDecodable, HashStable)]
 pub enum BorrowKind {
     /// Data must be immutable and is aliasable.
     Shared,
@@ -585,13 +587,14 @@ impl BorrowKind {
 
 newtype_index! {
     pub struct Local {
+        derive [HashStable]
         DEBUG_FORMAT = "_{}",
         const RETURN_PLACE = 0,
     }
 }
 
 /// Classifies locals into categories. See `Mir::local_kind`.
-#[derive(PartialEq, Eq, Debug)]
+#[derive(PartialEq, Eq, Debug, HashStable)]
 pub enum LocalKind {
     /// User-declared variable binding
     Var,
@@ -721,7 +724,7 @@ impl_stable_hash_for!(struct BlockTailInfo { tail_result_is_ignored });
 ///
 /// 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)]
+#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
 pub struct LocalDecl<'tcx> {
     /// `let mut x` vs `let x`.
     ///
@@ -977,7 +980,7 @@ impl<'tcx> LocalDecl<'tcx> {
 }
 
 /// A closure capture, with its name and mode.
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
 pub struct UpvarDecl {
     pub debug_name: Name,
 
@@ -995,6 +998,7 @@ pub struct UpvarDecl {
 
 newtype_index! {
     pub struct BasicBlock {
+        derive [HashStable]
         DEBUG_FORMAT = "bb{}",
         const START_BLOCK = 0,
     }
@@ -1012,7 +1016,7 @@ impl BasicBlock {
 ///////////////////////////////////////////////////////////////////////////
 // BasicBlockData and Terminator
 
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
 pub struct BasicBlockData<'tcx> {
     /// List of statements in this block.
     pub statements: Vec<Statement<'tcx>>,
@@ -1034,13 +1038,13 @@ pub struct BasicBlockData<'tcx> {
     pub is_cleanup: bool,
 }
 
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
 pub struct Terminator<'tcx> {
     pub source_info: SourceInfo,
     pub kind: TerminatorKind<'tcx>,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable)]
+#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
 pub enum TerminatorKind<'tcx> {
     /// block should have one successor in the graph; we jump there
     Goto { target: BasicBlock },
@@ -1723,7 +1727,7 @@ impl<'tcx> TerminatorKind<'tcx> {
 ///////////////////////////////////////////////////////////////////////////
 // Statements
 
-#[derive(Clone, RustcEncodable, RustcDecodable)]
+#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
 pub struct Statement<'tcx> {
     pub source_info: SourceInfo,
     pub kind: StatementKind<'tcx>,
@@ -1749,7 +1753,7 @@ impl<'tcx> Statement<'tcx> {
     }
 }
 
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
 pub enum StatementKind<'tcx> {
     /// Write the RHS Rvalue to the LHS Place.
     Assign(Place<'tcx>, Box<Rvalue<'tcx>>),
@@ -1808,7 +1812,7 @@ pub enum StatementKind<'tcx> {
 }
 
 /// `RetagKind` describes what kind of retag is to be performed.
-#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, PartialEq, Eq)]
+#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, PartialEq, Eq, HashStable)]
 pub enum RetagKind {
     /// The initial retag when entering a function
     FnEntry,
@@ -1821,7 +1825,7 @@ pub enum RetagKind {
 }
 
 /// The `FakeReadCause` describes the type of pattern why a `FakeRead` statement exists.
-#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum FakeReadCause {
     /// Inject a fake read of the borrowed input at the end of each guards
     /// code.
@@ -1894,7 +1898,7 @@ impl<'tcx> Debug for Statement<'tcx> {
 
 /// A path to a value; something that can be evaluated without
 /// changing or disturbing program state.
-#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, HashStable)]
 pub enum Place<'tcx> {
     Base(PlaceBase<'tcx>),
 
@@ -1902,7 +1906,7 @@ pub enum Place<'tcx> {
     Projection(Box<PlaceProjection<'tcx>>),
 }
 
-#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, HashStable)]
 pub enum PlaceBase<'tcx> {
     /// local variable
     Local(Local),
@@ -1931,13 +1935,15 @@ impl_stable_hash_for!(struct Static<'tcx> {
 /// or `*B` or `B[index]`. Note that it is parameterized because it is
 /// shared between `Constant` and `Place`. See the aliases
 /// `PlaceProjection` etc below.
-#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord,
+         Hash, RustcEncodable, RustcDecodable, HashStable)]
 pub struct Projection<'tcx, B, V, T> {
     pub base: B,
     pub elem: ProjectionElem<'tcx, V, T>,
 }
 
-#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord,
+         Hash, RustcEncodable, RustcDecodable, HashStable)]
 pub enum ProjectionElem<'tcx, V, T> {
     Deref,
     Field(Field, T),
@@ -1994,6 +2000,7 @@ pub type ProjectionKind<'tcx> = ProjectionElem<'tcx, (), ()>;
 
 newtype_index! {
     pub struct Field {
+        derive [HashStable]
         DEBUG_FORMAT = "field[{}]"
     }
 }
@@ -2102,18 +2109,19 @@ impl<'tcx> Debug for Place<'tcx> {
 
 newtype_index! {
     pub struct SourceScope {
+        derive [HashStable]
         DEBUG_FORMAT = "scope[{}]",
         const OUTERMOST_SOURCE_SCOPE = 0,
     }
 }
 
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
 pub struct SourceScopeData {
     pub span: Span,
     pub parent_scope: Option<SourceScope>,
 }
 
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
 pub struct SourceScopeLocalData {
     /// A HirId with lint levels equivalent to this scope's lint levels.
     pub lint_root: hir::HirId,
@@ -2126,7 +2134,7 @@ pub struct SourceScopeLocalData {
 
 /// 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)]
+#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, HashStable)]
 pub enum Operand<'tcx> {
     /// Copy: The value must be available for use afterwards.
     ///
@@ -2188,7 +2196,7 @@ impl<'tcx> Operand<'tcx> {
 ///////////////////////////////////////////////////////////////////////////
 /// Rvalues
 
-#[derive(Clone, RustcEncodable, RustcDecodable)]
+#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
 pub enum Rvalue<'tcx> {
     /// x (either a move or copy, depending on type of x)
     Use(Operand<'tcx>),
@@ -2224,7 +2232,7 @@ pub enum Rvalue<'tcx> {
     Aggregate(Box<AggregateKind<'tcx>>, Vec<Operand<'tcx>>),
 }
 
-#[derive(Clone, Copy, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Copy, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
 pub enum CastKind {
     Misc,
 
@@ -2248,7 +2256,7 @@ pub enum CastKind {
     Unsize,
 }
 
-#[derive(Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
 pub enum AggregateKind<'tcx> {
     /// The type is of the element
     Array(Ty<'tcx>),
@@ -2271,7 +2279,7 @@ pub enum AggregateKind<'tcx> {
     Generator(DefId, GeneratorSubsts<'tcx>, hir::GeneratorMovability),
 }
 
-#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
 pub enum BinOp {
     /// The `+` operator (addition)
     Add,
@@ -2319,7 +2327,7 @@ impl BinOp {
     }
 }
 
-#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
 pub enum NullOp {
     /// Returns the size of a value of that type
     SizeOf,
@@ -2327,7 +2335,7 @@ pub enum NullOp {
     Box,
 }
 
-#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
 pub enum UnOp {
     /// The `!` operator for logical inversion
     Not,
@@ -2468,7 +2476,7 @@ impl<'tcx> Debug for Rvalue<'tcx> {
 /// this does not necessarily mean that they are "==" in Rust -- in
 /// particular one must be wary of `NaN`!
 
-#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
 pub struct Constant<'tcx> {
     pub span: Span,
     pub ty: Ty<'tcx>,
@@ -2515,7 +2523,7 @@ pub struct Constant<'tcx> {
 /// 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, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
 pub struct UserTypeProjections<'tcx> {
     pub(crate) contents: Vec<(UserTypeProjection<'tcx>, Span)>,
 }
@@ -2601,7 +2609,7 @@ impl<'tcx> UserTypeProjections<'tcx> {
 /// * `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, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
 pub struct UserTypeProjection<'tcx> {
     pub base: UserTypeAnnotationIndex,
     pub projs: Vec<ProjectionElem<'tcx, (), ()>>,
@@ -2671,6 +2679,7 @@ impl<'tcx> TypeFoldable<'tcx> for UserTypeProjection<'tcx> {
 
 newtype_index! {
     pub struct Promoted {
+        derive [HashStable]
         DEBUG_FORMAT = "promoted[{}]"
     }
 }
@@ -2793,7 +2802,7 @@ impl<'a, 'b> graph::GraphSuccessors<'b> for Mir<'a> {
     type Iter = iter::Cloned<Successors<'b>>;
 }
 
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Ord, PartialOrd, HashStable)]
 pub struct Location {
     /// the location is within this block
     pub block: BasicBlock,
@@ -2865,7 +2874,7 @@ impl Location {
     }
 }
 
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
 pub enum UnsafetyViolationKind {
     General,
     /// Permitted in const fn and regular fns.
@@ -2874,7 +2883,7 @@ pub enum UnsafetyViolationKind {
     BorrowPacked(hir::HirId),
 }
 
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
 pub struct UnsafetyViolation {
     pub source_info: SourceInfo,
     pub description: InternedString,
@@ -2882,7 +2891,7 @@ pub struct UnsafetyViolation {
     pub kind: UnsafetyViolationKind,
 }
 
-#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
 pub struct UnsafetyCheckResult {
     /// Violations that are propagated *upwards* from this function
     pub violations: Lrc<[UnsafetyViolation]>,
@@ -2892,12 +2901,12 @@ pub struct UnsafetyCheckResult {
 }
 
 /// The layout of generator state
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
 pub struct GeneratorLayout<'tcx> {
     pub fields: Vec<LocalDecl<'tcx>>,
 }
 
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
 pub struct BorrowCheckResult<'gcx> {
     pub closure_requirements: Option<ClosureRegionRequirements<'gcx>>,
     pub used_mut_upvars: SmallVec<[Field; 8]>,
@@ -2953,7 +2962,7 @@ pub struct BorrowCheckResult<'gcx> {
 /// 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)]
+#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
 pub struct ClosureRegionRequirements<'gcx> {
     /// The number of external regions defined on the closure. In our
     /// example above, it would be 3 -- one for `'static`, then `'1`
@@ -2969,7 +2978,7 @@ pub struct ClosureRegionRequirements<'gcx> {
 
 /// Indicates an outlives constraint between a type or between two
 /// free-regions declared on the closure.
-#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
 pub struct ClosureOutlivesRequirement<'tcx> {
     // This region or type ...
     pub subject: ClosureOutlivesSubject<'tcx>,
@@ -2989,7 +2998,8 @@ pub struct ClosureOutlivesRequirement<'tcx> {
 /// 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, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord,
+         Hash, RustcEncodable, RustcDecodable, HashStable)]
 pub enum ConstraintCategory {
     Return,
     Yield,
@@ -3026,7 +3036,7 @@ pub enum ConstraintCategory {
 
 /// The subject of a ClosureOutlivesRequirement -- that is, the thing
 /// that must outlive some region.
-#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
+#[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
diff --git a/src/librustc/session/search_paths.rs b/src/librustc/session/search_paths.rs
index a950258cefd..1b6a1739b02 100644
--- a/src/librustc/session/search_paths.rs
+++ b/src/librustc/session/search_paths.rs
@@ -1,4 +1,5 @@
 use std::path::{Path, PathBuf};
+use rustc_macros::HashStable;
 use crate::session::{early_error, config};
 use crate::session::filesearch::make_target_lib_path;
 
@@ -9,7 +10,7 @@ pub struct SearchPath {
     pub files: Vec<PathBuf>,
 }
 
-#[derive(Eq, PartialEq, Clone, Copy, Debug, PartialOrd, Ord, Hash)]
+#[derive(Eq, PartialEq, Clone, Copy, Debug, PartialOrd, Ord, Hash, HashStable)]
 pub enum PathKind {
     Native,
     Crate,
diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs
index 32bb7f18693..df127b934b0 100644
--- a/src/librustc/traits/mod.rs
+++ b/src/librustc/traits/mod.rs
@@ -27,6 +27,7 @@ use crate::infer::outlives::env::OutlivesEnvironment;
 use crate::middle::region;
 use crate::mir::interpret::ErrorHandled;
 use rustc_data_structures::sync::Lrc;
+use rustc_macros::HashStable;
 use syntax::ast;
 use syntax_pos::{Span, DUMMY_SP};
 use crate::ty::subst::{InternalSubsts, SubstsRef};
@@ -294,7 +295,7 @@ pub type TraitObligations<'tcx> = Vec<TraitObligation<'tcx>>;
 /// 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)]
+#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable)]
 pub enum WhereClause<'tcx> {
     Implemented(ty::TraitPredicate<'tcx>),
     ProjectionEq(ty::ProjectionPredicate<'tcx>),
@@ -302,19 +303,19 @@ pub enum WhereClause<'tcx> {
     TypeOutlives(ty::TypeOutlivesPredicate<'tcx>),
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
+#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable)]
 pub enum WellFormed<'tcx> {
     Trait(ty::TraitPredicate<'tcx>),
     Ty(Ty<'tcx>),
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
+#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable)]
 pub enum FromEnv<'tcx> {
     Trait(ty::TraitPredicate<'tcx>),
     Ty(Ty<'tcx>),
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
+#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable)]
 pub enum DomainGoal<'tcx> {
     Holds(WhereClause<'tcx>),
     WellFormed(WellFormed<'tcx>),
@@ -324,13 +325,13 @@ pub enum DomainGoal<'tcx> {
 
 pub type PolyDomainGoal<'tcx> = ty::Binder<DomainGoal<'tcx>>;
 
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable)]
 pub enum QuantifierKind {
     Universal,
     Existential,
 }
 
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable)]
 pub enum GoalKind<'tcx> {
     Implies(Clauses<'tcx>, Goal<'tcx>),
     And(Goal<'tcx>, Goal<'tcx>),
@@ -376,7 +377,7 @@ impl<'tcx> GoalKind<'tcx> {
 
 /// 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)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable)]
 pub enum Clause<'tcx> {
     Implies(ProgramClause<'tcx>),
     ForAll(ty::Binder<ProgramClause<'tcx>>),
@@ -400,7 +401,7 @@ pub type Clauses<'tcx> = &'tcx List<Clause<'tcx>>;
 /// 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)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable)]
 pub struct ProgramClause<'tcx> {
     /// This goal will be considered true ...
     pub goal: DomainGoal<'tcx>,
@@ -412,7 +413,7 @@ pub struct ProgramClause<'tcx> {
     pub category: ProgramClauseCategory,
 }
 
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable)]
 pub enum ProgramClauseCategory {
     ImpliedBound,
     WellFormed,
@@ -420,7 +421,7 @@ pub enum ProgramClauseCategory {
 }
 
 /// A set of clauses that we assume to be true.
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable)]
 pub struct Environment<'tcx> {
     pub clauses: Clauses<'tcx>,
 }
@@ -435,7 +436,7 @@ impl Environment<'tcx> {
 }
 
 /// Something (usually a goal), along with an environment.
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable)]
 pub struct InEnvironment<'tcx, G> {
     pub environment: Environment<'tcx>,
     pub goal: G,
@@ -514,7 +515,7 @@ pub type SelectionResult<'tcx, T> = Result<Option<T>, SelectionError<'tcx>>;
 /// ### The type parameter `N`
 ///
 /// See explanation on `VtableImplData`.
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable)]
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
 pub enum Vtable<'tcx, N> {
     /// Vtable identifying a particular impl.
     VtableImpl(VtableImplData<'tcx, N>),
@@ -562,14 +563,14 @@ pub enum Vtable<'tcx, N> {
 /// 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)]
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
 pub struct VtableImplData<'tcx, N> {
     pub impl_def_id: DefId,
     pub substs: SubstsRef<'tcx>,
     pub nested: Vec<N>
 }
 
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable)]
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
 pub struct VtableGeneratorData<'tcx, N> {
     pub generator_def_id: DefId,
     pub substs: ty::GeneratorSubsts<'tcx>,
@@ -578,7 +579,7 @@ pub struct VtableGeneratorData<'tcx, N> {
     pub nested: Vec<N>
 }
 
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable)]
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
 pub struct VtableClosureData<'tcx, N> {
     pub closure_def_id: DefId,
     pub substs: ty::ClosureSubsts<'tcx>,
@@ -587,20 +588,20 @@ pub struct VtableClosureData<'tcx, N> {
     pub nested: Vec<N>
 }
 
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable)]
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
 pub struct VtableAutoImplData<N> {
     pub trait_def_id: DefId,
     pub nested: Vec<N>
 }
 
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable)]
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
 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)]
+#[derive(PartialEq, Eq, Clone, RustcEncodable, RustcDecodable, HashStable)]
 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>,
@@ -613,13 +614,13 @@ pub struct VtableObjectData<'tcx, N> {
     pub nested: Vec<N>,
 }
 
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable)]
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
 pub struct VtableFnPointerData<'tcx, N> {
     pub fn_ty: Ty<'tcx>,
     pub nested: Vec<N>
 }
 
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable)]
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
 pub struct VtableTraitAliasData<'tcx, N> {
     pub alias_def_id: DefId,
     pub substs: SubstsRef<'tcx>,
diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs
index 72df12bc535..197bea1c311 100644
--- a/src/librustc/traits/project.rs
+++ b/src/librustc/traits/project.rs
@@ -17,6 +17,7 @@ use crate::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime};
 use crate::infer::type_variable::TypeVariableOrigin;
 use crate::mir::interpret::{GlobalId};
 use rustc_data_structures::snapshot_map::{Snapshot, SnapshotMap};
+use rustc_macros::HashStable;
 use syntax::ast::Ident;
 use crate::ty::subst::{Subst, InternalSubsts};
 use crate::ty::{self, ToPredicate, ToPolyTraitRef, Ty, TyCtxt};
@@ -25,7 +26,7 @@ use crate::util::common::FN_OUTPUT_NAME;
 
 /// Depending on the stage of compilation, we want projection to be
 /// more or less conservative.
-#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+#[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
diff --git a/src/librustc/ty/adjustment.rs b/src/librustc/ty/adjustment.rs
index 8d449f5c44c..f9149ce0f6e 100644
--- a/src/librustc/ty/adjustment.rs
+++ b/src/librustc/ty/adjustment.rs
@@ -2,6 +2,7 @@ use crate::hir;
 use crate::hir::def_id::DefId;
 use crate::ty::{self, Ty, TyCtxt};
 use crate::ty::subst::SubstsRef;
+use rustc_macros::HashStable;
 
 
 /// Represents coercing a value to a different type of value.
@@ -44,13 +45,13 @@ use crate::ty::subst::SubstsRef;
 ///    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)]
+#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
 pub struct Adjustment<'tcx> {
     pub kind: Adjust<'tcx>,
     pub target: Ty<'tcx>,
 }
 
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
 pub enum Adjust<'tcx> {
     /// Go from ! to any type.
     NeverToAny,
@@ -90,7 +91,7 @@ pub enum Adjust<'tcx> {
 /// 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)]
+#[derive(Copy, Clone, PartialEq, Debug, RustcEncodable, RustcDecodable, HashStable)]
 pub struct OverloadedDeref<'tcx> {
     pub region: ty::Region<'tcx>,
     pub mutbl: hir::Mutability,
@@ -121,13 +122,13 @@ impl<'a, 'gcx, 'tcx> OverloadedDeref<'tcx> {
 /// 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)]
+#[derive(Copy, Clone, PartialEq, Debug, RustcEncodable, RustcDecodable, HashStable)]
 pub enum AllowTwoPhase {
     Yes,
     No
 }
 
-#[derive(Copy, Clone, PartialEq, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, PartialEq, Debug, RustcEncodable, RustcDecodable, HashStable)]
 pub enum AutoBorrowMutability {
     Mutable { allow_two_phase_borrow: AllowTwoPhase },
     Immutable,
@@ -142,7 +143,7 @@ impl From<AutoBorrowMutability> for hir::Mutability {
     }
 }
 
-#[derive(Copy, Clone, PartialEq, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, PartialEq, Debug, RustcEncodable, RustcDecodable, HashStable)]
 pub enum AutoBorrow<'tcx> {
     /// Converts from T to &T.
     Ref(ty::Region<'tcx>, AutoBorrowMutability),
@@ -157,7 +158,7 @@ pub enum AutoBorrow<'tcx> {
 /// 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)]
+#[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
@@ -166,7 +167,7 @@ pub struct CoerceUnsizedInfo {
     pub custom_kind: Option<CustomCoerceUnsized>
 }
 
-#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)]
+#[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/cast.rs b/src/librustc/ty/cast.rs
index 0b2112f42d5..7ea5c73c5b7 100644
--- a/src/librustc/ty/cast.rs
+++ b/src/librustc/ty/cast.rs
@@ -4,6 +4,7 @@
 use crate::ty::{self, Ty};
 
 use syntax::ast;
+use rustc_macros::HashStable;
 
 /// Types that are represented as ints.
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
@@ -32,7 +33,7 @@ pub enum CastTy<'tcx> {
 }
 
 /// Cast Kind. See RFC 401 (or librustc_typeck/check/cast.rs)
-#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
 pub enum CastKind {
     CoercionCast,
     PtrPtrCast,
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index b705968ce8a..e290ad19642 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -65,6 +65,7 @@ use std::sync::mpsc;
 use std::sync::Arc;
 use std::marker::PhantomData;
 use rustc_target::spec::abi;
+use rustc_macros::HashStable;
 use syntax::ast;
 use syntax::attr;
 use syntax::source_map::MultiSpan;
@@ -316,7 +317,7 @@ impl<'a, V> LocalTableInContextMut<'a, V> {
 }
 
 /// All information necessary to validate and reveal an `impl Trait` or `existential Type`
-#[derive(RustcEncodable, RustcDecodable, Debug)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct ResolvedOpaqueTy<'tcx> {
     /// The revealed type as seen by this function.
     pub concrete_type: Ty<'tcx>,
@@ -808,6 +809,7 @@ impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for TypeckTables<'gcx> {
 
 newtype_index! {
     pub struct UserTypeAnnotationIndex {
+        derive [HashStable]
         DEBUG_FORMAT = "UserType({})",
         const START_INDEX = 0,
     }
@@ -817,7 +819,7 @@ newtype_index! {
 pub type CanonicalUserTypeAnnotations<'tcx> =
     IndexVec<UserTypeAnnotationIndex, CanonicalUserTypeAnnotation<'tcx>>;
 
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
 pub struct CanonicalUserTypeAnnotation<'tcx> {
     pub user_ty: CanonicalUserType<'tcx>,
     pub span: Span,
@@ -893,7 +895,7 @@ impl CanonicalUserType<'gcx> {
 /// 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, Eq, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
 pub enum UserType<'tcx> {
     Ty(Ty<'tcx>),
 
diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs
index 49ebd202813..e0b7bbc68e2 100644
--- a/src/librustc/ty/instance.rs
+++ b/src/librustc/ty/instance.rs
@@ -3,18 +3,19 @@ use crate::hir::def_id::DefId;
 use crate::ty::{self, Ty, PolyFnSig, TypeFoldable, SubstsRef, TyCtxt};
 use crate::traits;
 use rustc_target::spec::abi::Abi;
+use rustc_macros::HashStable;
 use crate::util::ppaux;
 
 use std::fmt;
 use std::iter;
 
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable, HashStable)]
 pub struct Instance<'tcx> {
     pub def: InstanceDef<'tcx>,
     pub substs: SubstsRef<'tcx>,
 }
 
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable, HashStable)]
 pub enum InstanceDef<'tcx> {
     Item(DefId),
     Intrinsic(DefId),
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 1a44dbdbb61..68bdae7d744 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -10,6 +10,7 @@ use crate::hir::def::{Def, CtorKind, ExportMap};
 use crate::hir::def_id::{CrateNum, DefId, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
 use crate::hir::map::DefPathData;
 use rustc_data_structures::svh::Svh;
+use rustc_macros::HashStable;
 use crate::ich::Fingerprint;
 use crate::ich::StableHashingContext;
 use crate::infer::canonical::Canonical;
@@ -128,7 +129,7 @@ pub struct Resolutions {
     pub extern_prelude: FxHashMap<Name, bool>,
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, Debug)]
+#[derive(Clone, Copy, PartialEq, Eq, Debug, HashStable)]
 pub enum AssociatedItemContainer {
     TraitContainer(DefId),
     ImplContainer(DefId),
@@ -163,9 +164,10 @@ pub struct ImplHeader<'tcx> {
     pub predicates: Vec<Predicate<'tcx>>,
 }
 
-#[derive(Copy, Clone, Debug, PartialEq)]
+#[derive(Copy, Clone, Debug, PartialEq, HashStable)]
 pub struct AssociatedItem {
     pub def_id: DefId,
+    #[stable_hasher(project(name))]
     pub ident: Ident,
     pub kind: AssociatedKind,
     pub vis: Visibility,
@@ -177,7 +179,7 @@ pub struct AssociatedItem {
     pub method_has_self_argument: bool,
 }
 
-#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, RustcEncodable, RustcDecodable, HashStable)]
 pub enum AssociatedKind {
     Const,
     Method,
@@ -225,7 +227,7 @@ impl AssociatedItem {
     }
 }
 
-#[derive(Clone, Debug, PartialEq, Eq, Copy, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Debug, PartialEq, Eq, Copy, RustcEncodable, RustcDecodable, HashStable)]
 pub enum Visibility {
     /// Visible everywhere (including in other crates).
     Public,
@@ -312,7 +314,7 @@ impl Visibility {
     }
 }
 
-#[derive(Copy, Clone, PartialEq, Eq, RustcDecodable, RustcEncodable, Hash)]
+#[derive(Copy, Clone, PartialEq, Eq, RustcDecodable, RustcEncodable, Hash, 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
@@ -326,6 +328,7 @@ pub enum Variance {
 /// 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 {
     /// 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
@@ -333,6 +336,7 @@ pub struct CrateVariancesMap {
     pub variances: FxHashMap<DefId, Lrc<Vec<ty::Variance>>>,
 
     /// An empty vector, useful for cloning.
+    #[stable_hasher(ignore)]
     pub empty_variance: Lrc<Vec<ty::Variance>>,
 }
 
@@ -718,7 +722,7 @@ impl<T> List<T> {
     }
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
 pub struct UpvarPath {
     pub hir_id: hir::HirId,
 }
@@ -726,13 +730,13 @@ pub struct UpvarPath {
 /// 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)]
+#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
 pub struct UpvarId {
     pub var_path: UpvarPath,
     pub closure_expr_id: LocalDefId,
 }
 
-#[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable, Copy)]
+#[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable, Copy, HashStable)]
 pub enum BorrowKind {
     /// Data must be immutable and is aliasable.
     ImmBorrow,
@@ -780,7 +784,7 @@ pub enum BorrowKind {
 
 /// Information describing the capture of an upvar. This is computed
 /// during `typeck`, specifically by `regionck`.
-#[derive(PartialEq, Clone, Debug, Copy, RustcEncodable, RustcDecodable)]
+#[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
@@ -791,7 +795,7 @@ pub enum UpvarCapture<'tcx> {
     ByRef(UpvarBorrow<'tcx>),
 }
 
-#[derive(PartialEq, Clone, Copy, RustcEncodable, RustcDecodable)]
+#[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
@@ -833,7 +837,7 @@ impl ty::EarlyBoundRegion {
     }
 }
 
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
 pub enum GenericParamDefKind {
     Lifetime,
     Type {
@@ -844,7 +848,7 @@ pub enum GenericParamDefKind {
     Const,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable)]
+#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
 pub struct GenericParamDef {
     pub name: InternedString,
     pub def_id: DefId,
@@ -892,13 +896,14 @@ pub struct GenericParamCount {
 ///
 /// The ordering of parameters is the same as in `Subst` (excluding child generics):
 /// `Self` (optionally), `Lifetime` params..., `Type` params...
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
+#[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,
@@ -995,7 +1000,7 @@ impl<'a, 'gcx, 'tcx> Generics {
 }
 
 /// Bounds on generics.
-#[derive(Clone, Default)]
+#[derive(Clone, Default, HashStable)]
 pub struct GenericPredicates<'tcx> {
     pub parent: Option<DefId>,
     pub predicates: Vec<(Predicate<'tcx>, Span)>,
@@ -1058,7 +1063,7 @@ impl<'a, 'gcx, 'tcx> GenericPredicates<'tcx> {
     }
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
 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`
@@ -1099,6 +1104,7 @@ pub enum Predicate<'tcx> {
 /// 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
@@ -1106,6 +1112,7 @@ pub struct CratePredicatesMap<'tcx> {
     pub predicates: FxHashMap<DefId, Lrc<Vec<ty::Predicate<'tcx>>>>,
 
     /// An empty vector, useful for cloning.
+    #[stable_hasher(ignore)]
     pub empty_predicate: Lrc<Vec<ty::Predicate<'tcx>>>,
 }
 
@@ -1209,7 +1216,7 @@ impl<'a, 'gcx, 'tcx> Predicate<'tcx> {
     }
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
 pub struct TraitPredicate<'tcx> {
     pub trait_ref: TraitRef<'tcx>
 }
@@ -1237,7 +1244,8 @@ impl<'tcx> PolyTraitPredicate<'tcx> {
     }
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord,
+         Hash, Debug, RustcEncodable, RustcDecodable, HashStable)]
 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>,
@@ -1247,7 +1255,7 @@ pub type TypeOutlivesPredicate<'tcx> = OutlivesPredicate<Ty<'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(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable, HashStable)]
 pub struct SubtypePredicate<'tcx> {
     pub a_is_expected: bool,
     pub a: Ty<'tcx>,
@@ -1267,7 +1275,7 @@ pub type PolySubtypePredicate<'tcx> = ty::Binder<SubtypePredicate<'tcx>>;
 /// 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(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
 pub struct ProjectionPredicate<'tcx> {
     pub projection_ty: ProjectionTy<'tcx>,
     pub ty: Ty<'tcx>,
@@ -1622,7 +1630,7 @@ pub type PlaceholderType = 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)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)]
 pub struct ParamEnv<'tcx> {
     /// Obligations that the caller must satisfy. This is basically
     /// the set of bounds on the in-scope type parameters, translated
@@ -1757,13 +1765,14 @@ impl<'a, 'gcx, T> HashStable<StableHashingContext<'a>> for ParamEnvAnd<'gcx, T>
     }
 }
 
-#[derive(Copy, Clone, Debug)]
+#[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;
         const IS_ENUM             = 1 << 0;
@@ -1784,6 +1793,7 @@ bitflags! {
 }
 
 bitflags! {
+    #[derive(HashStable)]
     pub struct VariantFlags: u32 {
         const NO_VARIANT_FLAGS        = 0;
         /// Indicates whether the field list of this variant is `#[non_exhaustive]`.
@@ -1861,7 +1871,7 @@ impl_stable_hash_for!(struct VariantDef {
     flags
 });
 
-#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
+#[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.
@@ -1874,9 +1884,10 @@ pub enum VariantDiscr {
     Relative(u32),
 }
 
-#[derive(Debug)]
+#[derive(Debug, HashStable)]
 pub struct FieldDef {
     pub did: DefId,
+    #[stable_hasher(project(name))]
     pub ident: Ident,
     pub vis: Visibility,
 }
@@ -2497,7 +2508,8 @@ impl<'a, 'gcx, 'tcx> FieldDef {
 ///
 /// 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)]
+#[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
@@ -3092,7 +3104,7 @@ fn associated_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Asso
               parent_item.node)
 }
 
-#[derive(Clone)]
+#[derive(Clone, HashStable)]
 pub struct AdtSizedConstraint<'tcx>(pub &'tcx [Ty<'tcx>]);
 
 /// Calculates the `Sized` constraint.
@@ -3325,7 +3337,7 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) {
 /// 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)]
+#[derive(Clone, Debug, Default, HashStable)]
 pub struct CrateInherentImpls {
     pub inherent_impls: DefIdMap<Lrc<Vec<DefId>>>,
 }
diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
index 95148834e01..39728cc8cd5 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc/ty/sty.rs
@@ -7,6 +7,7 @@ use crate::mir::interpret::{ConstValue, truncate};
 use crate::middle::region;
 use polonius_engine::Atom;
 use rustc_data_structures::indexed_vec::Idx;
+use rustc_macros::HashStable;
 use crate::ty::subst::{InternalSubsts, Subst, SubstsRef, Kind, UnpackedKind};
 use crate::ty::{self, AdtDef, TypeFlags, Ty, TyCtxt, TypeFoldable};
 use crate::ty::{List, TyS, ParamEnvAnd, ParamEnv};
@@ -25,14 +26,15 @@ use serialize;
 use self::InferTy::*;
 use self::TyKind::*;
 
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord,
+         Hash, Debug, RustcEncodable, RustcDecodable, HashStable)]
 pub struct TypeAndMut<'tcx> {
     pub ty: Ty<'tcx>,
     pub mutbl: hir::Mutability,
 }
 
 #[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash,
-         RustcEncodable, RustcDecodable, Copy)]
+         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 {
@@ -41,7 +43,7 @@ pub struct FreeRegion {
 }
 
 #[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash,
-         RustcEncodable, RustcDecodable, Copy)]
+         RustcEncodable, RustcDecodable, Copy, HashStable)]
 pub enum BoundRegion {
     /// An anonymous region parameter for a given fn (&T)
     BrAnon(u32),
@@ -82,7 +84,8 @@ impl BoundRegion {
 
 /// 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, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug,
+         RustcEncodable, RustcDecodable, HashStable)]
 pub enum TyKind<'tcx> {
     /// The primitive boolean type. Written as `bool`.
     Bool,
@@ -303,7 +306,8 @@ static_assert!(MEM_SIZE_OF_TY_KIND: ::std::mem::size_of::<TyKind<'_>>() == 24);
 ///
 /// It'd be nice to split this struct into ClosureSubsts and
 /// GeneratorSubsts, I believe. -nmatsakis
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash,
+         Debug, RustcEncodable, RustcDecodable, HashStable)]
 pub struct ClosureSubsts<'tcx> {
     /// Lifetime and type parameters from the enclosing function,
     /// concatenated with the types of the upvars.
@@ -386,7 +390,8 @@ impl<'tcx> ClosureSubsts<'tcx> {
     }
 }
 
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug,
+         RustcEncodable, RustcDecodable, HashStable)]
 pub struct GeneratorSubsts<'tcx> {
     pub substs: SubstsRef<'tcx>,
 }
@@ -519,7 +524,8 @@ impl<'tcx> UpvarSubsts<'tcx> {
     }
 }
 
-#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Hash,
+         RustcEncodable, RustcDecodable, HashStable)]
 pub enum ExistentialPredicate<'tcx> {
     /// E.g., `Iterator`.
     Trait(ExistentialTraitRef<'tcx>),
@@ -670,7 +676,7 @@ impl<'tcx> Binder<&'tcx List<ExistentialPredicate<'tcx>>> {
 /// 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(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
 pub struct TraitRef<'tcx> {
     pub def_id: DefId,
     pub substs: SubstsRef<'tcx>,
@@ -740,7 +746,8 @@ impl<'tcx> PolyTraitRef<'tcx> {
 ///
 /// 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(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash,
+         RustcEncodable, RustcDecodable, HashStable)]
 pub struct ExistentialTraitRef<'tcx> {
     pub def_id: DefId,
     pub substs: SubstsRef<'tcx>,
@@ -913,7 +920,8 @@ impl<T> Binder<T> {
 
 /// 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(Copy, Clone, PartialEq, Eq, PartialOrd, Ord,
+         Hash, Debug, RustcEncodable, RustcDecodable, HashStable)]
 pub struct ProjectionTy<'tcx> {
     /// The parameters of the associated item.
     pub substs: SubstsRef<'tcx>,
@@ -958,7 +966,7 @@ impl<'a, 'tcx> ProjectionTy<'tcx> {
     }
 }
 
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
 pub struct GenSig<'tcx> {
     pub yield_ty: Ty<'tcx>,
     pub return_ty: Ty<'tcx>,
@@ -981,7 +989,8 @@ impl<'tcx> PolyGenSig<'tcx> {
 /// - `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(Copy, Clone, PartialEq, Eq, PartialOrd, Ord,
+         Hash, RustcEncodable, RustcDecodable, HashStable)]
 pub struct FnSig<'tcx> {
     pub inputs_and_output: &'tcx List<Ty<'tcx>>,
     pub c_variadic: bool,
@@ -1031,7 +1040,8 @@ impl<'tcx> PolyFnSig<'tcx> {
 pub type CanonicalPolyFnSig<'tcx> = Canonical<'tcx, Binder<FnSig<'tcx>>>;
 
 
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord,
+         Hash, RustcEncodable, RustcDecodable, HashStable)]
 pub struct ParamTy {
     pub idx: u32,
     pub name: InternedString,
@@ -1062,7 +1072,8 @@ impl<'a, 'gcx, 'tcx> ParamTy {
     }
 }
 
-#[derive(Copy, Clone, Hash, RustcEncodable, RustcDecodable, Eq, PartialEq, Ord, PartialOrd)]
+#[derive(Copy, Clone, Hash, RustcEncodable, RustcDecodable,
+         Eq, PartialEq, Ord, PartialOrd, HashStable)]
 pub struct ParamConst {
     pub index: u32,
     pub name: InternedString,
@@ -1278,7 +1289,8 @@ impl Atom for RegionVid {
     }
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord,
+         Hash, RustcEncodable, RustcDecodable, HashStable)]
 pub enum InferTy {
     TyVar(TyVid),
     IntVar(IntVid),
@@ -1321,7 +1333,8 @@ impl From<BoundVar> for BoundTy {
 }
 
 /// A `ProjectionPredicate` for an `ExistentialTraitRef`.
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash,
+         Debug, RustcEncodable, RustcDecodable, HashStable)]
 pub struct ExistentialProjection<'tcx> {
     pub item_def_id: DefId,
     pub substs: SubstsRef<'tcx>,
@@ -2083,7 +2096,8 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
     }
 }
 
-#[derive(Copy, Clone, Debug, Hash, RustcEncodable, RustcDecodable, Eq, PartialEq, Ord, PartialOrd)]
+#[derive(Copy, Clone, Debug, Hash, RustcEncodable, RustcDecodable,
+         Eq, PartialEq, Ord, PartialOrd, HashStable)]
 /// Used in the HIR by using `Unevaluated` everywhere and later normalizing to `Evaluated` if the
 /// code is monomorphic enough for that.
 pub enum LazyConst<'tcx> {
@@ -2129,7 +2143,8 @@ impl<'tcx> LazyConst<'tcx> {
 }
 
 /// Typed constant value.
-#[derive(Copy, Clone, Debug, Hash, RustcEncodable, RustcDecodable, Eq, PartialEq, Ord, PartialOrd)]
+#[derive(Copy, Clone, Debug, Hash, RustcEncodable, RustcDecodable,
+         Eq, PartialEq, Ord, PartialOrd, HashStable)]
 pub struct Const<'tcx> {
     pub ty: Ty<'tcx>,
 
@@ -2273,7 +2288,8 @@ impl<'tcx> Const<'tcx> {
 impl<'tcx> serialize::UseSpecializedDecodable for &'tcx LazyConst<'tcx> {}
 
 /// An inference variable for a const, for use in const generics.
-#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash)]
+#[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>),
diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs
index 35c6f980cd9..38be19a71c4 100644
--- a/src/librustc/ty/subst.rs
+++ b/src/librustc/ty/subst.rs
@@ -9,6 +9,7 @@ use crate::mir::interpret::ConstValue;
 use serialize::{self, Encodable, Encoder, Decodable, Decoder};
 use syntax_pos::{Span, DUMMY_SP};
 use smallvec::SmallVec;
+use rustc_macros::HashStable;
 
 use core::intrinsics;
 use std::cmp::Ordering;
@@ -33,7 +34,7 @@ const TYPE_TAG: usize = 0b00;
 const REGION_TAG: usize = 0b01;
 const CONST_TAG: usize = 0b10;
 
-#[derive(Debug, RustcEncodable, RustcDecodable, PartialEq, Eq, PartialOrd, Ord)]
+#[derive(Debug, RustcEncodable, RustcDecodable, PartialEq, Eq, PartialOrd, Ord, HashStable)]
 pub enum UnpackedKind<'tcx> {
     Lifetime(ty::Region<'tcx>),
     Type(Ty<'tcx>),
@@ -666,7 +667,7 @@ 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(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
 pub struct UserSubsts<'tcx> {
     /// The substitutions for the item as given by the user.
     pub substs: SubstsRef<'tcx>,
@@ -707,7 +708,7 @@ BraceStructLiftImpl! {
 /// 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(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
 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
index 9ce8bf2e60a..b25a6c4f28c 100644
--- a/src/librustc/ty/trait_def.rs
+++ b/src/librustc/ty/trait_def.rs
@@ -11,9 +11,13 @@ use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
                                            StableHasherResult};
 use rustc_data_structures::sync::Lrc;
+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,
diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs
index fb0d1e2080b..422f97b2996 100644
--- a/src/librustc/ty/util.rs
+++ b/src/librustc/ty/util.rs
@@ -18,6 +18,7 @@ use crate::middle::lang_items;
 
 use rustc_data_structures::stable_hasher::{StableHasher, HashStable};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_macros::HashStable;
 use std::{cmp, fmt};
 use syntax::ast;
 use syntax::attr::{self, SignedInt, UnsignedInt};
@@ -1005,7 +1006,7 @@ fn is_freeze_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         ))
 }
 
-#[derive(Clone)]
+#[derive(Clone, HashStable)]
 pub struct NeedsDrop(pub bool);
 
 fn needs_drop_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs
index dd635e5c946..5622fe43436 100644
--- a/src/librustc/util/common.rs
+++ b/src/librustc/util/common.rs
@@ -12,6 +12,7 @@ use std::time::{Duration, Instant};
 
 use std::sync::mpsc::{Sender};
 use syntax_pos::{SpanData};
+use rustc_macros::HashStable;
 use crate::ty::TyCtxt;
 use crate::dep_graph::{DepNode};
 use lazy_static;
@@ -22,7 +23,7 @@ pub const FN_OUTPUT_NAME: &str = "Output";
 
 // Useful type to use with `Result<>` indicate that an error has already
 // been reported to the user, so no need to continue checking.
-#[derive(Clone, Copy, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Copy, Debug, RustcEncodable, RustcDecodable, HashStable)]
 pub struct ErrorReported;
 
 thread_local!(static TIME_DEPTH: Cell<usize> = Cell::new(0));
diff --git a/src/librustc_data_structures/thin_vec.rs b/src/librustc_data_structures/thin_vec.rs
index ed57c528f51..52f23f4893e 100644
--- a/src/librustc_data_structures/thin_vec.rs
+++ b/src/librustc_data_structures/thin_vec.rs
@@ -1,3 +1,5 @@
+use crate::stable_hasher::{StableHasher, StableHasherResult, HashStable};
+
 /// A vector type optimized for cases where this size is usually 0 (cf. `SmallVector`).
 /// The `Option<Box<..>>` wrapping allows us to represent a zero sized vector with `None`,
 /// which uses only a single (null) pointer.
@@ -56,3 +58,11 @@ impl<T> Extend<T> for ThinVec<T> {
         }
     }
 }
+
+impl<T: HashStable<CTX>, CTX> HashStable<CTX> for ThinVec<T> {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut CTX,
+                                          hasher: &mut StableHasher<W>) {
+        (**self).hash_stable(hcx, hasher)
+    }
+}