about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2019-11-20 18:32:07 +0100
committerGitHub <noreply@github.com>2019-11-20 18:32:07 +0100
commit647eda17e825b61511e66d7d01ac737cae054ee3 (patch)
treee1b43fd2d71c4f2275f9f3568e2c68f81a91f78e /src
parent00cbc75c74cda031a5e9df592cca95644f17ec8f (diff)
parent579625b9e738e606b91fa315c75ab4909fa090be (diff)
downloadrust-647eda17e825b61511e66d7d01ac737cae054ee3.tar.gz
rust-647eda17e825b61511e66d7d01ac737cae054ee3.zip
Rollup merge of #66457 - cjgillot:just_hashstable, r=Zoxc
Just derive Hashstable in librustc

Split out of #66279

r? @Zoxc
Diffstat (limited to 'src')
-rw-r--r--src/librustc/dep_graph/dep_node.rs6
-rw-r--r--src/librustc/hir/map/definitions.rs4
-rw-r--r--src/librustc/hir/mod.rs2
-rw-r--r--src/librustc/ich/impls_hir.rs7
-rw-r--r--src/librustc/infer/outlives/free_region_map.rs6
-rw-r--r--src/librustc/lint/mod.rs17
-rw-r--r--src/librustc/middle/exported_symbols.rs7
-rw-r--r--src/librustc/middle/resolve_lifetime.rs8
-rw-r--r--src/librustc/middle/stability.rs15
-rw-r--r--src/librustc/mir/interpret/allocation.rs6
-rw-r--r--src/librustc/mir/interpret/value.rs7
-rw-r--r--src/librustc/mir/mod.rs62
-rw-r--r--src/librustc/mir/mono.rs24
-rw-r--r--src/librustc/traits/query/dropck_outlives.rs13
-rw-r--r--src/librustc/traits/query/method_autoderef.rs18
-rw-r--r--src/librustc/traits/query/mod.rs4
-rw-r--r--src/librustc/traits/query/normalize.rs6
-rw-r--r--src/librustc/traits/query/type_op/ascribe_user_type.rs8
-rw-r--r--src/librustc/traits/query/type_op/eq.rs6
-rw-r--r--src/librustc/traits/query/type_op/implied_outlives_bounds.rs6
-rw-r--r--src/librustc/traits/query/type_op/normalize.rs8
-rw-r--r--src/librustc/traits/query/type_op/outlives.rs6
-rw-r--r--src/librustc/traits/query/type_op/prove_predicate.rs6
-rw-r--r--src/librustc/traits/query/type_op/subtype.rs6
-rw-r--r--src/librustc/traits/select.rs15
-rw-r--r--src/librustc/traits/specialize/specialization_graph.rs7
-rw-r--r--src/librustc/ty/binding.rs7
-rw-r--r--src/librustc/ty/mod.rs39
-rw-r--r--src/librustc/ty/sty.rs12
-rw-r--r--src/librustc_mir/Cargo.toml1
-rw-r--r--src/librustc_mir/interpret/eval_context.rs8
-rw-r--r--src/librustc_mir/interpret/operand.rs5
-rw-r--r--src/librustc_mir/interpret/place.rs5
-rw-r--r--src/librustc_mir/interpret/snapshot.rs42
34 files changed, 69 insertions, 330 deletions
diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs
index cea790375fc..17ab0c187a2 100644
--- a/src/librustc/dep_graph/dep_node.rs
+++ b/src/librustc/dep_graph/dep_node.rs
@@ -578,7 +578,7 @@ impl<'tcx> DepNodeParams<'tcx> for HirId {
 /// the need to be mapped or unmapped. (This ensures we can serialize
 /// them even in the absence of a tcx.)
 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash,
-         RustcEncodable, RustcDecodable)]
+         RustcEncodable, RustcDecodable, HashStable)]
 pub struct WorkProductId {
     hash: Fingerprint
 }
@@ -599,7 +599,3 @@ impl WorkProductId {
         }
     }
 }
-
-impl_stable_hash_for!(struct crate::dep_graph::WorkProductId {
-    hash
-});
diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs
index 1e444e8a5b8..2b3bc37c87c 100644
--- a/src/librustc/hir/map/definitions.rs
+++ b/src/librustc/hir/map/definitions.rs
@@ -313,11 +313,9 @@ pub enum DefPathData {
 }
 
 #[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Debug,
-         RustcEncodable, RustcDecodable)]
+         RustcEncodable, RustcDecodable, HashStable)]
 pub struct DefPathHash(pub Fingerprint);
 
