Rollup merge of #55302 - goffrie:impl-stable-hash, r=varkor
Extend the impl_stable_hash_for! macro for miri. Fixes #54075.
This commit is contained in:
commit
9880e29fa1
@ -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 @@ macro_rules! impl_stable_hash_for {
|
||||
|
||||
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 @@ macro_rules! impl_stable_hash_for {
|
||||
}
|
||||
};
|
||||
|
||||
(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 @@ macro_rules! impl_stable_hash_for {
|
||||
$(ref $field),*
|
||||
} = *self;
|
||||
|
||||
$( $field.hash_stable(__ctx, __hasher));*
|
||||
$( __impl_stable_hash_field!($field, __ctx, __hasher $(, $delegate)*) );*
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -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::{self, TyCtxt};
|
||||
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 @@ impl_snapshot_for!(struct MemPlace {
|
||||
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 @@ impl<'a, Ctx> Snapshot<'a, Ctx> for &'a Allocation
|
||||
}
|
||||
}
|
||||
|
||||
// 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>) {
|
||||
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,
|
||||
});
|
||||
|
||||
let Frame {
|
||||
mir,
|
||||
instance,
|
||||
span,
|
||||
return_to_block,
|
||||
return_place,
|
||||
locals,
|
||||
block,
|
||||
stmt,
|
||||
} = self;
|
||||
|
||||
(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 @@ impl<'a, 'mir, 'tcx> Hash for EvalSnapshot<'a, 'mir, 'tcx>
|
||||
}
|
||||
}
|
||||
|
||||
// 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>
|
||||
{}
|
||||
|
Loading…
Reference in New Issue
Block a user