Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend the impl_stable_hash_for! macro for miri. #55302

Merged
merged 1 commit into from
Oct 26, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 15 additions & 6 deletions src/librustc/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)*),* } )*
varkor marked this conversation as resolved.
Show resolved Hide resolved
),* $(,)*
}) => {
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,
Expand All @@ -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)*) );*)*
}
)*
}
Expand Down Expand Up @@ -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]
Expand All @@ -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)*) );*
}
}
};
Expand Down
95 changes: 25 additions & 70 deletions src/librustc_mir/interpret/snapshot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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;

Expand Down Expand Up @@ -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>,
{
Expand Down Expand Up @@ -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> {
Expand All @@ -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>,
{
Expand Down Expand Up @@ -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>
{}
Expand Down