未验证 提交 7921572a 编写于 作者: K kennytm

Rollup merge of #55722 - RalfJung:impl-stable-hash, r=varkor

impl_stable_hash_for: support enums and tuple structs with generic parameters

Port a bunch of implementations over to the macro, now that that is possible.
......@@ -37,68 +37,31 @@
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]
......
......@@ -224,20 +224,10 @@ fn hash_stable<W: StableHasherResult>(&self,
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 @@ fn hash_stable<W: StableHasherResult>(&self,
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 @@ fn hash_stable<W: StableHasherResult>(&self,
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 @@ fn hash_stable<W: StableHasherResult>(
}
}
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 @@ fn hash_stable<W: StableHasherResult>(
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 @@ fn hash_stable<W: StableHasherResult>(
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 @@ fn hash_stable<W: StableHasherResult>(&self,
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<'tcx, V> for struct infer::canonical::Canonical<'tcx, V> {
);
impl_stable_hash_for!(
impl<'tcx> for struct infer::canonical::CanonicalVarValues<'tcx> {
struct infer::canonical::CanonicalVarValues<'tcx> {
var_values
}
);
......@@ -1369,7 +1193,7 @@ fn hash_stable<W: StableHasherResult>(&self,
}
impl_stable_hash_for!(
impl<'tcx> for struct traits::ProgramClause<'tcx> {
struct traits::ProgramClause<'tcx> {
goal, hypotheses, category
}
);
......@@ -1404,7 +1228,7 @@ fn hash_stable<W: StableHasherResult>(&self,
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,
}
);
......@@ -71,6 +71,7 @@ pub fn from_u32(u: u32) -> Option<$name> {
#[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 {
......@@ -81,12 +82,37 @@ pub fn from_u32(u: u32) -> Option<$name> {
$( { $($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 {
......@@ -100,9 +126,20 @@ fn hash_stable<W: ::rustc_data_structures::stable_hasher::StableHasherResult>(&s
}
}
};
// 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>,
......@@ -115,26 +152,17 @@ fn hash_stable<W: ::rustc_data_structures::stable_hasher::StableHasherResult>(&s
}
}
};
// 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>>),*
{
......@@ -142,9 +170,9 @@ impl<'a, $tcx, $($lt $(: $lt_bound)*,)* $($T,)*>
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)*) );*
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册