]> git.lizzy.rs Git - rust.git/blob - src/librustc/ich/impls_ty.rs
cb685f83aba1eb670852fcb33970e6fb4a5a98f8
[rust.git] / src / librustc / ich / impls_ty.rs
1 // Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 //! This module contains `HashStable` implementations for various data types
12 //! from rustc::ty in no particular order.
13
14 use ich::{Fingerprint, StableHashingContext, NodeIdHashingMode};
15 use rustc_data_structures::fx::FxHashMap;
16 use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey,
17                                            StableHasher, StableHasherResult};
18 use std::cell::RefCell;
19 use std::hash as std_hash;
20 use std::mem;
21 use middle::region;
22 use infer;
23 use traits;
24 use ty;
25 use mir;
26
27 impl<'a, 'gcx, T> HashStable<StableHashingContext<'a>>
28 for &'gcx ty::Slice<T>
29     where T: HashStable<StableHashingContext<'a>> {
30     fn hash_stable<W: StableHasherResult>(&self,
31                                           hcx: &mut StableHashingContext<'a>,
32                                           hasher: &mut StableHasher<W>) {
33         thread_local! {
34             static CACHE: RefCell<FxHashMap<(usize, usize), Fingerprint>> =
35                 RefCell::new(FxHashMap());
36         }
37
38         let hash = CACHE.with(|cache| {
39             let key = (self.as_ptr() as usize, self.len());
40             if let Some(&hash) = cache.borrow().get(&key) {
41                 return hash;
42             }
43
44             let mut hasher = StableHasher::new();
45             (&self[..]).hash_stable(hcx, &mut hasher);
46
47             let hash: Fingerprint = hasher.finish();
48             cache.borrow_mut().insert(key, hash);
49             hash
50         });
51
52         hash.hash_stable(hcx, hasher);
53     }
54 }
55
56 impl<'a, 'gcx, T> ToStableHashKey<StableHashingContext<'a>> for &'gcx ty::Slice<T>
57     where T: HashStable<StableHashingContext<'a>>
58 {
59     type KeyType = Fingerprint;
60
61     #[inline]
62     fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> Fingerprint {
63         let mut hasher = StableHasher::new();
64         let mut hcx: StableHashingContext<'a> = hcx.clone();
65         self.hash_stable(&mut hcx, &mut hasher);
66         hasher.finish()
67     }
68 }
69
70 impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for ty::subst::Kind<'gcx> {
71     fn hash_stable<W: StableHasherResult>(&self,
72                                           hcx: &mut StableHashingContext<'a>,
73                                           hasher: &mut StableHasher<W>) {
74         self.unpack().hash_stable(hcx, hasher);
75     }
76 }
77
78 impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
79 for ty::subst::UnpackedKind<'gcx> {
80     fn hash_stable<W: StableHasherResult>(&self,
81                                           hcx: &mut StableHashingContext<'a>,
82                                           hasher: &mut StableHasher<W>) {
83         mem::discriminant(self).hash_stable(hcx, hasher);
84         match self {
85             ty::subst::UnpackedKind::Lifetime(lt) => lt.hash_stable(hcx, hasher),
86             ty::subst::UnpackedKind::Type(ty) => ty.hash_stable(hcx, hasher),
87         }
88     }
89 }
90
91 impl<'a> HashStable<StableHashingContext<'a>>
92 for ty::RegionKind {
93     fn hash_stable<W: StableHasherResult>(&self,
94                                           hcx: &mut StableHashingContext<'a>,
95                                           hasher: &mut StableHasher<W>) {
96         mem::discriminant(self).hash_stable(hcx, hasher);
97         match *self {
98             ty::ReErased |
99             ty::ReStatic |
100             ty::ReEmpty => {
101                 // No variant fields to hash for these ...
102             }
103             ty::ReCanonical(c) => {
104                 c.hash_stable(hcx, hasher);
105             }
106             ty::ReLateBound(db, ty::BrAnon(i)) => {
107                 db.hash_stable(hcx, hasher);
108                 i.hash_stable(hcx, hasher);
109             }
110             ty::ReLateBound(db, ty::BrNamed(def_id, name)) => {
111                 db.hash_stable(hcx, hasher);
112                 def_id.hash_stable(hcx, hasher);
113                 name.hash_stable(hcx, hasher);
114             }
115             ty::ReLateBound(db, ty::BrEnv) => {
116                 db.hash_stable(hcx, hasher);
117             }
118             ty::ReEarlyBound(ty::EarlyBoundRegion { def_id, index, name }) => {
119                 def_id.hash_stable(hcx, hasher);
120                 index.hash_stable(hcx, hasher);
121                 name.hash_stable(hcx, hasher);
122             }
123             ty::ReScope(scope) => {
124                 scope.hash_stable(hcx, hasher);
125             }
126             ty::ReFree(ref free_region) => {
127                 free_region.hash_stable(hcx, hasher);
128             }
129             ty::ReClosureBound(vid) => {
130                 vid.hash_stable(hcx, hasher);
131             }
132             ty::ReLateBound(..) |
133             ty::ReVar(..) |
134             ty::ReSkolemized(..) => {
135                 bug!("StableHasher: unexpected region {:?}", *self)
136             }
137         }
138     }
139 }
140
141 impl<'a> HashStable<StableHashingContext<'a>> for ty::RegionVid {
142     #[inline]
143     fn hash_stable<W: StableHasherResult>(&self,
144                                           hcx: &mut StableHashingContext<'a>,
145                                           hasher: &mut StableHasher<W>) {
146         use rustc_data_structures::indexed_vec::Idx;
147         self.index().hash_stable(hcx, hasher);
148     }
149 }
150
151 impl<'gcx> HashStable<StableHashingContext<'gcx>> for ty::CanonicalVar {
152     #[inline]
153     fn hash_stable<W: StableHasherResult>(&self,
154                                           hcx: &mut StableHashingContext<'gcx>,
155                                           hasher: &mut StableHasher<W>) {
156         use rustc_data_structures::indexed_vec::Idx;
157         self.index().hash_stable(hcx, hasher);
158     }
159 }
160
161 impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
162 for ty::adjustment::AutoBorrow<'gcx> {
163     fn hash_stable<W: StableHasherResult>(&self,
164                                           hcx: &mut StableHashingContext<'a>,
165                                           hasher: &mut StableHasher<W>) {
166         mem::discriminant(self).hash_stable(hcx, hasher);
167         match *self {
168             ty::adjustment::AutoBorrow::Ref(ref region, mutability) => {
169                 region.hash_stable(hcx, hasher);
170                 mutability.hash_stable(hcx, hasher);
171             }
172             ty::adjustment::AutoBorrow::RawPtr(mutability) => {
173                 mutability.hash_stable(hcx, hasher);
174             }
175         }
176     }
177 }
178
179 impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
180 for ty::adjustment::Adjust<'gcx> {
181     fn hash_stable<W: StableHasherResult>(&self,
182                                           hcx: &mut StableHashingContext<'a>,
183                                           hasher: &mut StableHasher<W>) {
184         mem::discriminant(self).hash_stable(hcx, hasher);
185         match *self {
186             ty::adjustment::Adjust::NeverToAny |
187             ty::adjustment::Adjust::ReifyFnPointer |
188             ty::adjustment::Adjust::UnsafeFnPointer |
189             ty::adjustment::Adjust::ClosureFnPointer |
190             ty::adjustment::Adjust::MutToConstPointer |
191             ty::adjustment::Adjust::Unsize => {}
192             ty::adjustment::Adjust::Deref(ref overloaded) => {
193                 overloaded.hash_stable(hcx, hasher);
194             }
195             ty::adjustment::Adjust::Borrow(ref autoref) => {
196                 autoref.hash_stable(hcx, hasher);
197             }
198         }
199     }
200 }
201
202 impl_stable_hash_for!(struct ty::adjustment::Adjustment<'tcx> { kind, target });
203 impl_stable_hash_for!(struct ty::adjustment::OverloadedDeref<'tcx> { region, mutbl });
204 impl_stable_hash_for!(struct ty::UpvarBorrow<'tcx> { kind, region });
205 impl_stable_hash_for!(enum ty::adjustment::AllowTwoPhase {
206     Yes,
207     No
208 });
209
210 impl<'gcx> HashStable<StableHashingContext<'gcx>> for ty::adjustment::AutoBorrowMutability {
211     fn hash_stable<W: StableHasherResult>(&self,
212                                           hcx: &mut StableHashingContext<'gcx>,
213                                           hasher: &mut StableHasher<W>) {
214         mem::discriminant(self).hash_stable(hcx, hasher);
215         match *self {
216             ty::adjustment::AutoBorrowMutability::Mutable { ref allow_two_phase_borrow } => {
217                 allow_two_phase_borrow.hash_stable(hcx, hasher);
218             }
219             ty::adjustment::AutoBorrowMutability::Immutable => {}
220         }
221     }
222 }
223
224 impl_stable_hash_for!(struct ty::UpvarId { var_id, closure_expr_id });
225
226 impl_stable_hash_for!(enum ty::BorrowKind {
227     ImmBorrow,
228     UniqueImmBorrow,
229     MutBorrow
230 });
231
232 impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
233 for ty::UpvarCapture<'gcx> {
234     fn hash_stable<W: StableHasherResult>(&self,
235                                           hcx: &mut StableHashingContext<'a>,
236                                           hasher: &mut StableHasher<W>) {
237         mem::discriminant(self).hash_stable(hcx, hasher);
238         match *self {
239             ty::UpvarCapture::ByValue => {}
240             ty::UpvarCapture::ByRef(ref up_var_borrow) => {
241                 up_var_borrow.hash_stable(hcx, hasher);
242             }
243         }
244     }
245 }
246
247 impl_stable_hash_for!(struct ty::GenSig<'tcx> {
248     yield_ty,
249     return_ty
250 });
251
252 impl_stable_hash_for!(struct ty::FnSig<'tcx> {
253     inputs_and_output,
254     variadic,
255     unsafety,
256     abi
257 });
258
259 impl<'a, 'gcx, T> HashStable<StableHashingContext<'a>> for ty::Binder<T>
260     where T: HashStable<StableHashingContext<'a>>
261 {
262     fn hash_stable<W: StableHasherResult>(&self,
263                                           hcx: &mut StableHashingContext<'a>,
264                                           hasher: &mut StableHasher<W>) {
265         self.skip_binder().hash_stable(hcx, hasher);
266     }
267 }
268
269 impl_stable_hash_for!(enum ty::ClosureKind { Fn, FnMut, FnOnce });
270
271 impl_stable_hash_for!(enum ty::Visibility {
272     Public,
273     Restricted(def_id),
274     Invisible
275 });
276
277 impl_stable_hash_for!(struct ty::TraitRef<'tcx> { def_id, substs });
278 impl_stable_hash_for!(struct ty::TraitPredicate<'tcx> { trait_ref });
279 impl_stable_hash_for!(struct ty::SubtypePredicate<'tcx> { a_is_expected, a, b });
280
281 impl<'a, 'gcx, A, B> HashStable<StableHashingContext<'a>>
282 for ty::OutlivesPredicate<A, B>
283     where A: HashStable<StableHashingContext<'a>>,
284           B: HashStable<StableHashingContext<'a>>,
285 {
286     fn hash_stable<W: StableHasherResult>(&self,
287                                           hcx: &mut StableHashingContext<'a>,
288                                           hasher: &mut StableHasher<W>) {
289         let ty::OutlivesPredicate(ref a, ref b) = *self;
290         a.hash_stable(hcx, hasher);
291         b.hash_stable(hcx, hasher);
292     }
293 }
294
295 impl_stable_hash_for!(struct ty::ProjectionPredicate<'tcx> { projection_ty, ty });
296 impl_stable_hash_for!(struct ty::ProjectionTy<'tcx> { substs, item_def_id });
297
298
299 impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for ty::Predicate<'gcx> {
300     fn hash_stable<W: StableHasherResult>(&self,
301                                           hcx: &mut StableHashingContext<'a>,
302                                           hasher: &mut StableHasher<W>) {
303         mem::discriminant(self).hash_stable(hcx, hasher);
304         match *self {
305             ty::Predicate::Trait(ref pred) => {
306                 pred.hash_stable(hcx, hasher);
307             }
308             ty::Predicate::Subtype(ref pred) => {
309                 pred.hash_stable(hcx, hasher);
310             }
311             ty::Predicate::RegionOutlives(ref pred) => {
312                 pred.hash_stable(hcx, hasher);
313             }
314             ty::Predicate::TypeOutlives(ref pred) => {
315                 pred.hash_stable(hcx, hasher);
316             }
317             ty::Predicate::Projection(ref pred) => {
318                 pred.hash_stable(hcx, hasher);
319             }
320             ty::Predicate::WellFormed(ty) => {
321                 ty.hash_stable(hcx, hasher);
322             }
323             ty::Predicate::ObjectSafe(def_id) => {
324                 def_id.hash_stable(hcx, hasher);
325             }
326             ty::Predicate::ClosureKind(def_id, closure_substs, closure_kind) => {
327                 def_id.hash_stable(hcx, hasher);
328                 closure_substs.hash_stable(hcx, hasher);
329                 closure_kind.hash_stable(hcx, hasher);
330             }
331             ty::Predicate::ConstEvaluatable(def_id, substs) => {
332                 def_id.hash_stable(hcx, hasher);
333                 substs.hash_stable(hcx, hasher);
334             }
335         }
336     }
337 }
338
339 impl<'a> HashStable<StableHashingContext<'a>> for ty::AdtFlags {
340     fn hash_stable<W: StableHasherResult>(&self,
341                                           _: &mut StableHashingContext<'a>,
342                                           hasher: &mut StableHasher<W>) {
343         std_hash::Hash::hash(self, hasher);
344     }
345 }
346
347 impl_stable_hash_for!(struct ty::VariantDef {
348     did,
349     name,
350     discr,
351     fields,
352     ctor_kind
353 });
354
355 impl_stable_hash_for!(enum ty::VariantDiscr {
356     Explicit(def_id),
357     Relative(distance)
358 });
359
360 impl_stable_hash_for!(struct ty::FieldDef {
361     did,
362     ident -> (ident.name),
363     vis,
364 });
365
366 impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
367 for ::mir::interpret::ConstValue<'gcx> {
368     fn hash_stable<W: StableHasherResult>(&self,
369                                           hcx: &mut StableHashingContext<'a>,
370                                           hasher: &mut StableHasher<W>) {
371         use mir::interpret::ConstValue::*;
372
373         mem::discriminant(self).hash_stable(hcx, hasher);
374
375         match *self {
376             Unevaluated(def_id, substs) => {
377                 def_id.hash_stable(hcx, hasher);
378                 substs.hash_stable(hcx, hasher);
379             }
380             Scalar(val) => {
381                 val.hash_stable(hcx, hasher);
382             }
383             ScalarPair(a, b) => {
384                 a.hash_stable(hcx, hasher);
385                 b.hash_stable(hcx, hasher);
386             }
387             ByRef(alloc, offset) => {
388                 alloc.hash_stable(hcx, hasher);
389                 offset.hash_stable(hcx, hasher);
390             }
391         }
392     }
393 }
394
395 impl_stable_hash_for!(enum mir::interpret::Value {
396     Scalar(v),
397     ScalarPair(a, b),
398     ByRef(ptr, align)
399 });
400
401 impl_stable_hash_for!(struct mir::interpret::Pointer {
402     alloc_id,
403     offset
404 });
405
406 impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::AllocId {
407     fn hash_stable<W: StableHasherResult>(
408         &self,
409         hcx: &mut StableHashingContext<'a>,
410         hasher: &mut StableHasher<W>,
411     ) {
412         ty::tls::with_opt(|tcx| {
413             trace!("hashing {:?}", *self);
414             let tcx = tcx.expect("can't hash AllocIds during hir lowering");
415             let alloc_kind = tcx.alloc_map.lock().get(*self).expect("no value for AllocId");
416             alloc_kind.hash_stable(hcx, hasher);
417         });
418     }
419 }
420
421 impl<'a, 'gcx, M: HashStable<StableHashingContext<'a>>> HashStable<StableHashingContext<'a>>
422 for mir::interpret::AllocType<'gcx, M> {
423     fn hash_stable<W: StableHasherResult>(&self,
424                                           hcx: &mut StableHashingContext<'a>,
425                                           hasher: &mut StableHasher<W>) {
426         use mir::interpret::AllocType::*;
427
428         mem::discriminant(self).hash_stable(hcx, hasher);
429
430         match *self {
431             Function(instance) => instance.hash_stable(hcx, hasher),
432             Static(def_id) => def_id.hash_stable(hcx, hasher),
433             Memory(ref mem) => mem.hash_stable(hcx, hasher),
434         }
435     }
436 }
437
438 impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::Allocation {
439     fn hash_stable<W: StableHasherResult>(
440         &self,
441         hcx: &mut StableHashingContext<'a>,
442         hasher: &mut StableHasher<W>,
443     ) {
444         self.bytes.hash_stable(hcx, hasher);
445         for reloc in self.relocations.iter() {
446             reloc.hash_stable(hcx, hasher);
447         }
448         self.undef_mask.hash_stable(hcx, hasher);
449         self.align.hash_stable(hcx, hasher);
450         self.runtime_mutability.hash_stable(hcx, hasher);
451     }
452 }
453
454 impl_stable_hash_for!(enum ::syntax::ast::Mutability {
455     Immutable,
456     Mutable
457 });
458
459
460 impl<'a> HashStable<StableHashingContext<'a>>
461 for ::mir::interpret::Scalar {
462     fn hash_stable<W: StableHasherResult>(&self,
463                                           hcx: &mut StableHashingContext<'a>,
464                                           hasher: &mut StableHasher<W>) {
465         use mir::interpret::Scalar::*;
466
467         mem::discriminant(self).hash_stable(hcx, hasher);
468         match *self {
469             Bits { bits, defined } => {
470                 bits.hash_stable(hcx, hasher);
471                 defined.hash_stable(hcx, hasher);
472             },
473             Ptr(ptr) => ptr.hash_stable(hcx, hasher),
474         }
475     }
476 }
477
478 impl_stable_hash_for!(struct ty::Const<'tcx> {
479     ty,
480     val
481 });
482
483 impl_stable_hash_for!(struct ::mir::interpret::ConstEvalErr<'tcx> {
484     span,
485     stacktrace,
486     error
487 });
488
489 impl_stable_hash_for!(struct ::mir::interpret::FrameInfo {
490     span,
491     lint_root,
492     location
493 });
494
495 impl_stable_hash_for!(struct ty::ClosureSubsts<'tcx> { substs });
496 impl_stable_hash_for!(struct ty::GeneratorSubsts<'tcx> { substs });
497
498 impl_stable_hash_for!(struct ty::GenericPredicates<'tcx> {
499     parent,
500     predicates
501 });
502
503 impl_stable_hash_for!(struct ::mir::interpret::EvalError<'tcx> { kind });
504
505 impl<'a, 'gcx, O: HashStable<StableHashingContext<'a>>> HashStable<StableHashingContext<'a>>
506 for ::mir::interpret::EvalErrorKind<'gcx, O> {
507     fn hash_stable<W: StableHasherResult>(&self,
508                                           hcx: &mut StableHashingContext<'a>,
509                                           hasher: &mut StableHasher<W>) {
510         use mir::interpret::EvalErrorKind::*;
511
512         mem::discriminant(&self).hash_stable(hcx, hasher);
513
514         match *self {
515             DanglingPointerDeref |
516             DoubleFree |
517             InvalidMemoryAccess |
518             InvalidFunctionPointer |
519             InvalidBool |
520             InvalidDiscriminant |
521             InvalidNullPointerUsage |
522             ReadPointerAsBytes |
523             ReadBytesAsPointer |
524             ReadForeignStatic |
525             InvalidPointerMath |
526             ReadUndefBytes |
527             DeadLocal |
528             StackFrameLimitReached |
529             OutOfTls |
530             TlsOutOfBounds |
531             CalledClosureAsFunction |
532             VtableForArgumentlessMethod |
533             ModifiedConstantMemory |
534             AssumptionNotHeld |
535             InlineAsm |
536             ReallocateNonBasePtr |
537             DeallocateNonBasePtr |
538             HeapAllocZeroBytes |
539             Unreachable |
540             Panic |
541             ReadFromReturnPointer |
542             UnimplementedTraitSelection |
543             TypeckError |
544             TooGeneric |
545             CheckMatchError |
546             DerefFunctionPointer |
547             ExecuteMemory |
548             OverflowNeg |
549             RemainderByZero |
550             DivisionByZero |
551             GeneratorResumedAfterReturn |
552             GeneratorResumedAfterPanic |
553             InfiniteLoop => {}
554             ReferencedConstant(ref err) => err.hash_stable(hcx, hasher),
555             MachineError(ref err) => err.hash_stable(hcx, hasher),
556             FunctionPointerTyMismatch(a, b) => {
557                 a.hash_stable(hcx, hasher);
558                 b.hash_stable(hcx, hasher)
559             },
560             NoMirFor(ref s) => s.hash_stable(hcx, hasher),
561             UnterminatedCString(ptr) => ptr.hash_stable(hcx, hasher),
562             PointerOutOfBounds {
563                 ptr,
564                 access,
565                 allocation_size,
566             } => {
567                 ptr.hash_stable(hcx, hasher);
568                 access.hash_stable(hcx, hasher);
569                 allocation_size.hash_stable(hcx, hasher)
570             },
571             InvalidBoolOp(bop) => bop.hash_stable(hcx, hasher),
572             Unimplemented(ref s) => s.hash_stable(hcx, hasher),
573             BoundsCheck { ref len, ref index } => {
574                 len.hash_stable(hcx, hasher);
575                 index.hash_stable(hcx, hasher)
576             },
577             Intrinsic(ref s) => s.hash_stable(hcx, hasher),
578             InvalidChar(c) => c.hash_stable(hcx, hasher),
579             AbiViolation(ref s) => s.hash_stable(hcx, hasher),
580             AlignmentCheckFailed {
581                 required,
582                 has,
583             } => {
584                 required.hash_stable(hcx, hasher);
585                 has.hash_stable(hcx, hasher)
586             },
587             MemoryLockViolation {
588                 ptr,
589                 len,
590                 frame,
591                 access,
592                 ref lock,
593             } =>  {
594                 ptr.hash_stable(hcx, hasher);
595                 len.hash_stable(hcx, hasher);
596                 frame.hash_stable(hcx, hasher);
597                 access.hash_stable(hcx, hasher);
598                 lock.hash_stable(hcx, hasher)
599             },
600             MemoryAcquireConflict {
601                 ptr,
602                 len,
603                 kind,
604                 ref lock,
605             } =>  {
606                 ptr.hash_stable(hcx, hasher);
607                 len.hash_stable(hcx, hasher);
608                 kind.hash_stable(hcx, hasher);
609                 lock.hash_stable(hcx, hasher)
610             },
611             InvalidMemoryLockRelease {
612                 ptr,
613                 len,
614                 frame,
615                 ref lock,
616             } =>  {
617                 ptr.hash_stable(hcx, hasher);
618                 len.hash_stable(hcx, hasher);
619                 frame.hash_stable(hcx, hasher);
620                 lock.hash_stable(hcx, hasher)
621             },
622             DeallocatedLockedMemory {
623                 ptr,
624                 ref lock,
625             } => {
626                 ptr.hash_stable(hcx, hasher);
627                 lock.hash_stable(hcx, hasher)
628             },
629             ValidationFailure(ref s) => s.hash_stable(hcx, hasher),
630             TypeNotPrimitive(ty) => ty.hash_stable(hcx, hasher),
631             ReallocatedWrongMemoryKind(ref a, ref b) => {
632                 a.hash_stable(hcx, hasher);
633                 b.hash_stable(hcx, hasher)
634             },
635             DeallocatedWrongMemoryKind(ref a, ref b) => {
636                 a.hash_stable(hcx, hasher);
637                 b.hash_stable(hcx, hasher)
638             },
639             IncorrectAllocationInformation(a, b, c, d) => {
640                 a.hash_stable(hcx, hasher);
641                 b.hash_stable(hcx, hasher);
642                 c.hash_stable(hcx, hasher);
643                 d.hash_stable(hcx, hasher)
644             },
645             Layout(lay) => lay.hash_stable(hcx, hasher),
646             HeapAllocNonPowerOfTwoAlignment(n) => n.hash_stable(hcx, hasher),
647             PathNotFound(ref v) => v.hash_stable(hcx, hasher),
648             Overflow(op) => op.hash_stable(hcx, hasher),
649         }
650     }
651 }
652
653 impl_stable_hash_for!(enum mir::interpret::Lock {
654     NoLock,
655     WriteLock(dl),
656     ReadLock(v)
657 });
658
659 impl_stable_hash_for!(struct mir::interpret::DynamicLifetime {
660     frame,
661     region
662 });
663
664 impl_stable_hash_for!(enum mir::interpret::AccessKind {
665     Read,
666     Write
667 });
668
669 impl_stable_hash_for!(enum ty::Variance {
670     Covariant,
671     Invariant,
672     Contravariant,
673     Bivariant
674 });
675
676 impl_stable_hash_for!(enum ty::adjustment::CustomCoerceUnsized {
677     Struct(index)
678 });
679
680 impl_stable_hash_for!(struct ty::Generics {
681     parent,
682     parent_count,
683     params,
684     // Reverse map to each param's `index` field, from its `def_id`.
685     param_def_id_to_index -> _, // Don't hash this
686     has_self,
687     has_late_bound_regions,
688 });
689
690 impl_stable_hash_for!(struct ty::GenericParamDef {
691     name,
692     def_id,
693     index,
694     pure_wrt_drop,
695     kind
696 });
697
698 impl<'a> HashStable<StableHashingContext<'a>> for ty::GenericParamDefKind {
699     fn hash_stable<W: StableHasherResult>(&self,
700                                           hcx: &mut StableHashingContext<'a>,
701                                           hasher: &mut StableHasher<W>) {
702         mem::discriminant(self).hash_stable(hcx, hasher);
703         match *self {
704             ty::GenericParamDefKind::Lifetime => {}
705             ty::GenericParamDefKind::Type {
706                 has_default,
707                 ref object_lifetime_default,
708                 ref synthetic,
709             } => {
710                 has_default.hash_stable(hcx, hasher);
711                 object_lifetime_default.hash_stable(hcx, hasher);
712                 synthetic.hash_stable(hcx, hasher);
713             }
714         }
715     }
716 }
717
718 impl<'a, 'gcx, T> HashStable<StableHashingContext<'a>>
719 for ::middle::resolve_lifetime::Set1<T>
720     where T: HashStable<StableHashingContext<'a>>
721 {
722     fn hash_stable<W: StableHasherResult>(&self,
723                                           hcx: &mut StableHashingContext<'a>,
724                                           hasher: &mut StableHasher<W>) {
725         use middle::resolve_lifetime::Set1;
726
727         mem::discriminant(self).hash_stable(hcx, hasher);
728         match *self {
729             Set1::Empty |
730             Set1::Many => {
731                 // Nothing to do.
732             }
733             Set1::One(ref value) => {
734                 value.hash_stable(hcx, hasher);
735             }
736         }
737     }
738 }
739
740 impl_stable_hash_for!(enum ::middle::resolve_lifetime::LifetimeDefOrigin {
741     Explicit,
742     InBand
743 });
744
745 impl_stable_hash_for!(enum ::middle::resolve_lifetime::Region {
746     Static,
747     EarlyBound(index, decl, is_in_band),
748     LateBound(db_index, decl, is_in_band),
749     LateBoundAnon(db_index, anon_index),
750     Free(call_site_scope_data, decl)
751 });
752
753 impl_stable_hash_for!(enum ty::cast::CastKind {
754     CoercionCast,
755     PtrPtrCast,
756     PtrAddrCast,
757     AddrPtrCast,
758     NumericCast,
759     EnumCast,
760     PrimIntCast,
761     U8CharCast,
762     ArrayPtrCast,
763     FnPtrPtrCast,
764     FnPtrAddrCast
765 });
766
767 impl_stable_hash_for!(tuple_struct ::middle::region::FirstStatementIndex { idx });
768 impl_stable_hash_for!(struct ::middle::region::Scope { id, code });
769
770 impl<'a> ToStableHashKey<StableHashingContext<'a>> for region::Scope {
771     type KeyType = region::Scope;
772
773     #[inline]
774     fn to_stable_hash_key(&self, _: &StableHashingContext<'a>) -> region::Scope {
775         *self
776     }
777 }
778
779 impl_stable_hash_for!(struct ::middle::region::BlockRemainder {
780     block,
781     first_statement_index
782 });
783
784 impl_stable_hash_for!(struct ty::adjustment::CoerceUnsizedInfo {
785     custom_kind
786 });
787
788 impl_stable_hash_for!(struct ty::FreeRegion {
789     scope,
790     bound_region
791 });
792
793 impl_stable_hash_for!(enum ty::BoundRegion {
794     BrAnon(index),
795     BrNamed(def_id, name),
796     BrFresh(index),
797     BrEnv
798 });
799
800 impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
801 for ty::TypeVariants<'gcx>
802 {
803     fn hash_stable<W: StableHasherResult>(&self,
804                                           hcx: &mut StableHashingContext<'a>,
805                                           hasher: &mut StableHasher<W>) {
806         use ty::TypeVariants::*;
807
808         mem::discriminant(self).hash_stable(hcx, hasher);
809         match *self {
810             TyBool  |
811             TyChar  |
812             TyStr   |
813             TyError |
814             TyNever => {
815                 // Nothing more to hash.
816             }
817             TyInt(int_ty) => {
818                 int_ty.hash_stable(hcx, hasher);
819             }
820             TyUint(uint_ty) => {
821                 uint_ty.hash_stable(hcx, hasher);
822             }
823             TyFloat(float_ty)  => {
824                 float_ty.hash_stable(hcx, hasher);
825             }
826             TyAdt(adt_def, substs) => {
827                 adt_def.hash_stable(hcx, hasher);
828                 substs.hash_stable(hcx, hasher);
829             }
830             TyArray(inner_ty, len) => {
831                 inner_ty.hash_stable(hcx, hasher);
832                 len.hash_stable(hcx, hasher);
833             }
834             TySlice(inner_ty) => {
835                 inner_ty.hash_stable(hcx, hasher);
836             }
837             TyRawPtr(pointee_ty) => {
838                 pointee_ty.hash_stable(hcx, hasher);
839             }
840             TyRef(region, pointee_ty, mutbl) => {
841                 region.hash_stable(hcx, hasher);
842                 pointee_ty.hash_stable(hcx, hasher);
843                 mutbl.hash_stable(hcx, hasher);
844             }
845             TyFnDef(def_id, substs) => {
846                 def_id.hash_stable(hcx, hasher);
847                 substs.hash_stable(hcx, hasher);
848             }
849             TyFnPtr(ref sig) => {
850                 sig.hash_stable(hcx, hasher);
851             }
852             TyDynamic(ref existential_predicates, region) => {
853                 existential_predicates.hash_stable(hcx, hasher);
854                 region.hash_stable(hcx, hasher);
855             }
856             TyClosure(def_id, closure_substs) => {
857                 def_id.hash_stable(hcx, hasher);
858                 closure_substs.hash_stable(hcx, hasher);
859             }
860             TyGenerator(def_id, generator_substs, movability) => {
861                 def_id.hash_stable(hcx, hasher);
862                 generator_substs.hash_stable(hcx, hasher);
863                 movability.hash_stable(hcx, hasher);
864             }
865             TyGeneratorWitness(types) => {
866                 types.hash_stable(hcx, hasher)
867             }
868             TyTuple(inner_tys) => {
869                 inner_tys.hash_stable(hcx, hasher);
870             }
871             TyProjection(ref projection_ty) => {
872                 projection_ty.hash_stable(hcx, hasher);
873             }
874             TyAnon(def_id, substs) => {
875                 def_id.hash_stable(hcx, hasher);
876                 substs.hash_stable(hcx, hasher);
877             }
878             TyParam(param_ty) => {
879                 param_ty.hash_stable(hcx, hasher);
880             }
881             TyForeign(def_id) => {
882                 def_id.hash_stable(hcx, hasher);
883             }
884             TyInfer(infer_ty) => {
885                 infer_ty.hash_stable(hcx, hasher);
886             }
887         }
888     }
889 }
890
891 impl_stable_hash_for!(enum ty::InferTy {
892     TyVar(a),
893     IntVar(a),
894     FloatVar(a),
895     FreshTy(a),
896     FreshIntTy(a),
897     FreshFloatTy(a),
898     CanonicalTy(a),
899 });
900
901 impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
902 for ty::TyVid
903 {
904     fn hash_stable<W: StableHasherResult>(&self,
905                                           _hcx: &mut StableHashingContext<'a>,
906                                           _hasher: &mut StableHasher<W>) {
907         // TyVid values are confined to an inference context and hence
908         // should not be hashed.
909         bug!("ty::TypeVariants::hash_stable() - can't hash a TyVid {:?}.", *self)
910     }
911 }
912
913 impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
914 for ty::IntVid
915 {
916     fn hash_stable<W: StableHasherResult>(&self,
917                                           _hcx: &mut StableHashingContext<'a>,
918                                           _hasher: &mut StableHasher<W>) {
919         // IntVid values are confined to an inference context and hence
920         // should not be hashed.
921         bug!("ty::TypeVariants::hash_stable() - can't hash an IntVid {:?}.", *self)
922     }
923 }
924
925 impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
926 for ty::FloatVid
927 {
928     fn hash_stable<W: StableHasherResult>(&self,
929                                           _hcx: &mut StableHashingContext<'a>,
930                                           _hasher: &mut StableHasher<W>) {
931         // FloatVid values are confined to an inference context and hence
932         // should not be hashed.
933         bug!("ty::TypeVariants::hash_stable() - can't hash a FloatVid {:?}.", *self)
934     }
935 }
936
937 impl_stable_hash_for!(struct ty::ParamTy {
938     idx,
939     name
940 });
941
942 impl_stable_hash_for!(struct ty::TypeAndMut<'tcx> {
943     ty,
944     mutbl
945 });
946
947 impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
948 for ty::ExistentialPredicate<'gcx>
949 {
950     fn hash_stable<W: StableHasherResult>(&self,
951                                           hcx: &mut StableHashingContext<'a>,
952                                           hasher: &mut StableHasher<W>) {
953         mem::discriminant(self).hash_stable(hcx, hasher);
954         match *self {
955             ty::ExistentialPredicate::Trait(ref trait_ref) => {
956                 trait_ref.hash_stable(hcx, hasher);
957             }
958             ty::ExistentialPredicate::Projection(ref projection) => {
959                 projection.hash_stable(hcx, hasher);
960             }
961             ty::ExistentialPredicate::AutoTrait(def_id) => {
962                 def_id.hash_stable(hcx, hasher);
963             }
964         }
965     }
966 }
967
968 impl_stable_hash_for!(struct ty::ExistentialTraitRef<'tcx> {
969     def_id,
970     substs
971 });
972
973 impl_stable_hash_for!(struct ty::ExistentialProjection<'tcx> {
974     item_def_id,
975     substs,
976     ty
977 });
978
979 impl_stable_hash_for!(struct ty::Instance<'tcx> {
980     def,
981     substs
982 });
983
984 impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for ty::InstanceDef<'gcx> {
985     fn hash_stable<W: StableHasherResult>(&self,
986                                           hcx: &mut StableHashingContext<'a>,
987                                           hasher: &mut StableHasher<W>) {
988         mem::discriminant(self).hash_stable(hcx, hasher);
989
990         match *self {
991             ty::InstanceDef::Item(def_id) => {
992                 def_id.hash_stable(hcx, hasher);
993             }
994             ty::InstanceDef::Intrinsic(def_id) => {
995                 def_id.hash_stable(hcx, hasher);
996             }
997             ty::InstanceDef::FnPtrShim(def_id, ty) => {
998                 def_id.hash_stable(hcx, hasher);
999                 ty.hash_stable(hcx, hasher);
1000             }
1001             ty::InstanceDef::Virtual(def_id, n) => {
1002                 def_id.hash_stable(hcx, hasher);
1003                 n.hash_stable(hcx, hasher);
1004             }
1005             ty::InstanceDef::ClosureOnceShim { call_once } => {
1006                 call_once.hash_stable(hcx, hasher);
1007             }
1008             ty::InstanceDef::DropGlue(def_id, ty) => {
1009                 def_id.hash_stable(hcx, hasher);
1010                 ty.hash_stable(hcx, hasher);
1011             }
1012             ty::InstanceDef::CloneShim(def_id, ty) => {
1013                 def_id.hash_stable(hcx, hasher);
1014                 ty.hash_stable(hcx, hasher);
1015             }
1016         }
1017     }
1018 }
1019
1020 impl_stable_hash_for!(struct ty::TraitDef {
1021     // We already have the def_path_hash below, no need to hash it twice
1022     def_id -> _,
1023     unsafety,
1024     paren_sugar,
1025     has_auto_impl,
1026     def_path_hash,
1027 });
1028
1029 impl_stable_hash_for!(struct ty::Destructor {
1030     did
1031 });
1032
1033 impl_stable_hash_for!(struct ty::CrateVariancesMap {
1034     variances,
1035     // This is just an irrelevant helper value.
1036     empty_variance -> _,
1037 });
1038
1039 impl_stable_hash_for!(struct ty::CratePredicatesMap<'tcx> {
1040     predicates,
1041     // This is just an irrelevant helper value.
1042     empty_predicate -> _,
1043 });
1044
1045 impl_stable_hash_for!(struct ty::AssociatedItem {
1046     def_id,
1047     ident -> (ident.name),
1048     kind,
1049     vis,
1050     defaultness,
1051     container,
1052     method_has_self_argument
1053 });
1054
1055 impl_stable_hash_for!(enum ty::AssociatedKind {
1056     Const,
1057     Method,
1058     Existential,
1059     Type
1060 });
1061
1062 impl_stable_hash_for!(enum ty::AssociatedItemContainer {
1063     TraitContainer(def_id),
1064     ImplContainer(def_id)
1065 });
1066
1067
1068 impl<'a, 'gcx, T> HashStable<StableHashingContext<'a>>
1069 for ty::steal::Steal<T>
1070     where T: HashStable<StableHashingContext<'a>>
1071 {
1072     fn hash_stable<W: StableHasherResult>(&self,
1073                                           hcx: &mut StableHashingContext<'a>,
1074                                           hasher: &mut StableHasher<W>) {
1075         self.borrow().hash_stable(hcx, hasher);
1076     }
1077 }
1078
1079 impl_stable_hash_for!(struct ty::ParamEnv<'tcx> {
1080     caller_bounds,
1081     reveal
1082 });
1083
1084 impl_stable_hash_for!(enum traits::Reveal {
1085     UserFacing,
1086     All
1087 });
1088
1089 impl_stable_hash_for!(enum ::middle::privacy::AccessLevel {
1090     Reachable,
1091     Exported,
1092     Public
1093 });
1094
1095 impl<'a> HashStable<StableHashingContext<'a>>
1096 for ::middle::privacy::AccessLevels {
1097     fn hash_stable<W: StableHasherResult>(&self,
1098                                           hcx: &mut StableHashingContext<'a>,
1099                                           hasher: &mut StableHasher<W>) {
1100         hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
1101             let ::middle::privacy::AccessLevels {
1102                 ref map
1103             } = *self;
1104
1105             map.hash_stable(hcx, hasher);
1106         });
1107     }
1108 }
1109
1110 impl_stable_hash_for!(struct ty::CrateInherentImpls {
1111     inherent_impls
1112 });
1113
1114 impl_stable_hash_for!(enum ::session::CompileIncomplete {
1115     Stopped,
1116     Errored(error_reported)
1117 });
1118
1119 impl_stable_hash_for!(struct ::util::common::ErrorReported {});
1120
1121 impl_stable_hash_for!(tuple_struct ::middle::reachable::ReachableSet {
1122     reachable_set
1123 });
1124
1125 impl<'a, 'gcx, N> HashStable<StableHashingContext<'a>>
1126 for traits::Vtable<'gcx, N> where N: HashStable<StableHashingContext<'a>> {
1127     fn hash_stable<W: StableHasherResult>(&self,
1128                                           hcx: &mut StableHashingContext<'a>,
1129                                           hasher: &mut StableHasher<W>) {
1130         use traits::Vtable::*;
1131
1132         mem::discriminant(self).hash_stable(hcx, hasher);
1133
1134         match self {
1135             &VtableImpl(ref table_impl) => table_impl.hash_stable(hcx, hasher),
1136             &VtableAutoImpl(ref table_def_impl) => table_def_impl.hash_stable(hcx, hasher),
1137             &VtableParam(ref table_param) => table_param.hash_stable(hcx, hasher),
1138             &VtableObject(ref table_obj) => table_obj.hash_stable(hcx, hasher),
1139             &VtableBuiltin(ref table_builtin) => table_builtin.hash_stable(hcx, hasher),
1140             &VtableClosure(ref table_closure) => table_closure.hash_stable(hcx, hasher),
1141             &VtableFnPointer(ref table_fn_pointer) => table_fn_pointer.hash_stable(hcx, hasher),
1142             &VtableGenerator(ref table_generator) => table_generator.hash_stable(hcx, hasher),
1143         }
1144     }
1145 }
1146
1147 impl<'a, 'gcx, N> HashStable<StableHashingContext<'a>>
1148 for traits::VtableImplData<'gcx, N> where N: HashStable<StableHashingContext<'a>> {
1149     fn hash_stable<W: StableHasherResult>(&self,
1150                                           hcx: &mut StableHashingContext<'a>,
1151                                           hasher: &mut StableHasher<W>) {
1152         let traits::VtableImplData {
1153             impl_def_id,
1154             substs,
1155             ref nested,
1156         } = *self;
1157         impl_def_id.hash_stable(hcx, hasher);
1158         substs.hash_stable(hcx, hasher);
1159         nested.hash_stable(hcx, hasher);
1160     }
1161 }
1162
1163 impl<'a, 'gcx, N> HashStable<StableHashingContext<'a>>
1164 for traits::VtableAutoImplData<N> where N: HashStable<StableHashingContext<'a>> {
1165     fn hash_stable<W: StableHasherResult>(&self,
1166                                           hcx: &mut StableHashingContext<'a>,
1167                                           hasher: &mut StableHasher<W>) {
1168         let traits::VtableAutoImplData {
1169             trait_def_id,
1170             ref nested,
1171         } = *self;
1172         trait_def_id.hash_stable(hcx, hasher);
1173         nested.hash_stable(hcx, hasher);
1174     }
1175 }
1176
1177 impl<'a, 'gcx, N> HashStable<StableHashingContext<'a>>
1178 for traits::VtableObjectData<'gcx, N> where N: HashStable<StableHashingContext<'a>> {
1179     fn hash_stable<W: StableHasherResult>(&self,
1180                                           hcx: &mut StableHashingContext<'a>,
1181                                           hasher: &mut StableHasher<W>) {
1182         let traits::VtableObjectData {
1183             upcast_trait_ref,
1184             vtable_base,
1185             ref nested,
1186         } = *self;
1187         upcast_trait_ref.hash_stable(hcx, hasher);
1188         vtable_base.hash_stable(hcx, hasher);
1189         nested.hash_stable(hcx, hasher);
1190     }
1191 }
1192
1193 impl<'a, 'gcx, N> HashStable<StableHashingContext<'a>>
1194 for traits::VtableBuiltinData<N> where N: HashStable<StableHashingContext<'a>> {
1195     fn hash_stable<W: StableHasherResult>(&self,
1196                                           hcx: &mut StableHashingContext<'a>,
1197                                           hasher: &mut StableHasher<W>) {
1198         let traits::VtableBuiltinData {
1199             ref nested,
1200         } = *self;
1201         nested.hash_stable(hcx, hasher);
1202     }
1203 }
1204
1205 impl<'a, 'gcx, N> HashStable<StableHashingContext<'a>>
1206 for traits::VtableClosureData<'gcx, N> where N: HashStable<StableHashingContext<'a>> {
1207     fn hash_stable<W: StableHasherResult>(&self,
1208                                           hcx: &mut StableHashingContext<'a>,
1209                                           hasher: &mut StableHasher<W>) {
1210         let traits::VtableClosureData {
1211             closure_def_id,
1212             substs,
1213             ref nested,
1214         } = *self;
1215         closure_def_id.hash_stable(hcx, hasher);
1216         substs.hash_stable(hcx, hasher);
1217         nested.hash_stable(hcx, hasher);
1218     }
1219 }
1220
1221 impl<'a, 'gcx, N> HashStable<StableHashingContext<'a>>
1222 for traits::VtableFnPointerData<'gcx, N> where N: HashStable<StableHashingContext<'a>> {
1223     fn hash_stable<W: StableHasherResult>(&self,
1224                                           hcx: &mut StableHashingContext<'a>,
1225                                           hasher: &mut StableHasher<W>) {
1226         let traits::VtableFnPointerData {
1227             fn_ty,
1228             ref nested,
1229         } = *self;
1230         fn_ty.hash_stable(hcx, hasher);
1231         nested.hash_stable(hcx, hasher);
1232     }
1233 }
1234
1235 impl<'a, 'gcx, N> HashStable<StableHashingContext<'a>>
1236 for traits::VtableGeneratorData<'gcx, N> where N: HashStable<StableHashingContext<'a>> {
1237     fn hash_stable<W: StableHasherResult>(&self,
1238                                           hcx: &mut StableHashingContext<'a>,
1239                                           hasher: &mut StableHasher<W>) {
1240         let traits::VtableGeneratorData {
1241             generator_def_id,
1242             substs,
1243             ref nested,
1244         } = *self;
1245         generator_def_id.hash_stable(hcx, hasher);
1246         substs.hash_stable(hcx, hasher);
1247         nested.hash_stable(hcx, hasher);
1248     }
1249 }
1250
1251 impl_stable_hash_for!(
1252     impl<'tcx, V> for struct infer::canonical::Canonical<'tcx, V> {
1253         variables, value
1254     }
1255 );
1256
1257 impl_stable_hash_for!(
1258     impl<'tcx> for struct infer::canonical::CanonicalVarValues<'tcx> {
1259         var_values
1260     }
1261 );
1262
1263 impl_stable_hash_for!(struct infer::canonical::CanonicalVarInfo {
1264     kind
1265 });
1266
1267 impl_stable_hash_for!(enum infer::canonical::CanonicalVarKind {
1268     Ty(k),
1269     Region
1270 });
1271
1272 impl_stable_hash_for!(enum infer::canonical::CanonicalTyVarKind {
1273     General,
1274     Int,
1275     Float
1276 });
1277
1278 impl_stable_hash_for!(
1279     impl<'tcx, R> for struct infer::canonical::QueryResult<'tcx, R> {
1280         var_values, region_constraints, certainty, value
1281     }
1282 );
1283
1284 impl_stable_hash_for!(enum infer::canonical::Certainty {
1285     Proven, Ambiguous
1286 });
1287
1288 impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for traits::WhereClause<'tcx> {
1289     fn hash_stable<W: StableHasherResult>(&self,
1290                                           hcx: &mut StableHashingContext<'a>,
1291                                           hasher: &mut StableHasher<W>) {
1292         use traits::WhereClause::*;
1293
1294         mem::discriminant(self).hash_stable(hcx, hasher);
1295         match self {
1296             Implemented(trait_ref) => trait_ref.hash_stable(hcx, hasher),
1297             ProjectionEq(projection) => projection.hash_stable(hcx, hasher),
1298             TypeOutlives(ty_outlives) => ty_outlives.hash_stable(hcx, hasher),
1299             RegionOutlives(region_outlives) => region_outlives.hash_stable(hcx, hasher),
1300         }
1301     }
1302 }
1303
1304 impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for traits::WellFormed<'tcx> {
1305     fn hash_stable<W: StableHasherResult>(&self,
1306                                           hcx: &mut StableHashingContext<'a>,
1307                                           hasher: &mut StableHasher<W>) {
1308         use traits::WellFormed::*;
1309
1310         mem::discriminant(self).hash_stable(hcx, hasher);
1311         match self {
1312             Trait(trait_ref) => trait_ref.hash_stable(hcx, hasher),
1313             Ty(ty) => ty.hash_stable(hcx, hasher),
1314         }
1315     }
1316 }
1317
1318 impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for traits::FromEnv<'tcx> {
1319     fn hash_stable<W: StableHasherResult>(&self,
1320                                           hcx: &mut StableHashingContext<'a>,
1321                                           hasher: &mut StableHasher<W>) {
1322         use traits::FromEnv::*;
1323
1324         mem::discriminant(self).hash_stable(hcx, hasher);
1325         match self {
1326             Trait(trait_ref) => trait_ref.hash_stable(hcx, hasher),
1327             Ty(ty) => ty.hash_stable(hcx, hasher),
1328         }
1329     }
1330 }
1331
1332 impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for traits::DomainGoal<'tcx> {
1333     fn hash_stable<W: StableHasherResult>(&self,
1334                                           hcx: &mut StableHashingContext<'a>,
1335                                           hasher: &mut StableHasher<W>) {
1336         use traits::DomainGoal::*;
1337
1338         mem::discriminant(self).hash_stable(hcx, hasher);
1339         match self {
1340             Holds(wc) => wc.hash_stable(hcx, hasher),
1341             WellFormed(wf) => wf.hash_stable(hcx, hasher),
1342             FromEnv(from_env) => from_env.hash_stable(hcx, hasher),
1343             Normalize(projection) => projection.hash_stable(hcx, hasher),
1344         }
1345     }
1346 }
1347
1348 impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for traits::Goal<'tcx> {
1349     fn hash_stable<W: StableHasherResult>(&self,
1350                                           hcx: &mut StableHashingContext<'a>,
1351                                           hasher: &mut StableHasher<W>) {
1352         use traits::Goal::*;
1353
1354         mem::discriminant(self).hash_stable(hcx, hasher);
1355         match self {
1356             Implies(hypotheses, goal) => {
1357                 hypotheses.hash_stable(hcx, hasher);
1358                 goal.hash_stable(hcx, hasher);
1359             },
1360             And(goal1, goal2) => {
1361                 goal1.hash_stable(hcx, hasher);
1362                 goal2.hash_stable(hcx, hasher);
1363             }
1364             Not(goal) => goal.hash_stable(hcx, hasher),
1365             DomainGoal(domain_goal) => domain_goal.hash_stable(hcx, hasher),
1366             Quantified(quantifier, goal) => {
1367                 quantifier.hash_stable(hcx, hasher);
1368                 goal.hash_stable(hcx, hasher);
1369             },
1370             CannotProve => { },
1371         }
1372     }
1373 }
1374
1375 impl_stable_hash_for!(
1376     impl<'tcx> for struct traits::ProgramClause<'tcx> {
1377         goal, hypotheses
1378     }
1379 );
1380
1381 impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for traits::Clause<'tcx> {
1382     fn hash_stable<W: StableHasherResult>(&self,
1383                                           hcx: &mut StableHashingContext<'a>,
1384                                           hasher: &mut StableHasher<W>) {
1385         use traits::Clause::*;
1386
1387         mem::discriminant(self).hash_stable(hcx, hasher);
1388         match self {
1389             Implies(clause) => clause.hash_stable(hcx, hasher),
1390             ForAll(clause) => clause.hash_stable(hcx, hasher),
1391         }
1392     }
1393 }
1394
1395 impl_stable_hash_for!(enum traits::QuantifierKind {
1396     Universal,
1397     Existential
1398 });