-impl_stable_hash_for!(tuple_struct DefPathHash { fingerprint });
-
 impl Borrow<Fingerprint> for DefPathHash {
     #[inline]
     fn borrow(&self) -> &Fingerprint {
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index bbd3b40e1be..465673082e5 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -1215,7 +1215,7 @@ impl UnOp {
 }
 
 /// A statement.
-#[derive(RustcEncodable, RustcDecodable)]
+#[derive(RustcEncodable, RustcDecodable, HashStable)]
 pub struct Stmt {
     pub hir_id: HirId,
     pub kind: StmtKind,
diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs
index c0255e5b8a4..816e93698bc 100644
--- a/src/librustc/ich/impls_hir.rs
+++ b/src/librustc/ich/impls_hir.rs
@@ -140,13 +140,6 @@ impl<'a> HashStable<StableHashingContext<'a>> for hir::Ty {
 
 impl_stable_hash_for_spanned!(hir::BinOpKind);
 
-impl_stable_hash_for!(struct hir::Stmt {
-    hir_id,
-    kind,
-    span,
-});
-
-
 impl_stable_hash_for_spanned!(ast::Name);
 
 impl<'a> HashStable<StableHashingContext<'a>> for hir::Expr {
diff --git a/src/librustc/infer/outlives/free_region_map.rs b/src/librustc/infer/outlives/free_region_map.rs
index c085df6a6e7..fd8ccce6833 100644
--- a/src/librustc/infer/outlives/free_region_map.rs
+++ b/src/librustc/infer/outlives/free_region_map.rs
@@ -1,7 +1,7 @@
 use crate::ty::{self, Lift, TyCtxt, Region};
 use rustc_data_structures::transitive_relation::TransitiveRelation;
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Default)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Default, HashStable)]
 pub struct FreeRegionMap<'tcx> {
     // Stores the relation `a < b`, where `a` and `b` are regions.
     //
@@ -89,10 +89,6 @@ fn is_free_or_static(r: Region<'_>) -> bool {
     }
 }
 
-impl_stable_hash_for!(struct FreeRegionMap<'tcx> {
-    relation
-});
-
 impl<'a, 'tcx> Lift<'tcx> for FreeRegionMap<'a> {
     type Lifted = FreeRegionMap<'tcx>;
     fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<FreeRegionMap<'tcx>> {
diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs
index 11d0d0d90fa..d84102ff3c5 100644
--- a/src/librustc/lint/mod.rs
+++ b/src/librustc/lint/mod.rs
@@ -543,18 +543,11 @@ impl LintId {
 }
 
 /// Setting for how to handle a lint.
-#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
+#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash, HashStable)]
 pub enum Level {
     Allow, Warn, Deny, Forbid,
 }
 
-impl_stable_hash_for!(enum self::Level {
-    Allow,
-    Warn,
-    Deny,
-    Forbid
-});
-
 impl Level {
     /// Converts a level to a lower-case string.
     pub fn as_str(self) -> &'static str {
@@ -590,7 +583,7 @@ impl Level {
 }
 
 /// How a lint level was set.
-#[derive(Clone, Copy, PartialEq, Eq)]
+#[derive(Clone, Copy, PartialEq, Eq, HashStable)]
 pub enum LintSource {
     /// Lint is at the default level as declared
     /// in rustc or a plugin.
@@ -603,12 +596,6 @@ pub enum LintSource {
     CommandLine(Symbol),
 }
 
-impl_stable_hash_for!(enum self::LintSource {
-    Default,
-    Node(name, span, reason),
-    CommandLine(text)
-});
-
 pub type LevelSource = (Level, LintSource);
 
 pub mod builtin;
diff --git a/src/librustc/middle/exported_symbols.rs b/src/librustc/middle/exported_symbols.rs
index 4d14299751c..7182f031824 100644
--- a/src/librustc/middle/exported_symbols.rs
+++ b/src/librustc/middle/exported_symbols.rs
@@ -11,17 +11,12 @@ use crate::ty::subst::SubstsRef;
 /// kind of crate, including cdylibs which export very few things.
 /// `Rust` will only be exported if the crate produced is a Rust
 /// dylib.
-#[derive(Eq, PartialEq, Debug, Copy, Clone, RustcEncodable, RustcDecodable)]
+#[derive(Eq, PartialEq, Debug, Copy, Clone, RustcEncodable, RustcDecodable, HashStable)]
 pub enum SymbolExportLevel {
     C,
     Rust,
 }
 
-impl_stable_hash_for!(enum self::SymbolExportLevel {
-    C,
-    Rust
-});
-
 impl SymbolExportLevel {
     pub fn is_below_threshold(self, threshold: SymbolExportLevel) -> bool {
         threshold == SymbolExportLevel::Rust // export everything from Rust dylibs
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index a70fe2be96c..c13c44c413d 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -207,7 +207,7 @@ struct NamedRegionMap {
 }
 
 /// See [`NamedRegionMap`].
-#[derive(Default)]
+#[derive(Default, HashStable)]
 pub struct ResolveLifetimes {
     defs: FxHashMap<LocalDefId, FxHashMap<ItemLocalId, Region>>,
     late_bound: FxHashMap<LocalDefId, FxHashSet<ItemLocalId>>,
@@ -215,12 +215,6 @@ pub struct ResolveLifetimes {
         FxHashMap<LocalDefId, FxHashMap<ItemLocalId, Vec<ObjectLifetimeDefault>>>,
 }
 
-impl_stable_hash_for!(struct crate::middle::resolve_lifetime::ResolveLifetimes {
-    defs,
-    late_bound,
-    object_lifetime_defaults
-});
-
 struct LifetimeContext<'a, 'tcx> {
     tcx: TyCtxt<'tcx>,
     map: &'a mut NamedRegionMap,
diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs
index 8f8b4ed98bd..411a47423c5 100644
--- a/src/librustc/middle/stability.rs
+++ b/src/librustc/middle/stability.rs
@@ -52,7 +52,7 @@ enum AnnotationKind {
 }
 
 /// An entry in the `depr_map`.
-#[derive(Clone)]
+#[derive(Clone, HashStable)]
 pub struct DeprecationEntry {
     /// The metadata of the attribute associated with this entry.
     pub attr: Deprecation,
@@ -61,11 +61,6 @@ pub struct DeprecationEntry {
     origin: Option<HirId>,
 }
 
-impl_stable_hash_for!(struct self::DeprecationEntry {
-    attr,
-    origin
-});
-
 impl DeprecationEntry {
     fn local(attr: Deprecation, id: HirId) -> DeprecationEntry {
         DeprecationEntry {
@@ -90,6 +85,7 @@ impl DeprecationEntry {
 }
 
 /// A stability index, giving the stability level for items and methods.
+#[derive(HashStable)]
 pub struct Index<'tcx> {
     /// This is mostly a cache, except the stabilities of local items
     /// are filled by the annotator.
@@ -103,13 +99,6 @@ pub struct Index<'tcx> {
     active_features: FxHashSet<Symbol>,
 }
 
-impl_stable_hash_for!(struct self::Index<'tcx> {
-    stab_map,
-    depr_map,
-    staged_api,
-    active_features
-});
-
 // A private tree-walker for producing an Index.
 struct Annotator<'a, 'tcx> {
     tcx: TyCtxt<'tcx>,
diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs
index aa8ac4902a8..f849361e08b 100644
--- a/src/librustc/mir/interpret/allocation.rs
+++ b/src/librustc/mir/interpret/allocation.rs
@@ -4,7 +4,6 @@ use super::{
     Pointer, InterpResult, AllocId, ScalarMaybeUndef, write_target_uint, read_target_uint, Scalar,
 };
 
-use crate::mir;
 use crate::ty::layout::{Size, Align};
 
 use rustc_data_structures::sorted_map::SortedMap;
@@ -787,14 +786,13 @@ type Block = u64;
 
 /// A bitmask where each bit refers to the byte with the same index. If the bit is `true`, the byte
 /// is defined. If it is `false` the byte is undefined.
-#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash,
+         RustcEncodable, RustcDecodable, HashStable)]
 pub struct UndefMask {
     blocks: Vec<Block>,
     len: Size,
 }
 
-impl_stable_hash_for!(struct mir::interpret::UndefMask{blocks, len});
-
 impl UndefMask {
     pub const BLOCK_SIZE: u64 = 64;
 
diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs
index a0367154b75..52c72de7579 100644
--- a/src/librustc/mir/interpret/value.rs
+++ b/src/librustc/mir/interpret/value.rs
@@ -458,7 +458,7 @@ impl<Tag> From<Pointer<Tag>> for Scalar<Tag> {
     }
 }
 
-#[derive(Clone, Copy, Eq, PartialEq, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Copy, Eq, PartialEq, RustcEncodable, RustcDecodable, HashStable)]
 pub enum ScalarMaybeUndef<Tag = (), Id = AllocId> {
     Scalar(Scalar<Tag, Id>),
     Undef,
@@ -583,11 +583,6 @@ impl<'tcx, Tag> ScalarMaybeUndef<Tag> {
     }
 }
 
-impl_stable_hash_for!(enum crate::mir::interpret::ScalarMaybeUndef {
-    Scalar(v),
-    Undef
-});
-
 /// Gets the bytes of a constant slice value.
 pub fn get_slice_bytes<'tcx>(cx: &impl HasDataLayout, val: ConstValue<'tcx>) -> &'tcx [u8] {
     if let ConstValue::Slice { data, start, end } = val {
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index 5997e4367bf..79468b68055 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -70,7 +70,8 @@ impl<'tcx> HasLocalDecls<'tcx> for Body<'tcx> {
 /// The various "big phases" that MIR goes through.
 ///
 /// Warning: ordering of variants is significant.
-#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, PartialEq, Eq, PartialOrd, Ord)]
+#[derive(Copy, Clone, RustcEncodable, RustcDecodable, HashStable,
+         Debug, PartialEq, Eq, PartialOrd, Ord)]
 pub enum MirPhase {
     Build = 0,
     Const = 1,
@@ -86,7 +87,7 @@ impl MirPhase {
 }
 
 /// The lowered representation of a single function.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, TypeFoldable)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable, TypeFoldable)]
 pub struct Body<'tcx> {
     /// A list of basic blocks. References to basic block use a newtyped index type `BasicBlock`
     /// that indexes into this vector.
@@ -412,24 +413,6 @@ pub enum Safety {
     ExplicitUnsafe(hir::HirId),
 }
 
-impl_stable_hash_for!(struct Body<'tcx> {
-    phase,
-    basic_blocks,
-    source_scopes,
-    source_scope_local_data,
-    yield_ty,
-    generator_drop,
-    generator_layout,
-    local_decls,
-    user_type_annotations,
-    arg_count,
-    __upvar_debuginfo_codegen_only_do_not_use,
-    spread_arg,
-    control_flow_destroyed,
-    span,
-    cache
-});
-
 impl<'tcx> Index<BasicBlock> for Body<'tcx> {
     type Output = BasicBlockData<'tcx>;
 
@@ -609,7 +592,7 @@ pub enum LocalKind {
     ReturnPointer,
 }
 
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
 pub struct VarBindingForm<'tcx> {
     /// Is variable bound via `x`, `mut x`, `ref x`, or `ref mut x`?
     pub binding_mode: ty::BindingMode,
@@ -642,7 +625,7 @@ pub enum BindingForm<'tcx> {
 }
 
 /// Represents what type of implicit self a function has, if any.
-#[derive(Clone, Copy, PartialEq, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Copy, PartialEq, Debug, RustcEncodable, RustcDecodable, HashStable)]
 pub enum ImplicitSelfKind {
     /// Represents a `fn x(self);`.
     Imm,
@@ -659,28 +642,6 @@ pub enum ImplicitSelfKind {
 
 CloneTypeFoldableAndLiftImpls! { BindingForm<'tcx>, }
 
-impl_stable_hash_for!(struct self::VarBindingForm<'tcx> {
-    binding_mode,
-    opt_ty_info,
-    opt_match_place,
-    pat_span
-});
-
-impl_stable_hash_for!(enum self::ImplicitSelfKind {
-    Imm,
-    Mut,
-    ImmRef,
-    MutRef,
-    None
-});
-
-impl_stable_hash_for!(enum self::MirPhase {
-    Build,
-    Const,
-    Validated,
-    Optimized,
-});
-
 mod binding_form_impl {
     use crate::ich::StableHashingContext;
     use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
@@ -707,7 +668,7 @@ mod binding_form_impl {
 /// involved in borrow_check errors, e.g., explanations of where the
 /// temporaries come from, when their destructors are run, and/or how
 /// one might revise the code to satisfy the borrow checker's rules.
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
 pub struct BlockTailInfo {
     /// If `true`, then the value resulting from evaluating this tail
     /// expression is ignored by the block's expression context.
@@ -717,8 +678,6 @@ pub struct BlockTailInfo {
     pub tail_result_is_ignored: bool,
 }
 
-impl_stable_hash_for!(struct BlockTailInfo { tail_result_is_ignored });
-
 /// A MIR local.
 ///
 /// This can be a binding declared by the user, a temporary inserted by the compiler, a function
@@ -1746,7 +1705,8 @@ pub enum PlaceBase<'tcx> {
 }
 
 /// We store the normalized type to avoid requiring normalization when reading MIR
-#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash,
+         RustcEncodable, RustcDecodable, HashStable)]
 pub struct Static<'tcx> {
     pub ty: Ty<'tcx>,
     pub kind: StaticKind<'tcx>,
@@ -1768,12 +1728,6 @@ pub enum StaticKind<'tcx> {
     Static,
 }
 
-impl_stable_hash_for!(struct Static<'tcx> {
-    ty,
-    kind,
-    def_id
-});
-
 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
 #[derive(RustcEncodable, RustcDecodable, HashStable)]
 pub enum ProjectionElem<V, T> {
diff --git a/src/librustc/mir/mono.rs b/src/librustc/mir/mono.rs
index a54635c3d51..34daf185b29 100644
--- a/src/librustc/mir/mono.rs
+++ b/src/librustc/mir/mono.rs
@@ -251,7 +251,7 @@ pub struct CodegenUnit<'tcx> {
     size_estimate: Option<usize>,
 }
 
-#[derive(Copy, Clone, PartialEq, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, PartialEq, Debug, RustcEncodable, RustcDecodable, HashStable)]
 pub enum Linkage {
     External,
     AvailableExternally,
@@ -266,33 +266,13 @@ pub enum Linkage {
     Common,
 }
 
-impl_stable_hash_for!(enum self::Linkage {
-    External,
-    AvailableExternally,
-    LinkOnceAny,
-    LinkOnceODR,
-    WeakAny,
-    WeakODR,
-    Appending,
-    Internal,
-    Private,
-    ExternalWeak,
-    Common
-});
-
-#[derive(Copy, Clone, PartialEq, Debug)]
+#[derive(Copy, Clone, PartialEq, Debug, HashStable)]
 pub enum Visibility {
     Default,
     Hidden,
     Protected,
 }
 
-impl_stable_hash_for!(enum self::Visibility {
-    Default,
-    Hidden,
-    Protected
-});
-
 impl<'tcx> CodegenUnit<'tcx> {
     pub fn new(name: Symbol) -> CodegenUnit<'tcx> {
         CodegenUnit {
diff --git a/src/librustc/traits/query/dropck_outlives.rs b/src/librustc/traits/query/dropck_outlives.rs
index 93f56804a9f..785b4122d08 100644
--- a/src/librustc/traits/query/dropck_outlives.rs
+++ b/src/librustc/traits/query/dropck_outlives.rs
@@ -79,7 +79,7 @@ impl<'cx, 'tcx> At<'cx, 'tcx> {
     }
 }
 
-#[derive(Clone, Debug, Default, TypeFoldable, Lift)]
+#[derive(Clone, Debug, Default, HashStable, TypeFoldable, Lift)]
 pub struct DropckOutlivesResult<'tcx> {
     pub kinds: Vec<GenericArg<'tcx>>,
     pub overflows: Vec<Ty<'tcx>>,
@@ -114,7 +114,7 @@ impl<'tcx> DropckOutlivesResult<'tcx> {
 
 /// A set of constraints that need to be satisfied in order for
 /// a type to be valid for destruction.
-#[derive(Clone, Debug)]
+#[derive(Clone, Debug, HashStable)]
 pub struct DtorckConstraint<'tcx> {
     /// Types that are required to be alive in order for this
     /// type to be valid for destruction.
@@ -152,15 +152,6 @@ impl<'tcx> FromIterator<DtorckConstraint<'tcx>> for DtorckConstraint<'tcx> {
         result
     }
 }
-impl_stable_hash_for!(struct DropckOutlivesResult<'tcx> {
-    kinds, overflows
-});
-
-impl_stable_hash_for!(struct DtorckConstraint<'tcx> {
-    outlives,
-    dtorck_types,
-    overflows
-});
 
 /// This returns true if the type `ty` is "trivial" for
 /// dropck-outlives -- that is, if it doesn't require any types to
diff --git a/src/librustc/traits/query/method_autoderef.rs b/src/librustc/traits/query/method_autoderef.rs
index 039dea1ffcd..be846287e29 100644
--- a/src/librustc/traits/query/method_autoderef.rs
+++ b/src/librustc/traits/query/method_autoderef.rs
@@ -2,7 +2,7 @@ use rustc_data_structures::sync::Lrc;
 use crate::infer::canonical::{Canonical, QueryResponse};
 use crate::ty::Ty;
 
-#[derive(Debug)]
+#[derive(Debug, HashStable)]
 pub struct CandidateStep<'tcx> {
     pub self_ty: Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>,
     pub autoderefs: usize,
@@ -15,7 +15,7 @@ pub struct CandidateStep<'tcx> {
     pub unsize: bool,
 }
 
-#[derive(Clone, Debug)]
+#[derive(Clone, Debug, HashStable)]
 pub struct MethodAutoderefStepsResult<'tcx> {
     /// The valid autoderef steps that could be find.
     pub steps: Lrc<Vec<CandidateStep<'tcx>>>,
@@ -26,20 +26,8 @@ pub struct MethodAutoderefStepsResult<'tcx> {
     pub reached_recursion_limit: bool,
 }
 
-#[derive(Debug)]
+#[derive(Debug, HashStable)]
 pub struct MethodAutoderefBadTy<'tcx> {
     pub reached_raw_pointer: bool,
     pub ty: Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>,
 }
-
-impl_stable_hash_for!(struct MethodAutoderefBadTy<'tcx> {
-    reached_raw_pointer, ty
-});
-
-impl_stable_hash_for!(struct MethodAutoderefStepsResult<'tcx> {
-    reached_recursion_limit, steps, opt_bad_ty
-});
-
-impl_stable_hash_for!(struct CandidateStep<'tcx> {
-    self_ty, autoderefs, from_unsafe_deref, unsize
-});
diff --git a/src/librustc/traits/query/mod.rs b/src/librustc/traits/query/mod.rs
index f6ea77dc5cc..66683cab959 100644
--- a/src/librustc/traits/query/mod.rs
+++ b/src/librustc/traits/query/mod.rs
@@ -40,7 +40,7 @@ pub type CanonicalTypeOpProvePredicateGoal<'tcx> =
 pub type CanonicalTypeOpNormalizeGoal<'tcx, T> =
     Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::normalize::Normalize<T>>>;
 
