rust/src/librustc/ich/impls_ty.rs

1406 lines
46 KiB
Rust

// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! This module contains `HashStable` implementations for various data types
//! from rustc::ty in no particular order.
use ich::{Fingerprint, StableHashingContext, NodeIdHashingMode};
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey,
StableHasher, StableHasherResult};
use std::cell::RefCell;
use std::hash as std_hash;
use std::mem;
use middle::region;
use infer;
use traits;
use ty;
use mir;
impl<'a, 'gcx, T> HashStable<StableHashingContext<'a>>
for &'gcx ty::List<T>
where T: HashStable<StableHashingContext<'a>> {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
thread_local! {
static CACHE: RefCell<FxHashMap<(usize, usize), Fingerprint>> =
RefCell::new(FxHashMap());
}
let hash = CACHE.with(|cache| {
let key = (self.as_ptr() as usize, self.len());
if let Some(&hash) = cache.borrow().get(&key) {
return hash;
}
let mut hasher = StableHasher::new();
(&self[..]).hash_stable(hcx, &mut hasher);
let hash: Fingerprint = hasher.finish();
cache.borrow_mut().insert(key, hash);
hash
});
hash.hash_stable(hcx, hasher);
}
}
impl<'a, 'gcx, T> ToStableHashKey<StableHashingContext<'a>> for &'gcx ty::List<T>
where T: HashStable<StableHashingContext<'a>>
{
type KeyType = Fingerprint;
#[inline]
fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> Fingerprint {
let mut hasher = StableHasher::new();
let mut hcx: StableHashingContext<'a> = hcx.clone();
self.hash_stable(&mut hcx, &mut hasher);
hasher.finish()
}
}
impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for ty::subst::Kind<'gcx> {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
self.unpack().hash_stable(hcx, hasher);
}
}
impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
for ty::subst::UnpackedKind<'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::subst::UnpackedKind::Lifetime(lt) => lt.hash_stable(hcx, hasher),
ty::subst::UnpackedKind::Type(ty) => ty.hash_stable(hcx, hasher),
}
}
}
impl<'a> HashStable<StableHashingContext<'a>>
for ty::RegionKind {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
mem::discriminant(self).hash_stable(hcx, hasher);
match *self {
ty::ReErased |
ty::ReStatic |
ty::ReEmpty => {
// No variant fields to hash for these ...
}
ty::ReCanonical(c) => {
c.hash_stable(hcx, hasher);
}
ty::ReLateBound(db, ty::BrAnon(i)) => {
db.hash_stable(hcx, hasher);
i.hash_stable(hcx, hasher);
}
ty::ReLateBound(db, ty::BrNamed(def_id, name)) => {
db.hash_stable(hcx, hasher);
def_id.hash_stable(hcx, hasher);
name.hash_stable(hcx, hasher);
}
ty::ReLateBound(db, ty::BrEnv) => {
db.hash_stable(hcx, hasher);
}
ty::ReEarlyBound(ty::EarlyBoundRegion { def_id, index, name }) => {
def_id.hash_stable(hcx, hasher);
index.hash_stable(hcx, hasher);
name.hash_stable(hcx, hasher);
}
ty::ReScope(scope) => {
scope.hash_stable(hcx, hasher);
}
ty::ReFree(ref free_region) => {
free_region.hash_stable(hcx, hasher);
}
ty::ReClosureBound(vid) => {
vid.hash_stable(hcx, hasher);
}
ty::ReLateBound(..) |
ty::ReVar(..) |
ty::RePlaceholder(..) => {
bug!("StableHasher: unexpected region {:?}", *self)
}
}
}
}
impl<'a> HashStable<StableHashingContext<'a>> for ty::RegionVid {
#[inline]
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
self.index().hash_stable(hcx, hasher);
}
}
impl<'gcx> HashStable<StableHashingContext<'gcx>> for ty::CanonicalVar {
#[inline]
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'gcx>,
hasher: &mut StableHasher<W>) {
self.index().hash_stable(hcx, hasher);
}
}
impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
for ty::adjustment::AutoBorrow<'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::adjustment::AutoBorrow::Ref(ref region, mutability) => {
region.hash_stable(hcx, hasher);
mutability.hash_stable(hcx, hasher);
}
ty::adjustment::AutoBorrow::RawPtr(mutability) => {
mutability.hash_stable(hcx, hasher);
}
}
}
}
impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
for ty::adjustment::Adjust<'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::adjustment::Adjust::NeverToAny |
ty::adjustment::Adjust::ReifyFnPointer |
ty::adjustment::Adjust::UnsafeFnPointer |
ty::adjustment::Adjust::ClosureFnPointer |
ty::adjustment::Adjust::MutToConstPointer |
ty::adjustment::Adjust::Unsize => {}
ty::adjustment::Adjust::Deref(ref overloaded) => {
overloaded.hash_stable(hcx, hasher);
}
ty::adjustment::Adjust::Borrow(ref autoref) => {
autoref.hash_stable(hcx, hasher);
}
}
}
}
impl_stable_hash_for!(struct ty::adjustment::Adjustment<'tcx> { kind, target });
impl_stable_hash_for!(struct ty::adjustment::OverloadedDeref<'tcx> { region, mutbl });
impl_stable_hash_for!(struct ty::UpvarBorrow<'tcx> { kind, region });
impl_stable_hash_for!(enum ty::adjustment::AllowTwoPhase {
Yes,
No
});
impl<'gcx> HashStable<StableHashingContext<'gcx>> for ty::adjustment::AutoBorrowMutability {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'gcx>,
hasher: &mut StableHasher<W>) {
mem::discriminant(self).hash_stable(hcx, hasher);
match *self {
ty::adjustment::AutoBorrowMutability::Mutable { ref allow_two_phase_borrow } => {
allow_two_phase_borrow.hash_stable(hcx, hasher);
}
ty::adjustment::AutoBorrowMutability::Immutable => {}
}
}
}
impl_stable_hash_for!(struct ty::UpvarId { var_id, closure_expr_id });
impl_stable_hash_for!(enum ty::BorrowKind {
ImmBorrow,
UniqueImmBorrow,
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!(struct ty::GenSig<'tcx> {
yield_ty,
return_ty
});
impl_stable_hash_for!(struct ty::FnSig<'tcx> {
inputs_and_output,
variadic,
unsafety,
abi
});
impl<'a, 'gcx, T> HashStable<StableHashingContext<'a>> for ty::Binder<T>
where T: HashStable<StableHashingContext<'a>>
{
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
self.skip_binder().hash_stable(hcx, hasher);
}
}
impl_stable_hash_for!(enum ty::ClosureKind { Fn, FnMut, FnOnce });
impl_stable_hash_for!(enum ty::Visibility {
Public,
Restricted(def_id),
Invisible
});
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!(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<'a> HashStable<StableHashingContext<'a>> for ty::AdtFlags {
fn hash_stable<W: StableHasherResult>(&self,
_: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
std_hash::Hash::hash(self, hasher);
}
}
impl<'a> HashStable<StableHashingContext<'a>> for ty::VariantFlags {
fn hash_stable<W: StableHasherResult>(&self,
_: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
std_hash::Hash::hash(self, hasher);
}
}
impl_stable_hash_for!(enum ty::VariantDiscr {
Explicit(def_id),
Relative(distance)
});
impl_stable_hash_for!(struct ty::FieldDef {
did,
ident -> (ident.name),
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!(struct mir::interpret::Pointer {
alloc_id,
offset
});
impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::AllocId {
fn hash_stable<W: StableHasherResult>(
&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>,
) {
ty::tls::with_opt(|tcx| {
trace!("hashing {:?}", *self);
let tcx = tcx.expect("can't hash AllocIds during hir lowering");
let alloc_kind = tcx.alloc_map.lock().get(*self);
alloc_kind.hash_stable(hcx, hasher);
});
}
}
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),
}
}
}
impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::Allocation {
fn hash_stable<W: StableHasherResult>(
&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>,
) {
self.bytes.hash_stable(hcx, hasher);
for reloc in self.relocations.iter() {
reloc.hash_stable(hcx, hasher);
}
self.undef_mask.hash_stable(hcx, hasher);
self.align.hash_stable(hcx, hasher);
self.mutability.hash_stable(hcx, hasher);
}
}
impl_stable_hash_for!(enum ::syntax::ast::Mutability {
Immutable,
Mutable
});
impl<'a> HashStable<StableHashingContext<'a>>
for ::mir::interpret::Scalar {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
use mir::interpret::Scalar::*;
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!(struct ty::Const<'tcx> {
ty,
val
});
impl_stable_hash_for!(struct ::mir::interpret::ConstEvalErr<'tcx> {
span,
stacktrace,
error
});
impl_stable_hash_for!(struct ::mir::interpret::FrameInfo {
span,
lint_root,
location
});
impl_stable_hash_for!(struct ty::ClosureSubsts<'tcx> { substs });
impl_stable_hash_for!(struct ty::GeneratorSubsts<'tcx> { substs });
impl_stable_hash_for!(struct ty::GenericPredicates<'tcx> {
parent,
predicates
});
impl_stable_hash_for!(struct ::mir::interpret::EvalError<'tcx> { kind });
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 |
CheckMatchError |
DerefFunctionPointer |
ExecuteMemory |
OverflowNeg |
RemainderByZero |
DivisionByZero |
GeneratorResumedAfterReturn |
GeneratorResumedAfterPanic |
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);
},
ReferencedConstant(ref err) => err.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)
},
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)
},
MemoryLockViolation {
ptr,
len,
frame,
access,
ref lock,
} => {
ptr.hash_stable(hcx, hasher);
len.hash_stable(hcx, hasher);
frame.hash_stable(hcx, hasher);
access.hash_stable(hcx, hasher);
lock.hash_stable(hcx, hasher)
},
MemoryAcquireConflict {
ptr,
len,
kind,
ref lock,
} => {
ptr.hash_stable(hcx, hasher);
len.hash_stable(hcx, hasher);
kind.hash_stable(hcx, hasher);
lock.hash_stable(hcx, hasher)
},
InvalidMemoryLockRelease {
ptr,
len,
frame,
ref lock,
} => {
ptr.hash_stable(hcx, hasher);
len.hash_stable(hcx, hasher);
frame.hash_stable(hcx, hasher);
lock.hash_stable(hcx, hasher)
},
DeallocatedLockedMemory {
ptr,
ref lock,
} => {
ptr.hash_stable(hcx, hasher);
lock.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!(enum mir::interpret::Lock {
NoLock,
WriteLock(dl),
ReadLock(v)
});
impl_stable_hash_for!(struct mir::interpret::DynamicLifetime {
frame,
region
});
impl_stable_hash_for!(enum mir::interpret::AccessKind {
Read,
Write
});
impl_stable_hash_for!(enum ty::Variance {
Covariant,
Invariant,
Contravariant,
Bivariant
});
impl_stable_hash_for!(enum ty::adjustment::CustomCoerceUnsized {
Struct(index)
});
impl_stable_hash_for!(struct ty::Generics {
parent,
parent_count,
params,
// Reverse map to each param's `index` field, from its `def_id`.
param_def_id_to_index -> _, // Don't hash this
has_self,
has_late_bound_regions,
});
impl_stable_hash_for!(struct ty::GenericParamDef {
name,
def_id,
index,
pure_wrt_drop,
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;
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!(enum ::middle::resolve_lifetime::LifetimeDefOrigin {
Explicit,
InBand
});
impl_stable_hash_for!(enum ::middle::resolve_lifetime::Region {
Static,
EarlyBound(index, decl, is_in_band),
LateBound(db_index, decl, is_in_band),
LateBoundAnon(db_index, anon_index),
Free(call_site_scope_data, decl)
});
impl_stable_hash_for!(enum ty::cast::CastKind {
CoercionCast,
PtrPtrCast,
PtrAddrCast,
AddrPtrCast,
NumericCast,
EnumCast,
PrimIntCast,
U8CharCast,
ArrayPtrCast,
FnPtrPtrCast,
FnPtrAddrCast
});
impl_stable_hash_for!(struct ::middle::region::Scope { id, data });
impl_stable_hash_for!(enum ::middle::region::ScopeData {
Node,
CallSite,
Arguments,
Destruction,
Remainder(first_statement_index)
});
impl<'a> ToStableHashKey<StableHashingContext<'a>> for region::Scope {
type KeyType = region::Scope;
#[inline]
fn to_stable_hash_key(&self, _: &StableHashingContext<'a>) -> region::Scope {
*self
}
}
impl_stable_hash_for!(struct ty::adjustment::CoerceUnsizedInfo {
custom_kind
});
impl_stable_hash_for!(struct ty::FreeRegion {
scope,
bound_region
});
impl_stable_hash_for!(enum ty::BoundRegion {
BrAnon(index),
BrNamed(def_id, name),
BrFresh(index),
BrEnv
});
impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
for ty::TyKind<'gcx>
{
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
use ty::TyKind::*;
mem::discriminant(self).hash_stable(hcx, hasher);
match *self {
Bool |
Char |
Str |
Error |
Never => {
// Nothing more to hash.
}
Int(int_ty) => {
int_ty.hash_stable(hcx, hasher);
}
Uint(uint_ty) => {
uint_ty.hash_stable(hcx, hasher);
}
Float(float_ty) => {
float_ty.hash_stable(hcx, hasher);
}
Adt(adt_def, substs) => {
adt_def.hash_stable(hcx, hasher);
substs.hash_stable(hcx, hasher);
}
Array(inner_ty, len) => {
inner_ty.hash_stable(hcx, hasher);
len.hash_stable(hcx, hasher);
}
Slice(inner_ty) => {
inner_ty.hash_stable(hcx, hasher);
}
RawPtr(pointee_ty) => {
pointee_ty.hash_stable(hcx, hasher);
}
Ref(region, pointee_ty, mutbl) => {
region.hash_stable(hcx, hasher);
pointee_ty.hash_stable(hcx, hasher);
mutbl.hash_stable(hcx, hasher);
}
FnDef(def_id, substs) => {
def_id.hash_stable(hcx, hasher);
substs.hash_stable(hcx, hasher);
}
FnPtr(ref sig) => {
sig.hash_stable(hcx, hasher);
}
Dynamic(ref existential_predicates, region) => {
existential_predicates.hash_stable(hcx, hasher);
region.hash_stable(hcx, hasher);
}
Closure(def_id, closure_substs) => {
def_id.hash_stable(hcx, hasher);
closure_substs.hash_stable(hcx, hasher);
}
Generator(def_id, generator_substs, movability) => {
def_id.hash_stable(hcx, hasher);
generator_substs.hash_stable(hcx, hasher);
movability.hash_stable(hcx, hasher);
}
GeneratorWitness(types) => {
types.hash_stable(hcx, hasher)
}
Tuple(inner_tys) => {
inner_tys.hash_stable(hcx, hasher);
}
Projection(ref data) | UnnormalizedProjection(ref data) => {
data.hash_stable(hcx, hasher);
}
Opaque(def_id, substs) => {
def_id.hash_stable(hcx, hasher);
substs.hash_stable(hcx, hasher);
}
Param(param_ty) => {
param_ty.hash_stable(hcx, hasher);
}
Foreign(def_id) => {
def_id.hash_stable(hcx, hasher);
}
Infer(infer_ty) => {
infer_ty.hash_stable(hcx, hasher);
}
}
}
}
impl_stable_hash_for!(enum ty::InferTy {
TyVar(a),
IntVar(a),
FloatVar(a),
FreshTy(a),
FreshIntTy(a),
FreshFloatTy(a),
CanonicalTy(a),
});
impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
for ty::TyVid
{
fn hash_stable<W: StableHasherResult>(&self,
_hcx: &mut StableHashingContext<'a>,
_hasher: &mut StableHasher<W>) {
// TyVid values are confined to an inference context and hence
// should not be hashed.
bug!("ty::TyKind::hash_stable() - can't hash a TyVid {:?}.", *self)
}
}
impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
for ty::IntVid
{
fn hash_stable<W: StableHasherResult>(&self,
_hcx: &mut StableHashingContext<'a>,
_hasher: &mut StableHasher<W>) {
// IntVid values are confined to an inference context and hence
// should not be hashed.
bug!("ty::TyKind::hash_stable() - can't hash an IntVid {:?}.", *self)
}
}
impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
for ty::FloatVid
{
fn hash_stable<W: StableHasherResult>(&self,
_hcx: &mut StableHashingContext<'a>,
_hasher: &mut StableHasher<W>) {
// FloatVid values are confined to an inference context and hence
// should not be hashed.
bug!("ty::TyKind::hash_stable() - can't hash a FloatVid {:?}.", *self)
}
}
impl_stable_hash_for!(struct ty::ParamTy {
idx,
name
});
impl_stable_hash_for!(struct ty::TypeAndMut<'tcx> {
ty,
mutbl
});
impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
for ty::ExistentialPredicate<'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::ExistentialPredicate::Trait(ref trait_ref) => {
trait_ref.hash_stable(hcx, hasher);
}
ty::ExistentialPredicate::Projection(ref projection) => {
projection.hash_stable(hcx, hasher);
}
ty::ExistentialPredicate::AutoTrait(def_id) => {
def_id.hash_stable(hcx, hasher);
}
}
}
}
impl_stable_hash_for!(struct ty::ExistentialTraitRef<'tcx> {
def_id,
substs
});
impl_stable_hash_for!(struct ty::ExistentialProjection<'tcx> {
item_def_id,
substs,
ty
});
impl_stable_hash_for!(struct ty::Instance<'tcx> {
def,
substs
});
impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for ty::InstanceDef<'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::InstanceDef::Item(def_id) => {
def_id.hash_stable(hcx, hasher);
}
ty::InstanceDef::Intrinsic(def_id) => {
def_id.hash_stable(hcx, hasher);
}
ty::InstanceDef::FnPtrShim(def_id, ty) => {
def_id.hash_stable(hcx, hasher);
ty.hash_stable(hcx, hasher);
}
ty::InstanceDef::Virtual(def_id, n) => {
def_id.hash_stable(hcx, hasher);
n.hash_stable(hcx, hasher);
}
ty::InstanceDef::ClosureOnceShim { call_once } => {
call_once.hash_stable(hcx, hasher);
}
ty::InstanceDef::DropGlue(def_id, ty) => {
def_id.hash_stable(hcx, hasher);
ty.hash_stable(hcx, hasher);
}
ty::InstanceDef::CloneShim(def_id, ty) => {
def_id.hash_stable(hcx, hasher);
ty.hash_stable(hcx, hasher);
}
}
}
}
impl_stable_hash_for!(struct ty::TraitDef {
// We already have the def_path_hash below, no need to hash it twice
def_id -> _,
unsafety,
paren_sugar,
has_auto_impl,
is_marker,
def_path_hash,
});
impl_stable_hash_for!(struct ty::Destructor {
did
});
impl_stable_hash_for!(struct ty::CrateVariancesMap {
variances,
// This is just an irrelevant helper value.
empty_variance -> _,
});
impl_stable_hash_for!(struct ty::CratePredicatesMap<'tcx> {
predicates,
// This is just an irrelevant helper value.
empty_predicate -> _,
});
impl_stable_hash_for!(struct ty::AssociatedItem {
def_id,
ident -> (ident.name),
kind,
vis,
defaultness,
container,
method_has_self_argument
});
impl_stable_hash_for!(enum ty::AssociatedKind {
Const,
Method,
Existential,
Type
});
impl_stable_hash_for!(enum ty::AssociatedItemContainer {
TraitContainer(def_id),
ImplContainer(def_id)
});
impl<'a, 'gcx, T> HashStable<StableHashingContext<'a>>
for ty::steal::Steal<T>
where T: HashStable<StableHashingContext<'a>>
{
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
self.borrow().hash_stable(hcx, hasher);
}
}
impl_stable_hash_for!(struct ty::ParamEnv<'tcx> {
caller_bounds,
reveal
});
impl_stable_hash_for!(enum traits::Reveal {
UserFacing,
All
});
impl_stable_hash_for!(enum ::middle::privacy::AccessLevel {
ReachableFromImplTrait,
Reachable,
Exported,
Public
});
impl<'a> HashStable<StableHashingContext<'a>>
for ::middle::privacy::AccessLevels {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
let ::middle::privacy::AccessLevels {
ref map
} = *self;
map.hash_stable(hcx, hasher);
});
}
}
impl_stable_hash_for!(struct ty::CrateInherentImpls {
inherent_impls
});
impl_stable_hash_for!(enum ::session::CompileIncomplete {
Stopped,
Errored(error_reported)
});
impl_stable_hash_for!(struct ::util::common::ErrorReported {});
impl_stable_hash_for!(tuple_struct ::middle::reachable::ReachableSet {
reachable_set
});
impl<'a, 'gcx, N> HashStable<StableHashingContext<'a>>
for traits::Vtable<'gcx, N> where N: HashStable<StableHashingContext<'a>> {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
use traits::Vtable::*;
mem::discriminant(self).hash_stable(hcx, hasher);
match self {
&VtableImpl(ref table_impl) => table_impl.hash_stable(hcx, hasher),
&VtableAutoImpl(ref table_def_impl) => table_def_impl.hash_stable(hcx, hasher),
&VtableParam(ref table_param) => table_param.hash_stable(hcx, hasher),
&VtableObject(ref table_obj) => table_obj.hash_stable(hcx, hasher),
&VtableBuiltin(ref table_builtin) => table_builtin.hash_stable(hcx, hasher),
&VtableClosure(ref table_closure) => table_closure.hash_stable(hcx, hasher),
&VtableFnPointer(ref table_fn_pointer) => table_fn_pointer.hash_stable(hcx, hasher),
&VtableGenerator(ref table_generator) => table_generator.hash_stable(hcx, hasher),
}
}
}
impl<'a, 'gcx, N> HashStable<StableHashingContext<'a>>
for traits::VtableImplData<'gcx, N> where N: HashStable<StableHashingContext<'a>> {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
let traits::VtableImplData {
impl_def_id,
substs,
ref nested,
} = *self;
impl_def_id.hash_stable(hcx, hasher);
substs.hash_stable(hcx, hasher);
nested.hash_stable(hcx, hasher);
}
}
impl<'a, 'gcx, N> HashStable<StableHashingContext<'a>>
for traits::VtableAutoImplData<N> where N: HashStable<StableHashingContext<'a>> {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
let traits::VtableAutoImplData {
trait_def_id,
ref nested,
} = *self;
trait_def_id.hash_stable(hcx, hasher);
nested.hash_stable(hcx, hasher);
}
}
impl<'a, 'gcx, N> HashStable<StableHashingContext<'a>>
for traits::VtableObjectData<'gcx, N> where N: HashStable<StableHashingContext<'a>> {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
let traits::VtableObjectData {
upcast_trait_ref,
vtable_base,
ref nested,
} = *self;
upcast_trait_ref.hash_stable(hcx, hasher);
vtable_base.hash_stable(hcx, hasher);
nested.hash_stable(hcx, hasher);
}
}
impl<'a, 'gcx, N> HashStable<StableHashingContext<'a>>
for traits::VtableBuiltinData<N> where N: HashStable<StableHashingContext<'a>> {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
let traits::VtableBuiltinData {
ref nested,
} = *self;
nested.hash_stable(hcx, hasher);
}
}
impl<'a, 'gcx, N> HashStable<StableHashingContext<'a>>
for traits::VtableClosureData<'gcx, N> where N: HashStable<StableHashingContext<'a>> {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
let traits::VtableClosureData {
closure_def_id,
substs,
ref nested,
} = *self;
closure_def_id.hash_stable(hcx, hasher);
substs.hash_stable(hcx, hasher);
nested.hash_stable(hcx, hasher);
}
}
impl<'a, 'gcx, N> HashStable<StableHashingContext<'a>>
for traits::VtableFnPointerData<'gcx, N> where N: HashStable<StableHashingContext<'a>> {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
let traits::VtableFnPointerData {
fn_ty,
ref nested,
} = *self;
fn_ty.hash_stable(hcx, hasher);
nested.hash_stable(hcx, hasher);
}
}
impl<'a, 'gcx, N> HashStable<StableHashingContext<'a>>
for traits::VtableGeneratorData<'gcx, N> where N: HashStable<StableHashingContext<'a>> {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
let traits::VtableGeneratorData {
generator_def_id,
substs,
ref nested,
} = *self;
generator_def_id.hash_stable(hcx, hasher);
substs.hash_stable(hcx, hasher);
nested.hash_stable(hcx, hasher);
}
}
impl_stable_hash_for!(
impl<'tcx, V> for struct infer::canonical::Canonical<'tcx, V> {
variables, value
}
);
impl_stable_hash_for!(
impl<'tcx> for struct infer::canonical::CanonicalVarValues<'tcx> {
var_values
}
);
impl_stable_hash_for!(struct infer::canonical::CanonicalVarInfo {
kind
});
impl_stable_hash_for!(enum infer::canonical::CanonicalVarKind {
Ty(k),
Region
});
impl_stable_hash_for!(enum infer::canonical::CanonicalTyVarKind {
General,
Int,
Float
});
impl_stable_hash_for!(
impl<'tcx, R> for struct infer::canonical::QueryResult<'tcx, R> {
var_values, region_constraints, certainty, value
}
);
impl_stable_hash_for!(enum infer::canonical::Certainty {
Proven, Ambiguous
});
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for traits::WhereClause<'tcx> {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
use traits::WhereClause::*;
mem::discriminant(self).hash_stable(hcx, hasher);
match self {
Implemented(trait_ref) => trait_ref.hash_stable(hcx, hasher),
ProjectionEq(projection) => projection.hash_stable(hcx, hasher),
TypeOutlives(ty_outlives) => ty_outlives.hash_stable(hcx, hasher),
RegionOutlives(region_outlives) => region_outlives.hash_stable(hcx, hasher),
}
}
}
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for traits::WellFormed<'tcx> {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
use traits::WellFormed::*;
mem::discriminant(self).hash_stable(hcx, hasher);
match self {
Trait(trait_ref) => trait_ref.hash_stable(hcx, hasher),
Ty(ty) => ty.hash_stable(hcx, hasher),
}
}
}
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for traits::FromEnv<'tcx> {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
use traits::FromEnv::*;
mem::discriminant(self).hash_stable(hcx, hasher);
match self {
Trait(trait_ref) => trait_ref.hash_stable(hcx, hasher),
Ty(ty) => ty.hash_stable(hcx, hasher),
}
}
}
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for traits::DomainGoal<'tcx> {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
use traits::DomainGoal::*;
mem::discriminant(self).hash_stable(hcx, hasher);
match self {
Holds(wc) => wc.hash_stable(hcx, hasher),
WellFormed(wf) => wf.hash_stable(hcx, hasher),
FromEnv(from_env) => from_env.hash_stable(hcx, hasher),
Normalize(projection) => projection.hash_stable(hcx, hasher),
}
}
}
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for traits::Goal<'tcx> {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
use traits::GoalKind::*;
mem::discriminant(self).hash_stable(hcx, hasher);
match self {
Implies(hypotheses, goal) => {
hypotheses.hash_stable(hcx, hasher);
goal.hash_stable(hcx, hasher);
},
And(goal1, goal2) => {
goal1.hash_stable(hcx, hasher);
goal2.hash_stable(hcx, hasher);
}
Not(goal) => goal.hash_stable(hcx, hasher),
DomainGoal(domain_goal) => domain_goal.hash_stable(hcx, hasher),
Quantified(quantifier, goal) => {
quantifier.hash_stable(hcx, hasher);
goal.hash_stable(hcx, hasher);
},
CannotProve => { },
}
}
}
impl_stable_hash_for!(
impl<'tcx> for struct traits::ProgramClause<'tcx> {
goal, hypotheses
}
);
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for traits::Clause<'tcx> {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
use traits::Clause::*;
mem::discriminant(self).hash_stable(hcx, hasher);
match self {
Implies(clause) => clause.hash_stable(hcx, hasher),
ForAll(clause) => clause.hash_stable(hcx, hasher),
}
}
}
impl_stable_hash_for!(enum traits::QuantifierKind {
Universal,
Existential
});