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,
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)*) );*)*
}
)*
}
}
};
- (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]
$(ref $field),*
} = *self;
- $( $field.hash_stable(__ctx, __hasher));*
+ $( __impl_stable_hash_field!($field, __ctx, __hasher $(, $delegate)*) );*
}
}
};
// 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,
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;
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>,
{
}
}
-// 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> {
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>,
{
}
}
-// 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>
{}