-#[derive(Clone, Debug)]
+#[derive(Clone, Debug, HashStable)]
 pub struct NoSolution;
 
 pub type Fallible<T> = Result<T, NoSolution>;
@@ -50,5 +50,3 @@ impl<'tcx> From<TypeError<'tcx>> for NoSolution {
         NoSolution
     }
 }
-
-impl_stable_hash_for!(struct NoSolution { });
diff --git a/src/librustc/traits/query/normalize.rs b/src/librustc/traits/query/normalize.rs
index 30528dcebda..09c7f45c22b 100644
--- a/src/librustc/traits/query/normalize.rs
+++ b/src/librustc/traits/query/normalize.rs
@@ -66,7 +66,7 @@ impl<'cx, 'tcx> At<'cx, 'tcx> {
 }
 
 /// Result from the `normalize_projection_ty` query.
-#[derive(Clone, Debug, TypeFoldable, Lift)]
+#[derive(Clone, Debug, HashStable, TypeFoldable, Lift)]
 pub struct NormalizationResult<'tcx> {
     /// Result of normalization.
     pub normalized_ty: Ty<'tcx>,
@@ -193,7 +193,3 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
         constant.eval(self.infcx.tcx, self.param_env)
     }
 }
-
-impl_stable_hash_for!(struct NormalizationResult<'tcx> {
-    normalized_ty
-});
diff --git a/src/librustc/traits/query/type_op/ascribe_user_type.rs b/src/librustc/traits/query/type_op/ascribe_user_type.rs
index 8b0ee5feed7..ee8b73f86a6 100644
--- a/src/librustc/traits/query/type_op/ascribe_user_type.rs
+++ b/src/librustc/traits/query/type_op/ascribe_user_type.rs
@@ -4,7 +4,7 @@ use crate::hir::def_id::DefId;
 use crate::ty::{ParamEnvAnd, Ty, TyCtxt};
 use crate::ty::subst::UserSubsts;
 
