about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/ich/impls_mir.rs71
-rw-r--r--src/librustc/ich/impls_ty.rs426
-rw-r--r--src/librustc/macros.rs72
3 files changed, 192 insertions, 377 deletions
diff --git a/src/librustc/ich/impls_mir.rs b/src/librustc/ich/impls_mir.rs
index a73fe2b8a1a..c42c19e82c7 100644
--- a/src/librustc/ich/impls_mir.rs
+++ b/src/librustc/ich/impls_mir.rs
@@ -37,68 +37,31 @@ impl_stable_hash_for!(struct mir::BasicBlockData<'tcx> { statements, terminator,
 impl_stable_hash_for!(struct mir::UnsafetyViolation { source_info, description, details, kind });
 impl_stable_hash_for!(struct mir::UnsafetyCheckResult { violations, unsafe_blocks });
 
-impl<'a> HashStable<StableHashingContext<'a>>
-for mir::BorrowKind {
-    #[inline]
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        mem::discriminant(self).hash_stable(hcx, hasher);
-
-        match *self {
-            mir::BorrowKind::Shared |
-            mir::BorrowKind::Shallow |
-            mir::BorrowKind::Unique => {}
-            mir::BorrowKind::Mut { allow_two_phase_borrow } => {
-                allow_two_phase_borrow.hash_stable(hcx, hasher);
-            }
-        }
-    }
-}
-
-
-impl<'a> HashStable<StableHashingContext<'a>>
-for mir::UnsafetyViolationKind {
-    #[inline]
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-
-        mem::discriminant(self).hash_stable(hcx, hasher);
-
-        match *self {
-            mir::UnsafetyViolationKind::General => {}
-            mir::UnsafetyViolationKind::MinConstFn => {}
-            mir::UnsafetyViolationKind::ExternStatic(lint_node_id) |
-            mir::UnsafetyViolationKind::BorrowPacked(lint_node_id) => {
-                lint_node_id.hash_stable(hcx, hasher);
-            }
+impl_stable_hash_for!(enum mir::BorrowKind {
+    Shared,
+    Shallow,
+    Unique,
+    Mut { allow_two_phase_borrow },
+});
 
-        }
-    }
-}
+impl_stable_hash_for!(enum mir::UnsafetyViolationKind {
+    General,
+    MinConstFn,
+    ExternStatic(lint_node_id),
+    BorrowPacked(lint_node_id),
+});
 
 impl_stable_hash_for!(struct mir::Terminator<'tcx> {
     kind,
     source_info
 });
 
-impl<'a, 'gcx, T> HashStable<StableHashingContext<'a>> for mir::ClearCrossCrate<T>
-    where T: HashStable<StableHashingContext<'a>>
-{
-    #[inline]
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        mem::discriminant(self).hash_stable(hcx, hasher);
-        match *self {
-            mir::ClearCrossCrate::Clear => {}
-            mir::ClearCrossCrate::Set(ref value) => {
-                value.hash_stable(hcx, hasher);
-            }
-        }
+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]
diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs
index 7d25ecedb4e..f3a62975dd9 100644
--- a/src/librustc/ich/impls_ty.rs
+++ b/src/librustc/ich/impls_ty.rs
@@ -224,20 +224,10 @@ impl_stable_hash_for!(enum ty::BorrowKind {
     MutBorrow
 });
 
-impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
-for ty::UpvarCapture<'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::UpvarCapture::ByValue => {}
-            ty::UpvarCapture::ByRef(ref up_var_borrow) => {
-                up_var_borrow.hash_stable(hcx, hasher);
-            }
-        }
-    }
-}
+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,
@@ -272,64 +262,23 @@ impl_stable_hash_for!(enum ty::Visibility {
 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<'a, 'gcx, A, B> HashStable<StableHashingContext<'a>>
-for ty::OutlivesPredicate<A, B>
-    where A: HashStable<StableHashingContext<'a>>,
-          B: HashStable<StableHashingContext<'a>>,
-{
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        let ty::OutlivesPredicate(ref a, ref b) = *self;
-        a.hash_stable(hcx, hasher);
-        b.hash_stable(hcx, hasher);
-    }
-}
-
+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<'a, 'gcx> HashStable<StableHashingContext<'a>> for ty::Predicate<'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::Predicate::Trait(ref pred) => {
-                pred.hash_stable(hcx, hasher);
-            }
-            ty::Predicate::Subtype(ref pred) => {
-                pred.hash_stable(hcx, hasher);
-            }
-            ty::Predicate::RegionOutlives(ref pred) => {
-                pred.hash_stable(hcx, hasher);
-            }
-            ty::Predicate::TypeOutlives(ref pred) => {
-                pred.hash_stable(hcx, hasher);
-            }
-            ty::Predicate::Projection(ref pred) => {
-                pred.hash_stable(hcx, hasher);
-            }
-            ty::Predicate::WellFormed(ty) => {
-                ty.hash_stable(hcx, hasher);
-            }
-            ty::Predicate::ObjectSafe(def_id) => {
-                def_id.hash_stable(hcx, hasher);
-            }
-            ty::Predicate::ClosureKind(def_id, closure_substs, closure_kind) => {
-                def_id.hash_stable(hcx, hasher);
-                closure_substs.hash_stable(hcx, hasher);
-                closure_kind.hash_stable(hcx, hasher);
-            }
-            ty::Predicate::ConstEvaluatable(def_id, substs) => {
-                def_id.hash_stable(hcx, hasher);
-                substs.hash_stable(hcx, hasher);
-            }
-        }
+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,
@@ -358,70 +307,39 @@ impl_stable_hash_for!(struct ty::FieldDef {
     vis,
 });
 
-impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
-for ::mir::interpret::ConstValue<'gcx> {
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        use mir::interpret::ConstValue::*;
-
-        mem::discriminant(self).hash_stable(hcx, hasher);
-
-        match *self {
-            Unevaluated(def_id, substs) => {
-                def_id.hash_stable(hcx, hasher);
-                substs.hash_stable(hcx, hasher);
-            }
-            Scalar(val) => {
-                val.hash_stable(hcx, hasher);
-            }
-            ScalarPair(a, b) => {
-                a.hash_stable(hcx, hasher);
-                b.hash_stable(hcx, hasher);
-            }
-            ByRef(id, alloc, offset) => {
-                id.hash_stable(hcx, hasher);
-                alloc.hash_stable(hcx, hasher);
-                offset.hash_stable(hcx, hasher);
-            }
-        }
+impl_stable_hash_for!(
+    impl<'tcx> for enum mir::interpret::ConstValue<'tcx> [ mir::interpret::ConstValue ] {
+        Unevaluated(def_id, substs),
+        Scalar(val),
+        ScalarPair(a, b),
+        ByRef(id, alloc, offset),
     }
-}
+);
 
