]> git.lizzy.rs Git - rust.git/commitdiff
Extend the impl_stable_hash_for! macro for miri.
authorGeoffry Song <goffrie@gmail.com>
Wed, 24 Oct 2018 07:30:27 +0000 (00:30 -0700)
committerGeoffry Song <goffrie@gmail.com>
Fri, 26 Oct 2018 08:07:10 +0000 (01:07 -0700)
src/librustc/macros.rs
src/librustc_mir/interpret/snapshot.rs

index 897e9cc2a381f2305c96a59bc15b3508833637d6..f21f949c9f5cd220d8508c0e95225d1c7e6c6fd0 100644 (file)
@@ -83,7 +83,14 @@ macro_rules! __impl_stable_hash_field {
 macro_rules! impl_stable_hash_for {
     // 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 { $( $variant:ident $( ( $($field:ident $(-> $delegate:tt)*),* ) )* ),* $(,)* }) => {
+    (enum $enum_name: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, 'tcx> ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a>> for $enum_name {
             #[inline]
             fn hash_stable<W: ::rustc_data_structures::stable_hasher::StableHasherResult>(&self,
@@ -94,8 +101,9 @@ fn hash_stable<W: ::rustc_data_structures::stable_hasher::StableHasherResult>(&s
 
                 match *self {
                     $(
-                        $variant $( ( $(ref $field),* ) )* => {
+                        $variant $( ( $(ref $field),* ) )* $( { $(ref $named_field),* } )* => {
                             $($( __impl_stable_hash_field!($field, __ctx, __hasher $(, $delegate)*) );*)*
+                            $($( __impl_stable_hash_field!($named_field, __ctx, __hasher $(, $named_delegate)*) );*)*
                         }
                     )*
                 }
@@ -133,10 +141,11 @@ fn hash_stable<W: ::rustc_data_structures::stable_hasher::StableHasherResult>(&s
         }
     };
 
-    (impl<$tcx:lifetime $(, $T:ident)*> for struct $struct_name:path {
-        $($field:ident),* $(,)*
+    (impl<$tcx:lifetime $(, $lt:lifetime $(: $lt_bound:lifetime)*)* $(, $T:ident)*> for struct $struct_name:path {
+        $($field:ident $(-> $delegate:tt)*),* $(,)*
     }) => {
-        impl<'a, $tcx, $($T,)*> ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a>> for $struct_name
+        impl<'a, $tcx, $($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]
@@ -147,7 +156,7 @@ fn hash_stable<W: ::rustc_data_structures::stable_hasher::StableHasherResult>(&s
                     $(ref $field),*
                 } = *self;
 
-                $( $field.hash_stable(__ctx, __hasher));*
+                $( __impl_stable_hash_field!($field, __ctx, __hasher $(, $delegate)*) );*
             }
         }
     };
index 047a0125f78af968bad83a63ec91696ed517d7f6..cff2288fd8720c3ac04cd97045a105d8617d8d29 100644 (file)
@@ -6,9 +6,8 @@
 // it is not used by the general miri engine, just by CTFE.
 
 use std::hash::{Hash, Hasher};
-use std::mem;
 
-use rustc::ich::{StableHashingContext, StableHashingContextProvider};
+use rustc::ich::StableHashingContextProvider;
 use rustc::mir;
 use rustc::mir::interpret::{
     AllocId, Pointer, Scalar,
@@ -20,7 +19,7 @@
 use rustc::ty::layout::Align;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::indexed_vec::IndexVec;
-use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHasherResult};
+use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use syntax::ast::Mutability;
 use syntax::source_map::Span;
 
@@ -217,23 +216,10 @@ fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
     align -> *align, // just copy alignment verbatim
 });
 
-// Can't use the macro here because that does not support named enum fields.
-impl<'a> HashStable<StableHashingContext<'a>> for Place {
-    fn hash_stable<W: StableHasherResult>(
-        &self, hcx: &mut StableHashingContext<'a>,
-        hasher: &mut StableHasher<W>)
-    {
-        mem::discriminant(self).hash_stable(hcx, hasher);
-        match self {
-            Place::Ptr(mem_place) => mem_place.hash_stable(hcx, hasher),
-
-            Place::Local { frame, local } => {
-                frame.hash_stable(hcx, hasher);
-                local.hash_stable(hcx, hasher);
-            },
-        }
-    }
-}
+impl_stable_hash_for!(enum ::interpret::Place {
+    Ptr(mem_place),
+    Local { frame, local },
+});
 impl<'a, Ctx> Snapshot<'a, Ctx> for Place
     where Ctx: SnapshotContext<'a>,
 {
@@ -317,20 +303,10 @@ fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
     }
 }
 
-// Can't use the macro here because that does not support named enum fields.
-impl<'a> HashStable<StableHashingContext<'a>> for StackPopCleanup {
-    fn hash_stable<W: StableHasherResult>(
-        &self,
-        hcx: &mut StableHashingContext<'a>,
-        hasher: &mut StableHasher<W>)
-    {
-        mem::discriminant(self).hash_stable(hcx, hasher);
-        match self {
-            StackPopCleanup::Goto(ref block) => block.hash_stable(hcx, hasher),
-            StackPopCleanup::None { cleanup } => cleanup.hash_stable(hcx, hasher),
-        }
-    }
-}
+impl_stable_hash_for!(enum ::interpret::eval_context::StackPopCleanup {
+    Goto(block),
+    None { cleanup },
+});
 
 #[derive(Eq, PartialEq)]
 struct FrameSnapshot<'a, 'tcx: 'a> {
@@ -343,28 +319,17 @@ struct FrameSnapshot<'a, 'tcx: 'a> {
     stmt: usize,
 }
 
-// Not using the macro because that does not support types depending on two lifetimes
-impl<'a, 'mir, 'tcx: 'mir> HashStable<StableHashingContext<'a>> for Frame<'mir, 'tcx> {
-    fn hash_stable<W: StableHasherResult>(
-        &self,
-        hcx: &mut StableHashingContext<'a>,
-        hasher: &mut StableHasher<W>) {
-
-        let Frame {
-            mir,
-            instance,
-            span,
-            return_to_block,
-            return_place,
-            locals,
-            block,
-            stmt,
-        } = self;
+impl_stable_hash_for!(impl<'tcx, 'mir: 'tcx> for struct Frame<'mir, 'tcx> {
+    mir,
+    instance,
+    span,
+    return_to_block,
+    return_place -> (return_place.as_ref().map(|r| &**r)),
+    locals,
+    block,
+    stmt,
+});
 
-        (mir, instance, span, return_to_block).hash_stable(hcx, hasher);
-        (return_place.as_ref().map(|r| &**r), locals, block, stmt).hash_stable(hcx, hasher);
-    }
-}
 impl<'a, 'mir, 'tcx, Ctx> Snapshot<'a, Ctx> for &'a Frame<'mir, 'tcx>
     where Ctx: SnapshotContext<'a>,
 {
@@ -443,21 +408,11 @@ fn hash<H: Hasher>(&self, state: &mut H) {
     }
 }
 
-// Not using the macro because we need special handling for `memory`, which the macro
-// does not support at the same time as the extra bounds on the type.
-impl<'a, 'b, 'mir, 'tcx> HashStable<StableHashingContext<'b>>
-    for EvalSnapshot<'a, 'mir, 'tcx>
-{
-    fn hash_stable<W: StableHasherResult>(
-        &self,
-        hcx: &mut StableHashingContext<'b>,
-        hasher: &mut StableHasher<W>)
-    {
-        // Not hashing memory: Avoid hashing memory all the time during execution
-        let EvalSnapshot{ memory: _, stack } = self;
-        stack.hash_stable(hcx, hasher);
-    }
-}
+impl_stable_hash_for!(impl<'tcx, 'b, 'mir> for struct EvalSnapshot<'b, 'mir, 'tcx> {
+    // Not hashing memory: Avoid hashing memory all the time during execution
+    memory -> _,
+    stack,
+});
 
 impl<'a, 'mir, 'tcx> Eq for EvalSnapshot<'a, 'mir, 'tcx>
 {}