-#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, TypeFoldable, Lift)]
+#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, Lift)]
 pub struct AscribeUserType<'tcx> {
     pub mir_ty: Ty<'tcx>,
     pub def_id: DefId,
@@ -38,9 +38,3 @@ impl<'tcx> super::QueryTypeOp<'tcx> for AscribeUserType<'tcx> {
         tcx.type_op_ascribe_user_type(canonicalized)
     }
 }
-
-impl_stable_hash_for! {
-    struct AscribeUserType<'tcx> {
-        mir_ty, def_id, user_substs
-    }
-}
diff --git a/src/librustc/traits/query/type_op/eq.rs b/src/librustc/traits/query/type_op/eq.rs
index 5086994fbb6..8ea800cced2 100644
--- a/src/librustc/traits/query/type_op/eq.rs
+++ b/src/librustc/traits/query/type_op/eq.rs
@@ -2,7 +2,7 @@ use crate::infer::canonical::{Canonicalized, CanonicalizedQueryResponse};
 use crate::traits::query::Fallible;
 use crate::ty::{ParamEnvAnd, Ty, TyCtxt};
 
-#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, TypeFoldable, Lift)]
+#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, Lift)]
 pub struct Eq<'tcx> {
     pub a: Ty<'tcx>,
     pub b: Ty<'tcx>,