-impl<'a, Tag> HashStable<StableHashingContext<'a>>
-for ::mir::interpret::Pointer<Tag>
-where Tag: HashStable<StableHashingContext<'a>>
-{
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        let ::mir::interpret::Pointer { alloc_id, offset, tag } = self;
-        alloc_id.hash_stable(hcx, hasher);
-        offset.hash_stable(hcx, hasher);
-        tag.hash_stable(hcx, hasher);
+impl_stable_hash_for! {
+    impl<Tag> for struct mir::interpret::Pointer<Tag> {
+        alloc_id,
+        offset,
+        tag,
     }
 }
 
-impl<'a, Tag> HashStable<StableHashingContext<'a>>
-for ::mir::interpret::Scalar<Tag>
-where Tag: HashStable<StableHashingContext<'a>>
-{
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        use mir::interpret::Scalar::*;
+impl_stable_hash_for!(
+    impl<Tag> for enum mir::interpret::Scalar<Tag> [ mir::interpret::Scalar ] {
+        Bits { bits, size },
+        Ptr(ptr),
+    }
+);
 
-        mem::discriminant(self).hash_stable(hcx, hasher);
-        match self {
-            Bits { bits, size } => {
-                bits.hash_stable(hcx, hasher);
-                size.hash_stable(hcx, hasher);
-            },
-            Ptr(ptr) => ptr.hash_stable(hcx, hasher),
-        }
+impl_stable_hash_for!(
+    impl<'tcx, M> for enum mir::interpret::AllocType<'tcx, M> [ mir::interpret::AllocType ] {
+        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>(
         &self,
@@ -437,23 +355,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::AllocId {
     }
 }
 
-impl<'a, 'gcx, M: HashStable<StableHashingContext<'a>>> HashStable<StableHashingContext<'a>>
-for mir::interpret::AllocType<'gcx, M> {
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        use mir::interpret::AllocType::*;
-
-        mem::discriminant(self).hash_stable(hcx, hasher);
-
-        match *self {
-            Function(instance) => instance.hash_stable(hcx, hasher),
-            Static(def_id) => def_id.hash_stable(hcx, hasher),
-            Memory(ref mem) => mem.hash_stable(hcx, hasher),
-        }
-    }
-}
-
+// Allocations treat their relocations specially
 impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::Allocation {
     fn hash_stable<W: StableHasherResult>(
         &self,
@@ -485,7 +387,7 @@ impl_stable_hash_for!(enum mir::interpret::ErrorHandled {
     TooGeneric
 });
 
-impl_stable_hash_for!(struct ::mir::interpret::FrameInfo {
+impl_stable_hash_for!(struct mir::interpret::FrameInfo {
     span,
     lint_root,
     location
@@ -499,124 +401,75 @@ impl_stable_hash_for!(struct ty::GenericPredicates<'tcx> {
     predicates
 });
 
-impl<'a, 'gcx, O: HashStable<StableHashingContext<'a>>> HashStable<StableHashingContext<'a>>
-for ::mir::interpret::EvalErrorKind<'gcx, O> {
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        use mir::interpret::EvalErrorKind::*;
-
-        mem::discriminant(&self).hash_stable(hcx, hasher);
-
-        match *self {
-            FunctionArgCountMismatch |
-            DanglingPointerDeref |
-            DoubleFree |
-            InvalidMemoryAccess |
-            InvalidFunctionPointer |
-            InvalidBool |
-            InvalidNullPointerUsage |
-            ReadPointerAsBytes |
-            ReadBytesAsPointer |
-            ReadForeignStatic |
-            InvalidPointerMath |
-            DeadLocal |
-            StackFrameLimitReached |
-            OutOfTls |
-            TlsOutOfBounds |
-            CalledClosureAsFunction |
-            VtableForArgumentlessMethod |
-            ModifiedConstantMemory |
-            AssumptionNotHeld |
-            InlineAsm |
-            ReallocateNonBasePtr |
-            DeallocateNonBasePtr |
-            HeapAllocZeroBytes |
-            Unreachable |
-            ReadFromReturnPointer |
-            UnimplementedTraitSelection |
-            TypeckError |
-            TooGeneric |
-            DerefFunctionPointer |
-            ExecuteMemory |
-            OverflowNeg |
-            RemainderByZero |
-            DivisionByZero |
-            GeneratorResumedAfterReturn |
-            GeneratorResumedAfterPanic |
-            ReferencedConstant |
-            InfiniteLoop => {}
-            ReadUndefBytes(offset) => offset.hash_stable(hcx, hasher),
-            InvalidDiscriminant(val) => val.hash_stable(hcx, hasher),
-            Panic { ref msg, ref file, line, col } => {
-                msg.hash_stable(hcx, hasher);
-                file.hash_stable(hcx, hasher);
-                line.hash_stable(hcx, hasher);
-                col.hash_stable(hcx, hasher);
-            },
-            MachineError(ref err) => err.hash_stable(hcx, hasher),
-            FunctionAbiMismatch(a, b) => {
-                a.hash_stable(hcx, hasher);
-                b.hash_stable(hcx, hasher)
-            },
-            FunctionArgMismatch(a, b) => {
-                a.hash_stable(hcx, hasher);
-                b.hash_stable(hcx, hasher)
-            },
-            FunctionRetMismatch(a, b) => {
-                a.hash_stable(hcx, hasher);
-                b.hash_stable(hcx, hasher)
-            },
-            NoMirFor(ref s) => s.hash_stable(hcx, hasher),
-            UnterminatedCString(ptr) => ptr.hash_stable(hcx, hasher),
-            PointerOutOfBounds {
-                ptr,
-                access,
-                allocation_size,
-            } => {
-                ptr.hash_stable(hcx, hasher);
-                access.hash_stable(hcx, hasher);
-                allocation_size.hash_stable(hcx, hasher)
-            },
-            InvalidBoolOp(bop) => bop.hash_stable(hcx, hasher),
-            Unimplemented(ref s) => s.hash_stable(hcx, hasher),
-            BoundsCheck { ref len, ref index } => {
-                len.hash_stable(hcx, hasher);
-                index.hash_stable(hcx, hasher)
-            },
-            Intrinsic(ref s) => s.hash_stable(hcx, hasher),
-            InvalidChar(c) => c.hash_stable(hcx, hasher),
-            AbiViolation(ref s) => s.hash_stable(hcx, hasher),
-            AlignmentCheckFailed {
-                required,
-                has,
-            } => {
-                required.hash_stable(hcx, hasher);
-                has.hash_stable(hcx, hasher)
-            },
-            ValidationFailure(ref s) => s.hash_stable(hcx, hasher),
-            TypeNotPrimitive(ty) => ty.hash_stable(hcx, hasher),
-            ReallocatedWrongMemoryKind(ref a, ref b) => {
-                a.hash_stable(hcx, hasher);
-                b.hash_stable(hcx, hasher)
-            },
-            DeallocatedWrongMemoryKind(ref a, ref b) => {
-                a.hash_stable(hcx, hasher);
-                b.hash_stable(hcx, hasher)
-            },
-            IncorrectAllocationInformation(a, b, c, d) => {
-                a.hash_stable(hcx, hasher);
-                b.hash_stable(hcx, hasher);
-                c.hash_stable(hcx, hasher);
-                d.hash_stable(hcx, hasher)
-            },
-            Layout(lay) => lay.hash_stable(hcx, hasher),
-            HeapAllocNonPowerOfTwoAlignment(n) => n.hash_stable(hcx, hasher),
-            PathNotFound(ref v) => v.hash_stable(hcx, hasher),
-            Overflow(op) => op.hash_stable(hcx, hasher),
-        }
+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,
+        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, access, 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::Lock {
     NoLock,
@@ -663,47 +516,18 @@ impl_stable_hash_for!(struct ty::GenericParamDef {
     kind
 });
 
-impl<'a> HashStable<StableHashingContext<'a>> for ty::GenericParamDefKind {
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        mem::discriminant(self).hash_stable(hcx, hasher);
-        match *self {
-            ty::GenericParamDefKind::Lifetime => {}
-            ty::GenericParamDefKind::Type {
-                has_default,
-                ref object_lifetime_default,
-                ref synthetic,
-            } => {
-                has_default.hash_stable(hcx, hasher);
-                object_lifetime_default.hash_stable(hcx, hasher);
-                synthetic.hash_stable(hcx, hasher);
-            }
-        }
-    }
-}
-
-impl<'a, 'gcx, T> HashStable<StableHashingContext<'a>>
-for ::middle::resolve_lifetime::Set1<T>
-    where T: HashStable<StableHashingContext<'a>>
-{
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        use middle::resolve_lifetime::Set1;
+impl_stable_hash_for!(enum ty::GenericParamDefKind {
+    Lifetime,
+    Type { has_default, object_lifetime_default, synthetic },
+});
 
-        mem::discriminant(self).hash_stable(hcx, hasher);
-        match *self {
-            Set1::Empty |
-            Set1::Many => {
-                // Nothing to do.
-            }
-            Set1::One(ref value) => {
-                value.hash_stable(hcx, hasher);
-            }
-        }
+impl_stable_hash_for!(
+    impl<T> for enum ::middle::resolve_lifetime::Set1<T> [ ::middle::resolve_lifetime::Set1 ] {
+        Empty,
+        Many,
+        One(value),
     }
-}
+);
 
 impl_stable_hash_for!(enum ::middle::resolve_lifetime::LifetimeDefOrigin {
     ExplicitOrElided,
@@ -1250,7 +1074,7 @@ impl_stable_hash_for!(
 );
 
 impl_stable_hash_for!(
-    impl<'tcx> for struct infer::canonical::CanonicalVarValues<'tcx> {
+    struct infer::canonical::CanonicalVarValues<'tcx> {
         var_values
     }
 );
@@ -1369,7 +1193,7 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for traits::Goal<'tcx> {
 }
 
 impl_stable_hash_for!(
-    impl<'tcx> for struct traits::ProgramClause<'tcx> {
+    struct traits::ProgramClause<'tcx> {
         goal, hypotheses, category
     }
 );
@@ -1404,7 +1228,7 @@ 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!(
-    impl<'tcx> for struct traits::Environment<'tcx> {
+    struct traits::Environment<'tcx> {
         clauses,
     }
 );
diff --git a/src/librustc/macros.rs b/src/librustc/macros.rs
index f21f949c9f5..03b50c46a8b 100644
--- a/src/librustc/macros.rs
+++ b/src/librustc/macros.rs
@@ -81,6 +81,7 @@ macro_rules! __impl_stable_hash_field {
 
 #[macro_export]
 macro_rules! impl_stable_hash_for {
+    // Enums
     // FIXME(mark-i-m): Some of these should be `?` rather than `*`. See the git blame and change
     // them back when `?` is supported again.
     (enum $enum_name:path {
@@ -91,12 +92,37 @@ macro_rules! impl_stable_hash_for {
            $( { $($named_field:ident $(-> $named_delegate:tt)*),* } )*
         ),* $(,)*
     }) => {
-        impl<'a, 'tcx> ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a>> for $enum_name {
+        impl_stable_hash_for!(
+            impl<> for enum $enum_name [ $enum_name ] { $( $variant
+                $( ( $($field $(-> $delegate)*),* ) )*
+                $( { $($named_field $(-> $named_delegate)*),* } )*
+            ),* }
+        );
+    };
+    // We want to use the enum name both in the `impl ... for $enum_name` as well as for
+    // importing all the variants. Unfortunately it seems we have to take the name
+    // twice for this purpose
+    (impl<$($lt:lifetime $(: $lt_bound:lifetime)* ),* $(,)* $($T:ident),* $(,)*>
+        for enum $enum_name:path
+        [ $enum_path:path ]
+    {
+        $( $variant:ident
+           // this incorrectly allows specifying both tuple-like and struct-like fields, as in `Variant(a,b){c,d}`,
+           // when it should be only one or the other
+           $( ( $($field:ident $(-> $delegate:tt)*),* ) )*
+           $( { $($named_field:ident $(-> $named_delegate:tt)*),* } )*
+        ),* $(,)*
+    }) => {
+        impl<'a, $($lt $(: $lt_bound)*,)* $($T,)*>
+            ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a>>
+            for $enum_name
+            where $($T: ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a>>),*
+        {
             #[inline]
             fn hash_stable<W: ::rustc_data_structures::stable_hasher::StableHasherResult>(&self,
                                                   __ctx: &mut $crate::ich::StableHashingContext<'a>,
                                                   __hasher: &mut ::rustc_data_structures::stable_hasher::StableHasher<W>) {
-                use $enum_name::*;
+                use $enum_path::*;
                 ::std::mem::discriminant(self).hash_stable(__ctx, __hasher);
 
                 match *self {
@@ -110,9 +136,20 @@ macro_rules! impl_stable_hash_for {
             }
         }
     };
+    // Structs
     // FIXME(mark-i-m): same here.
     (struct $struct_name:path { $($field:ident $(-> $delegate:tt)*),*  $(,)* }) => {
-        impl<'a, 'tcx> ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a>> for $struct_name {
+        impl_stable_hash_for!(
+            impl<'tcx> for struct $struct_name { $($field $(-> $delegate)*),* }
+        );
+    };
+    (impl<$($lt:lifetime $(: $lt_bound:lifetime)* ),* $(,)* $($T:ident),* $(,)*> for struct $struct_name:path {
+        $($field:ident $(-> $delegate:tt)*),* $(,)*
+    }) => {
+        impl<'a, $($lt $(: $lt_bound)*,)* $($T,)*>
+            ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a>> for $struct_name
+            where $($T: ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a>>),*
+        {
             #[inline]
             fn hash_stable<W: ::rustc_data_structures::stable_hasher::StableHasherResult>(&self,
                                                   __ctx: &mut $crate::ich::StableHashingContext<'a>,
@@ -125,26 +162,17 @@ macro_rules! impl_stable_hash_for {
             }
         }
     };
+    // Tuple structs
+    // We cannot use normale parentheses here, the parser won't allow it
     // FIXME(mark-i-m): same here.
     (tuple_struct $struct_name:path { $($field:ident $(-> $delegate:tt)*),*  $(,)* }) => {
-        impl<'a, 'tcx> ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a>> for $struct_name {
-            #[inline]
-            fn hash_stable<W: ::rustc_data_structures::stable_hasher::StableHasherResult>(&self,
-                                                  __ctx: &mut $crate::ich::StableHashingContext<'a>,
-                                                  __hasher: &mut ::rustc_data_structures::stable_hasher::StableHasher<W>) {
-                let $struct_name (
-                    $(ref $field),*
-                ) = *self;
-
-                $( __impl_stable_hash_field!($field, __ctx, __hasher $(, $delegate)*) );*
-            }
-        }
+        impl_stable_hash_for!(
+            impl<'tcx> for tuple_struct $struct_name { $($field $(-> $delegate)*),* }
+        );
     };
-
-    (impl<$tcx:lifetime $(, $lt:lifetime $(: $lt_bound:lifetime)*)* $(, $T:ident)*> for struct $struct_name:path {
-        $($field:ident $(-> $delegate:tt)*),* $(,)*
-    }) => {
-        impl<'a, $tcx, $($lt $(: $lt_bound)*,)* $($T,)*>
+    (impl<$($lt:lifetime $(: $lt_bound:lifetime)* ),* $(,)* $($T:ident),* $(,)*>
+     for tuple_struct $struct_name:path { $($field:ident $(-> $delegate:tt)*),*  $(,)* }) => {
+        impl<'a, $($lt $(: $lt_bound)*,)* $($T,)*>
             ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a>> for $struct_name
             where $($T: ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a>>),*
         {
@@ -152,9 +180,9 @@ macro_rules! impl_stable_hash_for {
             fn hash_stable<W: ::rustc_data_structures::stable_hasher::StableHasherResult>(&self,
                                                   __ctx: &mut $crate::ich::StableHashingContext<'a>,
                                                   __hasher: &mut ::rustc_data_structures::stable_hasher::StableHasher<W>) {
-                let $struct_name {
+                let $struct_name (
                     $(ref $field),*
-                } = *self;
+                ) = *self;
 
                 $( __impl_stable_hash_field!($field, __ctx, __hasher $(, $delegate)*) );*
             }