@@ -35,7 +35,3 @@ impl<'tcx> super::QueryTypeOp<'tcx> for Eq<'tcx> {
         tcx.type_op_eq(canonicalized)
     }
 }
-
-impl_stable_hash_for! {
-    struct Eq<'tcx> { a, b }
-}
diff --git a/src/librustc/traits/query/type_op/implied_outlives_bounds.rs b/src/librustc/traits/query/type_op/implied_outlives_bounds.rs
index f97b34f9e9a..6f45d76a8e9 100644
--- a/src/librustc/traits/query/type_op/implied_outlives_bounds.rs
+++ b/src/librustc/traits/query/type_op/implied_outlives_bounds.rs
@@ -3,7 +3,7 @@ use crate::traits::query::outlives_bounds::OutlivesBound;
 use crate::traits::query::Fallible;
 use crate::ty::{ParamEnvAnd, Ty, TyCtxt};
 
-#[derive(Clone, Debug, TypeFoldable, Lift)]
+#[derive(Clone, Debug, HashStable, TypeFoldable, Lift)]
 pub struct ImpliedOutlivesBounds<'tcx> {
     pub ty: Ty<'tcx>,
 }
@@ -39,7 +39,3 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ImpliedOutlivesBounds<'tcx> {
         tcx.implied_outlives_bounds(canonicalized)
     }
 }
-
-impl_stable_hash_for! {
-    struct ImpliedOutlivesBounds<'tcx> { ty }
-}
diff --git a/src/librustc/traits/query/type_op/normalize.rs b/src/librustc/traits/query/type_op/normalize.rs
index 798fc5224cc..f905d5a019e 100644
--- a/src/librustc/traits/query/type_op/normalize.rs
+++ b/src/librustc/traits/query/type_op/normalize.rs
@@ -4,7 +4,7 @@ use crate::traits::query::Fallible;
 use crate::ty::fold::TypeFoldable;
 use crate::ty::{self, Lift, ParamEnvAnd, Ty, TyCtxt};
 
-#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, TypeFoldable, Lift)]
+#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, Lift)]
 pub struct Normalize<T> {
     pub value: T,
 }
@@ -82,9 +82,3 @@ impl Normalizable<'tcx> for ty::FnSig<'tcx> {
         tcx.type_op_normalize_fn_sig(canonicalized)
     }
 }
-
-impl_stable_hash_for! {
-    impl<T> for struct Normalize<T> {
-        value
-    }
-}
diff --git a/src/librustc/traits/query/type_op/outlives.rs b/src/librustc/traits/query/type_op/outlives.rs
index d2a7fdc8946..83d51b6d3eb 100644
--- a/src/librustc/traits/query/type_op/outlives.rs
+++ b/src/librustc/traits/query/type_op/outlives.rs
@@ -3,7 +3,7 @@ use crate::traits::query::dropck_outlives::{DropckOutlivesResult, trivial_dropck
 use crate::traits::query::Fallible;
 use crate::ty::{ParamEnvAnd, Ty, TyCtxt};
 
-#[derive(Copy, Clone, Debug, TypeFoldable, Lift)]
+#[derive(Copy, Clone, Debug, HashStable, TypeFoldable, Lift)]
 pub struct DropckOutlives<'tcx> {
     dropped_ty: Ty<'tcx>,
 }
@@ -53,7 +53,3 @@ impl super::QueryTypeOp<'tcx> for DropckOutlives<'tcx> {
         tcx.dropck_outlives(canonicalized)
     }
 }
-
-impl_stable_hash_for! {
-    struct DropckOutlives<'tcx> { dropped_ty }
-}
diff --git a/src/librustc/traits/query/type_op/prove_predicate.rs b/src/librustc/traits/query/type_op/prove_predicate.rs
index cbf485fcfe0..c0a0cbe9a38 100644
--- a/src/librustc/traits/query/type_op/prove_predicate.rs
+++ b/src/librustc/traits/query/type_op/prove_predicate.rs
@@ -2,7 +2,7 @@ use crate::infer::canonical::{Canonicalized, CanonicalizedQueryResponse};
 use crate::traits::query::Fallible;
 use crate::ty::{ParamEnvAnd, Predicate, TyCtxt};
 
-#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, TypeFoldable, Lift)]
+#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, Lift)]
 pub struct ProvePredicate<'tcx> {
     pub predicate: Predicate<'tcx>,
 }
@@ -44,7 +44,3 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ProvePredicate<'tcx> {
         tcx.type_op_prove_predicate(canonicalized)
     }
 }
-
-impl_stable_hash_for! {
-    struct ProvePredicate<'tcx> { predicate }
-}
diff --git a/src/librustc/traits/query/type_op/subtype.rs b/src/librustc/traits/query/type_op/subtype.rs
index bd53e234a6a..76292f9dea0 100644
--- a/src/librustc/traits/query/type_op/subtype.rs
+++ b/src/librustc/traits/query/type_op/subtype.rs
@@ -2,7 +2,7 @@ use crate::infer::canonical::{Canonicalized, CanonicalizedQueryResponse};
 use crate::traits::query::Fallible;
 use crate::ty::{ParamEnvAnd, Ty, TyCtxt};
 
-#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, TypeFoldable, Lift)]
+#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, Lift)]
 pub struct Subtype<'tcx> {
     pub sub: Ty<'tcx>,
     pub sup: Ty<'tcx>,
@@ -35,7 +35,3 @@ impl<'tcx> super::QueryTypeOp<'tcx> for Subtype<'tcx> {
         tcx.type_op_subtype(canonicalized)
     }
 }
-
-impl_stable_hash_for! {
-    struct Subtype<'tcx> { sub, sup }
-}
diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs
index 608883d609f..ffc94cf2b12 100644
--- a/src/librustc/traits/select.rs
+++ b/src/librustc/traits/select.rs
@@ -367,7 +367,6 @@ enum BuiltinImplConditions<'tcx> {
     Ambiguous,
 }
 
-#[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
 /// The result of trait evaluation. The order is important
 /// here as the evaluation of a list is the maximum of the
 /// evaluations.
@@ -380,6 +379,7 @@ enum BuiltinImplConditions<'tcx> {
 ///     all the "potential success" candidates can potentially succeed,
 ///     so they are noops when unioned with a definite error, and within
 ///     the categories it's easy to see that the unions are correct.
+#[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq, HashStable)]
 pub enum EvaluationResult {
     /// Evaluation successful
     EvaluatedToOk,
@@ -478,21 +478,10 @@ impl EvaluationResult {
     }
 }
 
-impl_stable_hash_for!(enum self::EvaluationResult {
-    EvaluatedToOk,
-    EvaluatedToOkModuloRegions,
-    EvaluatedToAmbig,
-    EvaluatedToUnknown,
-    EvaluatedToRecur,
-    EvaluatedToErr
-});
-
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
 /// Indicates that trait evaluation caused overflow.
+#[derive(Copy, Clone, Debug, PartialEq, Eq, HashStable)]
 pub struct OverflowError;
 
-impl_stable_hash_for!(struct OverflowError {});
-
 impl<'tcx> From<OverflowError> for SelectionError<'tcx> {
     fn from(OverflowError: OverflowError) -> SelectionError<'tcx> {
         SelectionError::Overflow
diff --git a/src/librustc/traits/specialize/specialization_graph.rs b/src/librustc/traits/specialize/specialization_graph.rs
index c64d6748ea9..d945c756f66 100644
--- a/src/librustc/traits/specialize/specialization_graph.rs
+++ b/src/librustc/traits/specialize/specialization_graph.rs
@@ -24,7 +24,7 @@ use crate::util::nodemap::{DefIdMap, FxHashMap};
 ///   parents of a given specializing impl, which is needed for extracting
 ///   default items amongst other things. In the simple "chain" rule, every impl
 ///   has at most one parent.
-#[derive(RustcEncodable, RustcDecodable)]
+#[derive(RustcEncodable, RustcDecodable, HashStable)]
 pub struct Graph {
     // All impls have a parent; the "root" impls have as their parent the `def_id`
     // of the trait.
@@ -535,8 +535,3 @@ impl<'a> HashStable<StableHashingContext<'a>> for Children {
         ich::hash_stable_trait_impls(hcx, hasher, blanket_impls, nonblanket_impls);
     }
 }
-
-impl_stable_hash_for!(struct self::Graph {
-    parent,
-    children
-});
diff --git a/src/librustc/ty/binding.rs b/src/librustc/ty/binding.rs
index 905d7abb782..491e09dff09 100644
--- a/src/librustc/ty/binding.rs
+++ b/src/librustc/ty/binding.rs
@@ -2,7 +2,7 @@ use crate::hir::BindingAnnotation::*;
 use crate::hir::BindingAnnotation;
 use crate::hir::Mutability;
 
-#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)]
+#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy, HashStable)]
 pub enum BindingMode {
     BindByReference(Mutability),
     BindByValue(Mutability),
@@ -20,8 +20,3 @@ impl BindingMode {
         }
     }
 }
-
-impl_stable_hash_for!(enum self::BindingMode {
-    BindByReference(mutability),
-    BindByValue(mutability)
-});
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 031d6f09b44..a54bf5079ca 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -1590,12 +1590,11 @@ rustc_index::newtype_index! {
     /// type -- an idealized representative of "types in general" that we
     /// use for checking generic functions.
     pub struct UniverseIndex {
+        derive [HashStable]
         DEBUG_FORMAT = "U{}",
     }
 }
 
-impl_stable_hash_for!(struct UniverseIndex { private });
-
 impl UniverseIndex {
     pub const ROOT: UniverseIndex = UniverseIndex::from_u32_const(0);
 
@@ -1839,7 +1838,7 @@ bitflags! {
 }
 
 /// Definition of a variant -- a struct's fields or a enum variant.
-#[derive(Debug)]
+#[derive(Debug, HashStable)]
 pub struct VariantDef {
     /// `DefId` that identifies the variant itself.
     /// If this variant belongs to a struct or union, then this is a copy of its `DefId`.
@@ -1848,6 +1847,7 @@ pub struct VariantDef {
     /// If this variant is a struct variant, then this is `None`.
     pub ctor_def_id: Option<DefId>,
     /// Variant or struct name.
+    #[stable_hasher(project(name))]
     pub ident: Ident,
     /// Discriminant of this variant.
     pub discr: VariantDiscr,
@@ -1927,17 +1927,6 @@ impl<'tcx> VariantDef {
     }
 }
 
-impl_stable_hash_for!(struct VariantDef {
-    def_id,
-    ctor_def_id,
-    ident -> (ident.name),
-    discr,
-    fields,
-    ctor_kind,
-    flags,
-    recovered
-});
-
 #[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
 pub enum VariantDiscr {
     /// Explicit value for this variant, i.e., `X = 123`.
@@ -2061,7 +2050,7 @@ impl Into<DataTypeKind> for AdtKind {
 }
 
 bitflags! {
-    #[derive(RustcEncodable, RustcDecodable, Default)]
+    #[derive(RustcEncodable, RustcDecodable, Default, HashStable)]
     pub struct ReprFlags: u8 {
         const IS_C               = 1 << 0;
         const IS_SIMD            = 1 << 1;
@@ -2076,12 +2065,9 @@ bitflags! {
     }
 }
 
-impl_stable_hash_for!(struct ReprFlags {
-    bits
-});
-
 /// Represents the repr options provided by the user,
-#[derive(Copy, Clone, Debug, Eq, PartialEq, RustcEncodable, RustcDecodable, Default)]
+#[derive(Copy, Clone, Debug, Eq, PartialEq, RustcEncodable, RustcDecodable,
+         Default, HashStable)]
 pub struct ReprOptions {
     pub int: Option<attr::IntType>,
     pub align: Option<Align>,
@@ -2089,13 +2075,6 @@ pub struct ReprOptions {
     pub flags: ReprFlags,
 }
 
-impl_stable_hash_for!(struct ReprOptions {
-    align,
-    pack,
-    int,
-    flags
-});
-
 impl ReprOptions {
     pub fn new(tcx: TyCtxt<'_>, did: DefId) -> ReprOptions {
         let mut flags = ReprFlags::empty();
@@ -3439,17 +3418,13 @@ pub struct CrateInherentImpls {
     pub inherent_impls: DefIdMap<Vec<DefId>>,
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
 pub struct SymbolName {
     // FIXME: we don't rely on interning or equality here - better have
     // this be a `&'tcx str`.
     pub name: Symbol
 }
 
-impl_stable_hash_for!(struct self::SymbolName {
-    name
-});
-
 impl SymbolName {
     pub fn new(name: &str) -> SymbolName {
         SymbolName {
diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
index fa22709d66f..07258717cd9 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc/ty/sty.rs
@@ -1204,6 +1204,7 @@ rustc_index::newtype_index! {
     /// is the outer fn.
     ///
     /// [dbi]: http://en.wikipedia.org/wiki/De_Bruijn_index
+    #[derive(HashStable)]
     pub struct DebruijnIndex {
         DEBUG_FORMAT = "DebruijnIndex({})",
         const INNERMOST = 0,
@@ -1379,21 +1380,20 @@ rustc_index::newtype_index! {
     pub struct BoundVar { .. }
 }
 
-#[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 BoundTy {
     pub var: BoundVar,
     pub kind: BoundTyKind,
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug,
+         RustcEncodable, RustcDecodable, HashStable)]
 pub enum BoundTyKind {
     Anon,
     Param(Symbol),
 }
 
-impl_stable_hash_for!(struct BoundTy { var, kind });
-impl_stable_hash_for!(enum self::BoundTyKind { Anon, Param(a) });
-
 impl From<BoundVar> for BoundTy {
     fn from(var: BoundVar) -> Self {
         BoundTy {
@@ -1518,8 +1518,6 @@ impl DebruijnIndex {
     }
 }
 
-impl_stable_hash_for!(struct DebruijnIndex { private });
-
 /// Region utilities
 impl RegionKind {
     /// Is this region named by the user?
diff --git a/src/librustc_mir/Cargo.toml b/src/librustc_mir/Cargo.toml
index daa2617bd9e..9bc6d32b7cb 100644
--- a/src/librustc_mir/Cargo.toml
+++ b/src/librustc_mir/Cargo.toml
@@ -22,6 +22,7 @@ rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_index = { path = "../librustc_index" }
 rustc_errors = { path = "../librustc_errors" }
 rustc_lexer = { path = "../librustc_lexer" }
+rustc_macros = { path = "../librustc_macros" }
 rustc_serialize = { path = "../libserialize", package = "serialize" }
 syntax = { path = "../libsyntax" }
 syntax_pos = { path = "../libsyntax_pos" }
diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs
index 92358ad247e..08640476f7a 100644
--- a/src/librustc_mir/interpret/eval_context.rs
+++ b/src/librustc_mir/interpret/eval_context.rs
@@ -18,6 +18,7 @@ use rustc::mir::interpret::{
     InterpResult, truncate, sign_extend,
 };
 use rustc_data_structures::fx::FxHashMap;
+use rustc_macros::HashStable;
 
 use super::{
     Immediate, Operand, MemPlace, MPlaceTy, Place, PlaceTy, ScalarMaybeUndef,
@@ -93,7 +94,7 @@ pub struct Frame<'mir, 'tcx, Tag=(), Extra=()> {
     pub stmt: usize,
 }
 
-#[derive(Clone, Eq, PartialEq, Debug)] // Miri debug-prints these
+#[derive(Clone, Eq, PartialEq, Debug, HashStable)] // Miri debug-prints these
 pub enum StackPopCleanup {
     /// Jump to the next block in the caller, or cause UB if None (that's a function
     /// that may never return). Also store layout of return place so
@@ -109,15 +110,16 @@ pub enum StackPopCleanup {
 }
 
 /// State of a local variable including a memoized layout
-#[derive(Clone, PartialEq, Eq)]
+#[derive(Clone, PartialEq, Eq, HashStable)]
 pub struct LocalState<'tcx, Tag=(), Id=AllocId> {
     pub value: LocalValue<Tag, Id>,
     /// Don't modify if `Some`, this is only used to prevent computing the layout twice
+    #[stable_hasher(ignore)]
     pub layout: Cell<Option<TyLayout<'tcx>>>,
 }
 
 /// Current value of a local variable
-#[derive(Clone, PartialEq, Eq, Debug)] // Miri debug-prints these
+#[derive(Clone, PartialEq, Eq, Debug, HashStable)] // Miri debug-prints these
 pub enum LocalValue<Tag=(), Id=AllocId> {
     /// This local is not currently alive, and cannot be used at all.
     Dead,
diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs
index 4d2ccdc20da..cfa70164cdc 100644
--- a/src/librustc_mir/interpret/operand.rs
+++ b/src/librustc_mir/interpret/operand.rs
@@ -18,6 +18,7 @@ use super::{
     MemPlace, MPlaceTy, PlaceTy, Place,
 };
 pub use rustc::mir::interpret::ScalarMaybeUndef;
+use rustc_macros::HashStable;
 
 /// An `Immediate` represents a single immediate self-contained Rust value.
 ///
@@ -26,7 +27,7 @@ pub use rustc::mir::interpret::ScalarMaybeUndef;
 /// operations and fat pointers. This idea was taken from rustc's codegen.
 /// In particular, thanks to `ScalarPair`, arithmetic operations and casts can be entirely
 /// defined on `Immediate`, and do not have to work with a `Place`.
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, HashStable)]
 pub enum Immediate<Tag=(), Id=AllocId> {
     Scalar(ScalarMaybeUndef<Tag, Id>),
     ScalarPair(ScalarMaybeUndef<Tag, Id>, ScalarMaybeUndef<Tag, Id>),
@@ -103,7 +104,7 @@ impl<'tcx, Tag> ::std::ops::Deref for ImmTy<'tcx, Tag> {
 /// An `Operand` is the result of computing a `mir::Operand`. It can be immediate,
 /// or still in memory. The latter is an optimization, to delay reading that chunk of
 /// memory and to avoid having to store arbitrary-sized data here.
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, HashStable)]
 pub enum Operand<Tag=(), Id=AllocId> {
     Immediate(Immediate<Tag, Id>),
     Indirect(MemPlace<Tag, Id>),
diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs
index 0bd47edc046..088fbe1695e 100644
--- a/src/librustc_mir/interpret/place.rs
+++ b/src/librustc_mir/interpret/place.rs
@@ -12,6 +12,7 @@ use rustc::ty::layout::{
     self, Size, Align, LayoutOf, TyLayout, HasDataLayout, VariantIdx, PrimitiveExt
 };
 use rustc::ty::TypeFoldable;
+use rustc_macros::HashStable;
 
 use super::{
     GlobalId, AllocId, Allocation, Scalar, InterpResult, Pointer, PointerArithmetic,
@@ -19,7 +20,7 @@ use super::{
     RawConst, Immediate, ImmTy, ScalarMaybeUndef, Operand, OpTy, MemoryKind, LocalValue,
 };
 
-#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
+#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable)]
 pub struct MemPlace<Tag=(), Id=AllocId> {
     /// A place may have an integral pointer for ZSTs, and since it might
     /// be turned back into a reference before ever being dereferenced.
@@ -32,7 +33,7 @@ pub struct MemPlace<Tag=(), Id=AllocId> {
     pub meta: Option<Scalar<Tag, Id>>,
 }
 
-#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
+#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable)]
 pub enum Place<Tag=(), Id=AllocId> {
     /// A place referring to a value allocated in the `Memory` system.
     Ptr(MemPlace<Tag, Id>),
diff --git a/src/librustc_mir/interpret/snapshot.rs b/src/librustc_mir/interpret/snapshot.rs
index 7f3ea0283cd..b460badd1fd 100644
--- a/src/librustc_mir/interpret/snapshot.rs
+++ b/src/librustc_mir/interpret/snapshot.rs
@@ -19,6 +19,7 @@ use rustc::ty::layout::{Align, Size};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_index::vec::IndexVec;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
+use rustc_macros::HashStable;
 use syntax::ast::Mutability;
 use syntax::source_map::Span;
 
@@ -197,21 +198,12 @@ impl_snapshot_for!(enum ScalarMaybeUndef {
     Undef,
 });
 
-impl_stable_hash_for!(struct crate::interpret::MemPlace {
-    ptr,
-    align,
-    meta,
-});
 impl_snapshot_for!(struct MemPlace {
     ptr,
     meta,
     align -> *align, // just copy alignment verbatim
 });
 
-impl_stable_hash_for!(enum crate::interpret::Place {
-    Ptr(mem_place),
-    Local { frame, local },
-});
 impl<'a, Ctx> Snapshot<'a, Ctx> for Place
     where Ctx: SnapshotContext<'a>,
 {
@@ -229,29 +221,16 @@ impl<'a, Ctx> Snapshot<'a, Ctx> for Place
     }
 }
 
-impl_stable_hash_for!(enum crate::interpret::Immediate {
-    Scalar(x),
-    ScalarPair(x, y),
-});
 impl_snapshot_for!(enum Immediate {
     Scalar(s),
     ScalarPair(s, t),
 });
 
-impl_stable_hash_for!(enum crate::interpret::Operand {
-    Immediate(x),
-    Indirect(x),
-});
 impl_snapshot_for!(enum Operand {
     Immediate(v),
     Indirect(m),
 });
 
-impl_stable_hash_for!(enum crate::interpret::LocalValue {
-    Dead,
-    Uninitialized,
-    Live(x),
-});
 impl_snapshot_for!(enum LocalValue {
     Dead,
     Uninitialized,
@@ -314,11 +293,6 @@ impl<'a, Ctx> Snapshot<'a, Ctx> for &'a Allocation
     }
 }
 
-impl_stable_hash_for!(enum crate::interpret::eval_context::StackPopCleanup {
-    Goto { ret, unwind },
-    None { cleanup },
-});
-
 #[derive(Eq, PartialEq)]
 struct FrameSnapshot<'a, 'tcx> {
     instance: ty::Instance<'tcx>,
@@ -383,11 +357,6 @@ impl<'a, 'tcx, Ctx> Snapshot<'a, Ctx> for &'a LocalState<'tcx>
     }
 }
 
-impl_stable_hash_for!(struct LocalState<'tcx> {
-    value,
-    layout -> _,
-});
-
 impl<'b, 'mir, 'tcx> SnapshotContext<'b>
     for Memory<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>
 {
@@ -399,7 +368,10 @@ impl<'b, 'mir, 'tcx> SnapshotContext<'b>
 /// The virtual machine state during const-evaluation at a given point in time.
 /// We assume the `CompileTimeInterpreter` has no interesting extra state that
 /// is worth considering here.
+#[derive(HashStable)]
 struct InterpSnapshot<'mir, 'tcx> {
+    // Not hashing memory: Avoid hashing memory all the time during execution
+    #[stable_hasher(ignore)]
     memory: Memory<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>,
     stack: Vec<Frame<'mir, 'tcx>>,
 }
@@ -434,12 +406,6 @@ impl<'mir, 'tcx> Hash for InterpSnapshot<'mir, 'tcx> {
     }
 }
 
-impl_stable_hash_for!(impl<> for struct InterpSnapshot<'mir, 'tcx> {
-    // Not hashing memory: Avoid hashing memory all the time during execution
-    memory -> _,
-    stack,
-});
-
 impl<'mir, 'tcx> Eq for InterpSnapshot<'mir, 'tcx> {}
 
 impl<'mir, 'tcx> PartialEq for InterpSnapshot<'mir, 'tcx> {