]> git.lizzy.rs Git - rust.git/blob - src/librustc/ich/impls_ty.rs
Auto merge of #50767 - oli-obk:rls_clippy, r=kennytm
[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.depth.hash_stable(hcx, hasher);
108                 i.hash_stable(hcx, hasher);
109             }
110             ty::ReLateBound(db, ty::BrNamed(def_id, name)) => {
111                 db.depth.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.depth.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!("TypeIdHasher: 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     name,
363     vis
364 });
365
366 impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
367 for ::middle::const_val::ConstVal<'gcx> {
368     fn hash_stable<W: StableHasherResult>(&self,
369                                           hcx: &mut StableHashingContext<'a>,
370                                           hasher: &mut StableHasher<W>) {
371         use middle::const_val::ConstVal::*;
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             Value(ref value) => {
381                 value.hash_stable(hcx, hasher);
382             }
383         }
384     }
385 }
386
387 impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
388 for ::mir::interpret::ConstValue<'gcx> {
389     fn hash_stable<W: StableHasherResult>(&self,
390                                           hcx: &mut StableHashingContext<'a>,
391                                           hasher: &mut StableHasher<W>) {
392         use mir::interpret::ConstValue::*;
393
394         mem::discriminant(self).hash_stable(hcx, hasher);
395
396         match *self {
397             ByVal(val) => {
398                 val.hash_stable(hcx, hasher);
399             }
400             ByValPair(a, b) => {
401                 a.hash_stable(hcx, hasher);
402                 b.hash_stable(hcx, hasher);
403             }
404             ByRef(alloc) => {
405                 alloc.hash_stable(hcx, hasher);
406             }
407         }
408     }
409 }
410
411 impl_stable_hash_for!(enum mir::interpret::Value {
412     ByVal(v),
413     ByValPair(a, b),
414     ByRef(ptr, align)
415 });
416
417 impl_stable_hash_for!(struct mir::interpret::MemoryPointer {
418     alloc_id,
419     offset
420 });
421
422 enum AllocDiscriminant {
423     Alloc,
424     Static,
425     Function,
426 }
427 impl_stable_hash_for!(enum self::AllocDiscriminant {
428     Alloc,
429     Static,
430     Function
431 });
432
433 impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::AllocId {
434     fn hash_stable<W: StableHasherResult>(
435         &self,
436         hcx: &mut StableHashingContext<'a>,
437         hasher: &mut StableHasher<W>,
438     ) {
439         ty::tls::with_opt(|tcx| {
440             trace!("hashing {:?}", *self);
441             let tcx = tcx.expect("can't hash AllocIds during hir lowering");
442             if let Some(def_id) = tcx.interpret_interner.get_static(*self) {
443                 AllocDiscriminant::Static.hash_stable(hcx, hasher);
444                 trace!("hashing {:?} as static {:?}", *self, def_id);
445                 def_id.hash_stable(hcx, hasher);
446             } else if let Some(alloc) = tcx.interpret_interner.get_alloc(*self) {
447                 AllocDiscriminant::Alloc.hash_stable(hcx, hasher);
448                 if hcx.alloc_id_recursion_tracker.insert(*self) {
449                     trace!("hashing {:?} as alloc {:#?}", *self, alloc);
450                     alloc.hash_stable(hcx, hasher);
451                     assert!(hcx.alloc_id_recursion_tracker.remove(self));
452                 } else {
453                     trace!("skipping hashing of {:?} due to recursion", *self);
454                 }
455             } else if let Some(inst) = tcx.interpret_interner.get_fn(*self) {
456                 trace!("hashing {:?} as fn {:#?}", *self, inst);
457                 AllocDiscriminant::Function.hash_stable(hcx, hasher);
458                 inst.hash_stable(hcx, hasher);
459             } else {
460                 bug!("no allocation for {}", self);
461             }
462         });
463     }
464 }
465
466 impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::Allocation {
467     fn hash_stable<W: StableHasherResult>(
468         &self,
469         hcx: &mut StableHashingContext<'a>,
470         hasher: &mut StableHasher<W>,
471     ) {
472         self.bytes.hash_stable(hcx, hasher);
473         for reloc in self.relocations.iter() {
474             reloc.hash_stable(hcx, hasher);
475         }
476         self.undef_mask.hash_stable(hcx, hasher);
477         self.align.hash_stable(hcx, hasher);
478         self.runtime_mutability.hash_stable(hcx, hasher);
479     }
480 }
481
482 impl_stable_hash_for!(enum ::syntax::ast::Mutability {
483     Immutable,
484     Mutable
485 });
486
487 impl_stable_hash_for!(struct mir::interpret::Pointer{primval});
488
489 impl_stable_hash_for!(enum mir::interpret::PrimVal {
490     Bytes(b),
491     Ptr(p),
492     Undef
493 });
494
495 impl_stable_hash_for!(struct ty::Const<'tcx> {
496     ty,
497     val
498 });
499
500 impl_stable_hash_for!(struct ::middle::const_val::ConstEvalErr<'tcx> {
501     span,
502     kind
503 });
504
505 impl_stable_hash_for!(struct ::middle::const_val::FrameInfo {
506     span,
507     location
508 });
509
510 impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
511 for ::middle::const_val::ErrKind<'gcx> {
512     fn hash_stable<W: StableHasherResult>(&self,
513                                           hcx: &mut StableHashingContext<'a>,
514                                           hasher: &mut StableHasher<W>) {
515         use middle::const_val::ErrKind::*;
516
517         mem::discriminant(self).hash_stable(hcx, hasher);
518
519         match *self {
520             NonConstPath |
521             TypeckError |
522             CheckMatchError => {
523                 // nothing to do
524             }
525             UnimplementedConstVal(s) => {
526                 s.hash_stable(hcx, hasher);
527             }
528             IndexOutOfBounds { len, index } => {
529                 len.hash_stable(hcx, hasher);
530                 index.hash_stable(hcx, hasher);
531             }
532             LayoutError(ref layout_error) => {
533                 layout_error.hash_stable(hcx, hasher);
534             }
535             Miri(ref err, ref trace) => {
536                 err.hash_stable(hcx, hasher);
537                 trace.hash_stable(hcx, hasher);
538             },
539         }
540     }
541 }
542
543 impl_stable_hash_for!(struct ty::ClosureSubsts<'tcx> { substs });
544 impl_stable_hash_for!(struct ty::GeneratorSubsts<'tcx> { substs });
545
546 impl_stable_hash_for!(struct ty::GenericPredicates<'tcx> {
547     parent,
548     predicates
549 });
550
551
552 impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
553 for ::mir::interpret::EvalError<'gcx> {
554     fn hash_stable<W: StableHasherResult>(&self,
555                                           hcx: &mut StableHashingContext<'a>,
556                                           hasher: &mut StableHasher<W>) {
557         self.kind.hash_stable(hcx, hasher)
558     }
559 }
560
561 impl<'a, 'gcx, O: HashStable<StableHashingContext<'a>>> HashStable<StableHashingContext<'a>>
562 for ::mir::interpret::EvalErrorKind<'gcx, O> {
563     fn hash_stable<W: StableHasherResult>(&self,
564                                           hcx: &mut StableHashingContext<'a>,
565                                           hasher: &mut StableHasher<W>) {
566         use mir::interpret::EvalErrorKind::*;
567
568         mem::discriminant(&self).hash_stable(hcx, hasher);
569
570         match *self {
571             DanglingPointerDeref |
572             DoubleFree |
573             InvalidMemoryAccess |
574             InvalidFunctionPointer |
575             InvalidBool |
576             InvalidDiscriminant |
577             InvalidNullPointerUsage |
578             ReadPointerAsBytes |
579             ReadBytesAsPointer |
580             InvalidPointerMath |
581             ReadUndefBytes |
582             DeadLocal |
583             StackFrameLimitReached |
584             OutOfTls |
585             TlsOutOfBounds |
586             CalledClosureAsFunction |
587             VtableForArgumentlessMethod |
588             ModifiedConstantMemory |
589             AssumptionNotHeld |
590             InlineAsm |
591             ReallocateNonBasePtr |
592             DeallocateNonBasePtr |
593             HeapAllocZeroBytes |
594             Unreachable |
595             Panic |
596             ReadFromReturnPointer |
597             UnimplementedTraitSelection |
598             TypeckError |
599             DerefFunctionPointer |
600             ExecuteMemory |
601             OverflowNeg |
602             RemainderByZero |
603             DivisionByZero |
604             GeneratorResumedAfterReturn |
605             GeneratorResumedAfterPanic |
606             ReferencedConstant => {}
607             MachineError(ref err) => err.hash_stable(hcx, hasher),
608             FunctionPointerTyMismatch(a, b) => {
609                 a.hash_stable(hcx, hasher);
610                 b.hash_stable(hcx, hasher)
611             },
612             NoMirFor(ref s) => s.hash_stable(hcx, hasher),
613             UnterminatedCString(ptr) => ptr.hash_stable(hcx, hasher),
614             PointerOutOfBounds {
615                 ptr,
616                 access,
617                 allocation_size,
618             } => {
619                 ptr.hash_stable(hcx, hasher);
620                 access.hash_stable(hcx, hasher);
621                 allocation_size.hash_stable(hcx, hasher)
622             },
623             InvalidBoolOp(bop) => bop.hash_stable(hcx, hasher),
624             Unimplemented(ref s) => s.hash_stable(hcx, hasher),
625             BoundsCheck { ref len, ref index } => {
626                 len.hash_stable(hcx, hasher);
627                 index.hash_stable(hcx, hasher)
628             },
629             Intrinsic(ref s) => s.hash_stable(hcx, hasher),
630             InvalidChar(c) => c.hash_stable(hcx, hasher),
631             AbiViolation(ref s) => s.hash_stable(hcx, hasher),
632             AlignmentCheckFailed {
633                 required,
634                 has,
635             } => {
636                 required.hash_stable(hcx, hasher);
637                 has.hash_stable(hcx, hasher)
638             },
639             MemoryLockViolation {
640                 ptr,
641                 len,
642                 frame,
643                 access,
644                 ref lock,
645             } =>  {
646                 ptr.hash_stable(hcx, hasher);
647                 len.hash_stable(hcx, hasher);
648                 frame.hash_stable(hcx, hasher);
649                 access.hash_stable(hcx, hasher);
650                 lock.hash_stable(hcx, hasher)
651             },
652             MemoryAcquireConflict {
653                 ptr,
654                 len,
655                 kind,
656                 ref lock,
657             } =>  {
658                 ptr.hash_stable(hcx, hasher);
659                 len.hash_stable(hcx, hasher);
660                 kind.hash_stable(hcx, hasher);
661                 lock.hash_stable(hcx, hasher)
662             },
663             InvalidMemoryLockRelease {
664                 ptr,
665                 len,
666                 frame,
667                 ref lock,
668             } =>  {
669                 ptr.hash_stable(hcx, hasher);
670                 len.hash_stable(hcx, hasher);
671                 frame.hash_stable(hcx, hasher);
672                 lock.hash_stable(hcx, hasher)
673             },
674             DeallocatedLockedMemory {
675                 ptr,
676                 ref lock,
677             } => {
678                 ptr.hash_stable(hcx, hasher);
679                 lock.hash_stable(hcx, hasher)
680             },
681             ValidationFailure(ref s) => s.hash_stable(hcx, hasher),
682             TypeNotPrimitive(ty) => ty.hash_stable(hcx, hasher),
683             ReallocatedWrongMemoryKind(ref a, ref b) => {
684                 a.hash_stable(hcx, hasher);
685                 b.hash_stable(hcx, hasher)
686             },
687             DeallocatedWrongMemoryKind(ref a, ref b) => {
688                 a.hash_stable(hcx, hasher);
689                 b.hash_stable(hcx, hasher)
690             },
691             IncorrectAllocationInformation(a, b, c, d) => {
692                 a.hash_stable(hcx, hasher);
693                 b.hash_stable(hcx, hasher);
694                 c.hash_stable(hcx, hasher);
695                 d.hash_stable(hcx, hasher)
696             },
697             Layout(lay) => lay.hash_stable(hcx, hasher),
698             HeapAllocNonPowerOfTwoAlignment(n) => n.hash_stable(hcx, hasher),
699             PathNotFound(ref v) => v.hash_stable(hcx, hasher),
700             Overflow(op) => op.hash_stable(hcx, hasher),
701         }
702     }
703 }
704
705 impl_stable_hash_for!(enum mir::interpret::Lock {
706     NoLock,
707     WriteLock(dl),
708     ReadLock(v)
709 });
710
711 impl_stable_hash_for!(struct mir::interpret::DynamicLifetime {
712     frame,
713     region
714 });
715
716 impl_stable_hash_for!(enum mir::interpret::AccessKind {
717     Read,
718     Write
719 });
720
721 impl_stable_hash_for!(enum ty::Variance {
722     Covariant,
723     Invariant,
724     Contravariant,
725     Bivariant
726 });
727
728 impl_stable_hash_for!(enum ty::adjustment::CustomCoerceUnsized {
729     Struct(index)
730 });
731
732 impl<'a> HashStable<StableHashingContext<'a>> for ty::Generics {
733     fn hash_stable<W: StableHasherResult>(&self,
734                                           hcx: &mut StableHashingContext<'a>,
735                                           hasher: &mut StableHasher<W>) {
736         let ty::Generics {
737             parent,
738             parent_regions,
739             parent_types,
740             ref regions,
741             ref types,
742
743             // Reverse map to each `TypeParameterDef`'s `index` field, from
744             // `def_id.index` (`def_id.krate` is the same as the item's).
745             type_param_to_index: _, // Don't hash this
746             has_self,
747             has_late_bound_regions,
748         } = *self;
749
750         parent.hash_stable(hcx, hasher);
751         parent_regions.hash_stable(hcx, hasher);
752         parent_types.hash_stable(hcx, hasher);
753         regions.hash_stable(hcx, hasher);
754         types.hash_stable(hcx, hasher);
755         has_self.hash_stable(hcx, hasher);
756         has_late_bound_regions.hash_stable(hcx, hasher);
757     }
758 }
759
760 impl<'a> HashStable<StableHashingContext<'a>>
761 for ty::RegionParameterDef {
762     fn hash_stable<W: StableHasherResult>(&self,
763                                           hcx: &mut StableHashingContext<'a>,
764                                           hasher: &mut StableHasher<W>) {
765         let ty::RegionParameterDef {
766             name,
767             def_id,
768             index,
769             pure_wrt_drop
770         } = *self;
771
772         name.hash_stable(hcx, hasher);
773         def_id.hash_stable(hcx, hasher);
774         index.hash_stable(hcx, hasher);
775         pure_wrt_drop.hash_stable(hcx, hasher);
776     }
777 }
778
779 impl_stable_hash_for!(struct ty::TypeParameterDef {
780     name,
781     def_id,
782     index,
783     has_default,
784     object_lifetime_default,
785     pure_wrt_drop,
786     synthetic
787 });
788
789 impl<'a, 'gcx, T> HashStable<StableHashingContext<'a>>
790 for ::middle::resolve_lifetime::Set1<T>
791     where T: HashStable<StableHashingContext<'a>>
792 {
793     fn hash_stable<W: StableHasherResult>(&self,
794                                           hcx: &mut StableHashingContext<'a>,
795                                           hasher: &mut StableHasher<W>) {
796         use middle::resolve_lifetime::Set1;
797
798         mem::discriminant(self).hash_stable(hcx, hasher);
799         match *self {
800             Set1::Empty |
801             Set1::Many => {
802                 // Nothing to do.
803             }
804             Set1::One(ref value) => {
805                 value.hash_stable(hcx, hasher);
806             }
807         }
808     }
809 }
810
811 impl_stable_hash_for!(enum ::middle::resolve_lifetime::LifetimeDefOrigin {
812     Explicit,
813     InBand
814 });
815
816 impl_stable_hash_for!(enum ::middle::resolve_lifetime::Region {
817     Static,
818     EarlyBound(index, decl, is_in_band),
819     LateBound(db_index, decl, is_in_band),
820     LateBoundAnon(db_index, anon_index),
821     Free(call_site_scope_data, decl)
822 });
823
824 impl_stable_hash_for!(struct ty::DebruijnIndex {
825     depth
826 });
827
828 impl_stable_hash_for!(enum ty::cast::CastKind {
829     CoercionCast,
830     PtrPtrCast,
831     PtrAddrCast,
832     AddrPtrCast,
833     NumericCast,
834     EnumCast,
835     PrimIntCast,
836     U8CharCast,
837     ArrayPtrCast,
838     FnPtrPtrCast,
839     FnPtrAddrCast
840 });
841
842 impl_stable_hash_for!(tuple_struct ::middle::region::FirstStatementIndex { idx });
843 impl_stable_hash_for!(struct ::middle::region::Scope { id, code });
844
845 impl<'a> ToStableHashKey<StableHashingContext<'a>> for region::Scope {
846     type KeyType = region::Scope;
847
848     #[inline]
849     fn to_stable_hash_key(&self, _: &StableHashingContext<'a>) -> region::Scope {
850         *self
851     }
852 }
853
854 impl_stable_hash_for!(struct ::middle::region::BlockRemainder {
855     block,
856     first_statement_index
857 });
858
859 impl_stable_hash_for!(struct ty::adjustment::CoerceUnsizedInfo {
860     custom_kind
861 });
862
863 impl_stable_hash_for!(struct ty::FreeRegion {
864     scope,
865     bound_region
866 });
867
868 impl_stable_hash_for!(enum ty::BoundRegion {
869     BrAnon(index),
870     BrNamed(def_id, name),
871     BrFresh(index),
872     BrEnv
873 });
874
875 impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
876 for ty::TypeVariants<'gcx>
877 {
878     fn hash_stable<W: StableHasherResult>(&self,
879                                           hcx: &mut StableHashingContext<'a>,
880                                           hasher: &mut StableHasher<W>) {
881         use ty::TypeVariants::*;
882
883         mem::discriminant(self).hash_stable(hcx, hasher);
884         match *self {
885             TyBool  |
886             TyChar  |
887             TyStr   |
888             TyError |
889             TyNever => {
890                 // Nothing more to hash.
891             }
892             TyInt(int_ty) => {
893                 int_ty.hash_stable(hcx, hasher);
894             }
895             TyUint(uint_ty) => {
896                 uint_ty.hash_stable(hcx, hasher);
897             }
898             TyFloat(float_ty)  => {
899                 float_ty.hash_stable(hcx, hasher);
900             }
901             TyAdt(adt_def, substs) => {
902                 adt_def.hash_stable(hcx, hasher);
903                 substs.hash_stable(hcx, hasher);
904             }
905             TyArray(inner_ty, len) => {
906                 inner_ty.hash_stable(hcx, hasher);
907                 len.hash_stable(hcx, hasher);
908             }
909             TySlice(inner_ty) => {
910                 inner_ty.hash_stable(hcx, hasher);
911             }
912             TyRawPtr(pointee_ty) => {
913                 pointee_ty.hash_stable(hcx, hasher);
914             }
915             TyRef(region, pointee_ty, mutbl) => {
916                 region.hash_stable(hcx, hasher);
917                 pointee_ty.hash_stable(hcx, hasher);
918                 mutbl.hash_stable(hcx, hasher);
919             }
920             TyFnDef(def_id, substs) => {
921                 def_id.hash_stable(hcx, hasher);
922                 substs.hash_stable(hcx, hasher);
923             }
924             TyFnPtr(ref sig) => {
925                 sig.hash_stable(hcx, hasher);
926             }
927             TyDynamic(ref existential_predicates, region) => {
928                 existential_predicates.hash_stable(hcx, hasher);
929                 region.hash_stable(hcx, hasher);
930             }
931             TyClosure(def_id, closure_substs) => {
932                 def_id.hash_stable(hcx, hasher);
933                 closure_substs.hash_stable(hcx, hasher);
934             }
935             TyGenerator(def_id, generator_substs, movability) => {
936                 def_id.hash_stable(hcx, hasher);
937                 generator_substs.hash_stable(hcx, hasher);
938                 movability.hash_stable(hcx, hasher);
939             }
940             TyGeneratorWitness(types) => {
941                 types.hash_stable(hcx, hasher)
942             }
943             TyTuple(inner_tys) => {
944                 inner_tys.hash_stable(hcx, hasher);
945             }
946             TyProjection(ref projection_ty) => {
947                 projection_ty.hash_stable(hcx, hasher);
948             }
949             TyAnon(def_id, substs) => {
950                 def_id.hash_stable(hcx, hasher);
951                 substs.hash_stable(hcx, hasher);
952             }
953             TyParam(param_ty) => {
954                 param_ty.hash_stable(hcx, hasher);
955             }
956             TyForeign(def_id) => {
957                 def_id.hash_stable(hcx, hasher);
958             }
959             TyInfer(infer_ty) => {
960                 infer_ty.hash_stable(hcx, hasher);
961             }
962         }
963     }
964 }
965
966 impl_stable_hash_for!(enum ty::InferTy {
967     TyVar(a),
968     IntVar(a),
969     FloatVar(a),
970     FreshTy(a),
971     FreshIntTy(a),
972     FreshFloatTy(a),
973     CanonicalTy(a),
974 });
975
976 impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
977 for ty::TyVid
978 {
979     fn hash_stable<W: StableHasherResult>(&self,
980                                           _hcx: &mut StableHashingContext<'a>,
981                                           _hasher: &mut StableHasher<W>) {
982         // TyVid values are confined to an inference context and hence
983         // should not be hashed.
984         bug!("ty::TypeVariants::hash_stable() - can't hash a TyVid {:?}.", *self)
985     }
986 }
987
988 impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
989 for ty::IntVid
990 {
991     fn hash_stable<W: StableHasherResult>(&self,
992                                           _hcx: &mut StableHashingContext<'a>,
993                                           _hasher: &mut StableHasher<W>) {
994         // IntVid values are confined to an inference context and hence
995         // should not be hashed.
996         bug!("ty::TypeVariants::hash_stable() - can't hash an IntVid {:?}.", *self)
997     }
998 }
999
1000 impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
1001 for ty::FloatVid
1002 {
1003     fn hash_stable<W: StableHasherResult>(&self,
1004                                           _hcx: &mut StableHashingContext<'a>,
1005                                           _hasher: &mut StableHasher<W>) {
1006         // FloatVid values are confined to an inference context and hence
1007         // should not be hashed.
1008         bug!("ty::TypeVariants::hash_stable() - can't hash a FloatVid {:?}.", *self)
1009     }
1010 }
1011
1012 impl_stable_hash_for!(struct ty::ParamTy {
1013     idx,
1014     name
1015 });
1016
1017 impl_stable_hash_for!(struct ty::TypeAndMut<'tcx> {
1018     ty,
1019     mutbl
1020 });
1021
1022 impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
1023 for ty::ExistentialPredicate<'gcx>
1024 {
1025     fn hash_stable<W: StableHasherResult>(&self,
1026                                           hcx: &mut StableHashingContext<'a>,
1027                                           hasher: &mut StableHasher<W>) {
1028         mem::discriminant(self).hash_stable(hcx, hasher);
1029         match *self {
1030             ty::ExistentialPredicate::Trait(ref trait_ref) => {
1031                 trait_ref.hash_stable(hcx, hasher);
1032             }
1033             ty::ExistentialPredicate::Projection(ref projection) => {
1034                 projection.hash_stable(hcx, hasher);
1035             }
1036             ty::ExistentialPredicate::AutoTrait(def_id) => {
1037                 def_id.hash_stable(hcx, hasher);
1038             }
1039         }
1040     }
1041 }
1042
1043 impl_stable_hash_for!(struct ty::ExistentialTraitRef<'tcx> {
1044     def_id,
1045     substs
1046 });
1047
1048 impl_stable_hash_for!(struct ty::ExistentialProjection<'tcx> {
1049     item_def_id,
1050     substs,
1051     ty
1052 });
1053
1054 impl_stable_hash_for!(struct ty::Instance<'tcx> {
1055     def,
1056     substs
1057 });
1058
1059 impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for ty::InstanceDef<'gcx> {
1060     fn hash_stable<W: StableHasherResult>(&self,
1061                                           hcx: &mut StableHashingContext<'a>,
1062                                           hasher: &mut StableHasher<W>) {
1063         mem::discriminant(self).hash_stable(hcx, hasher);
1064
1065         match *self {
1066             ty::InstanceDef::Item(def_id) => {
1067                 def_id.hash_stable(hcx, hasher);
1068             }
1069             ty::InstanceDef::Intrinsic(def_id) => {
1070                 def_id.hash_stable(hcx, hasher);
1071             }
1072             ty::InstanceDef::FnPtrShim(def_id, ty) => {
1073                 def_id.hash_stable(hcx, hasher);
1074                 ty.hash_stable(hcx, hasher);
1075             }
1076             ty::InstanceDef::Virtual(def_id, n) => {
1077                 def_id.hash_stable(hcx, hasher);
1078                 n.hash_stable(hcx, hasher);
1079             }
1080             ty::InstanceDef::ClosureOnceShim { call_once } => {
1081                 call_once.hash_stable(hcx, hasher);
1082             }
1083             ty::InstanceDef::DropGlue(def_id, ty) => {
1084                 def_id.hash_stable(hcx, hasher);
1085                 ty.hash_stable(hcx, hasher);
1086             }
1087             ty::InstanceDef::CloneShim(def_id, ty) => {
1088                 def_id.hash_stable(hcx, hasher);
1089                 ty.hash_stable(hcx, hasher);
1090             }
1091         }
1092     }
1093 }
1094
1095 impl<'a> HashStable<StableHashingContext<'a>> for ty::TraitDef {
1096     fn hash_stable<W: StableHasherResult>(&self,
1097                                           hcx: &mut StableHashingContext<'a>,
1098                                           hasher: &mut StableHasher<W>) {
1099         let ty::TraitDef {
1100             // We already have the def_path_hash below, no need to hash it twice
1101             def_id: _,
1102             unsafety,
1103             paren_sugar,
1104             has_auto_impl,
1105             def_path_hash,
1106         } = *self;
1107
1108         unsafety.hash_stable(hcx, hasher);
1109         paren_sugar.hash_stable(hcx, hasher);
1110         has_auto_impl.hash_stable(hcx, hasher);
1111         def_path_hash.hash_stable(hcx, hasher);
1112     }
1113 }
1114
1115 impl_stable_hash_for!(struct ty::Destructor {
1116     did
1117 });
1118
1119 impl<'a> HashStable<StableHashingContext<'a>> for ty::CrateVariancesMap {
1120     fn hash_stable<W: StableHasherResult>(&self,
1121                                           hcx: &mut StableHashingContext<'a>,
1122                                           hasher: &mut StableHasher<W>) {
1123         let ty::CrateVariancesMap {
1124             ref variances,
1125             // This is just an irrelevant helper value.
1126             empty_variance: _,
1127         } = *self;
1128
1129         variances.hash_stable(hcx, hasher);
1130     }
1131 }
1132
1133 impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for ty::CratePredicatesMap<'gcx> {
1134     fn hash_stable<W: StableHasherResult>(&self,
1135                                           hcx: &mut StableHashingContext<'a>,
1136                                           hasher: &mut StableHasher<W>) {
1137         let ty::CratePredicatesMap {
1138             ref predicates,
1139             // This is just an irrelevant helper value.
1140             empty_predicate: _,
1141         } = *self;
1142
1143         predicates.hash_stable(hcx, hasher);
1144     }
1145 }
1146
1147 impl_stable_hash_for!(struct ty::AssociatedItem {
1148     def_id,
1149     name,
1150     kind,
1151     vis,
1152     defaultness,
1153     container,
1154     method_has_self_argument
1155 });
1156
1157 impl_stable_hash_for!(enum ty::AssociatedKind {
1158     Const,
1159     Method,
1160     Type
1161 });
1162
1163 impl_stable_hash_for!(enum ty::AssociatedItemContainer {
1164     TraitContainer(def_id),
1165     ImplContainer(def_id)
1166 });
1167
1168
1169 impl<'a, 'gcx, T> HashStable<StableHashingContext<'a>>
1170 for ty::steal::Steal<T>
1171     where T: HashStable<StableHashingContext<'a>>
1172 {
1173     fn hash_stable<W: StableHasherResult>(&self,
1174                                           hcx: &mut StableHashingContext<'a>,
1175                                           hasher: &mut StableHasher<W>) {
1176         self.borrow().hash_stable(hcx, hasher);
1177     }
1178 }
1179
1180 impl_stable_hash_for!(struct ty::ParamEnv<'tcx> {
1181     caller_bounds,
1182     reveal
1183 });
1184
1185 impl_stable_hash_for!(enum traits::Reveal {
1186     UserFacing,
1187     All
1188 });
1189
1190 impl_stable_hash_for!(enum ::middle::privacy::AccessLevel {
1191     Reachable,
1192     Exported,
1193     Public
1194 });
1195
1196 impl<'a> HashStable<StableHashingContext<'a>>
1197 for ::middle::privacy::AccessLevels {
1198     fn hash_stable<W: StableHasherResult>(&self,
1199                                           hcx: &mut StableHashingContext<'a>,
1200                                           hasher: &mut StableHasher<W>) {
1201         hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
1202             let ::middle::privacy::AccessLevels {
1203                 ref map
1204             } = *self;
1205
1206             map.hash_stable(hcx, hasher);
1207         });
1208     }
1209 }
1210
1211 impl_stable_hash_for!(struct ty::CrateInherentImpls {
1212     inherent_impls
1213 });
1214
1215 impl_stable_hash_for!(enum ::session::CompileIncomplete {
1216     Stopped,
1217     Errored(error_reported)
1218 });
1219
1220 impl_stable_hash_for!(struct ::util::common::ErrorReported {});
1221
1222 impl_stable_hash_for!(tuple_struct ::middle::reachable::ReachableSet {
1223     reachable_set
1224 });
1225
1226 impl<'a, 'gcx, N> HashStable<StableHashingContext<'a>>
1227 for traits::Vtable<'gcx, N> where N: HashStable<StableHashingContext<'a>> {
1228     fn hash_stable<W: StableHasherResult>(&self,
1229                                           hcx: &mut StableHashingContext<'a>,
1230                                           hasher: &mut StableHasher<W>) {
1231         use traits::Vtable::*;
1232
1233         mem::discriminant(self).hash_stable(hcx, hasher);
1234
1235         match self {
1236             &VtableImpl(ref table_impl) => table_impl.hash_stable(hcx, hasher),
1237             &VtableAutoImpl(ref table_def_impl) => table_def_impl.hash_stable(hcx, hasher),
1238             &VtableParam(ref table_param) => table_param.hash_stable(hcx, hasher),
1239             &VtableObject(ref table_obj) => table_obj.hash_stable(hcx, hasher),
1240             &VtableBuiltin(ref table_builtin) => table_builtin.hash_stable(hcx, hasher),
1241             &VtableClosure(ref table_closure) => table_closure.hash_stable(hcx, hasher),
1242             &VtableFnPointer(ref table_fn_pointer) => table_fn_pointer.hash_stable(hcx, hasher),
1243             &VtableGenerator(ref table_generator) => table_generator.hash_stable(hcx, hasher),
1244         }
1245     }
1246 }
1247
1248 impl<'a, 'gcx, N> HashStable<StableHashingContext<'a>>
1249 for traits::VtableImplData<'gcx, N> where N: HashStable<StableHashingContext<'a>> {
1250     fn hash_stable<W: StableHasherResult>(&self,
1251                                           hcx: &mut StableHashingContext<'a>,
1252                                           hasher: &mut StableHasher<W>) {
1253         let traits::VtableImplData {
1254             impl_def_id,
1255             substs,
1256             ref nested,
1257         } = *self;
1258         impl_def_id.hash_stable(hcx, hasher);
1259         substs.hash_stable(hcx, hasher);
1260         nested.hash_stable(hcx, hasher);
1261     }
1262 }
1263
1264 impl<'a, 'gcx, N> HashStable<StableHashingContext<'a>>
1265 for traits::VtableAutoImplData<N> where N: HashStable<StableHashingContext<'a>> {
1266     fn hash_stable<W: StableHasherResult>(&self,
1267                                           hcx: &mut StableHashingContext<'a>,
1268                                           hasher: &mut StableHasher<W>) {
1269         let traits::VtableAutoImplData {
1270             trait_def_id,
1271             ref nested,
1272         } = *self;
1273         trait_def_id.hash_stable(hcx, hasher);
1274         nested.hash_stable(hcx, hasher);
1275     }
1276 }
1277
1278 impl<'a, 'gcx, N> HashStable<StableHashingContext<'a>>
1279 for traits::VtableObjectData<'gcx, N> where N: HashStable<StableHashingContext<'a>> {
1280     fn hash_stable<W: StableHasherResult>(&self,
1281                                           hcx: &mut StableHashingContext<'a>,
1282                                           hasher: &mut StableHasher<W>) {
1283         let traits::VtableObjectData {
1284             upcast_trait_ref,
1285             vtable_base,
1286             ref nested,
1287         } = *self;
1288         upcast_trait_ref.hash_stable(hcx, hasher);
1289         vtable_base.hash_stable(hcx, hasher);
1290         nested.hash_stable(hcx, hasher);
1291     }
1292 }
1293
1294 impl<'a, 'gcx, N> HashStable<StableHashingContext<'a>>
1295 for traits::VtableBuiltinData<N> where N: HashStable<StableHashingContext<'a>> {
1296     fn hash_stable<W: StableHasherResult>(&self,
1297                                           hcx: &mut StableHashingContext<'a>,
1298                                           hasher: &mut StableHasher<W>) {
1299         let traits::VtableBuiltinData {
1300             ref nested,
1301         } = *self;
1302         nested.hash_stable(hcx, hasher);
1303     }
1304 }
1305
1306 impl<'a, 'gcx, N> HashStable<StableHashingContext<'a>>
1307 for traits::VtableClosureData<'gcx, N> where N: HashStable<StableHashingContext<'a>> {
1308     fn hash_stable<W: StableHasherResult>(&self,
1309                                           hcx: &mut StableHashingContext<'a>,
1310                                           hasher: &mut StableHasher<W>) {
1311         let traits::VtableClosureData {
1312             closure_def_id,
1313             substs,
1314             ref nested,
1315         } = *self;
1316         closure_def_id.hash_stable(hcx, hasher);
1317         substs.hash_stable(hcx, hasher);
1318         nested.hash_stable(hcx, hasher);
1319     }
1320 }
1321
1322 impl<'a, 'gcx, N> HashStable<StableHashingContext<'a>>
1323 for traits::VtableFnPointerData<'gcx, N> where N: HashStable<StableHashingContext<'a>> {
1324     fn hash_stable<W: StableHasherResult>(&self,
1325                                           hcx: &mut StableHashingContext<'a>,
1326                                           hasher: &mut StableHasher<W>) {
1327         let traits::VtableFnPointerData {
1328             fn_ty,
1329             ref nested,
1330         } = *self;
1331         fn_ty.hash_stable(hcx, hasher);
1332         nested.hash_stable(hcx, hasher);
1333     }
1334 }
1335
1336 impl<'a, 'gcx, N> HashStable<StableHashingContext<'a>>
1337 for traits::VtableGeneratorData<'gcx, N> where N: HashStable<StableHashingContext<'a>> {
1338     fn hash_stable<W: StableHasherResult>(&self,
1339                                           hcx: &mut StableHashingContext<'a>,
1340                                           hasher: &mut StableHasher<W>) {
1341         let traits::VtableGeneratorData {
1342             generator_def_id,
1343             substs,
1344             ref nested,
1345         } = *self;
1346         generator_def_id.hash_stable(hcx, hasher);
1347         substs.hash_stable(hcx, hasher);
1348         nested.hash_stable(hcx, hasher);
1349     }
1350 }
1351
1352 impl_stable_hash_for!(
1353     impl<'tcx, V> for struct infer::canonical::Canonical<'tcx, V> {
1354         variables, value
1355     }
1356 );
1357
1358 impl_stable_hash_for!(
1359     impl<'tcx> for struct infer::canonical::CanonicalVarValues<'tcx> {
1360         var_values
1361     }
1362 );
1363
1364 impl_stable_hash_for!(struct infer::canonical::CanonicalVarInfo {
1365     kind
1366 });
1367
1368 impl_stable_hash_for!(enum infer::canonical::CanonicalVarKind {
1369     Ty(k),
1370     Region
1371 });
1372
1373 impl_stable_hash_for!(enum infer::canonical::CanonicalTyVarKind {
1374     General,
1375     Int,
1376     Float
1377 });
1378
1379 impl_stable_hash_for!(
1380     impl<'tcx, R> for struct infer::canonical::QueryResult<'tcx, R> {
1381         var_values, region_constraints, certainty, value
1382     }
1383 );
1384
1385 impl_stable_hash_for!(enum infer::canonical::Certainty {
1386     Proven, Ambiguous
1387 });
1388
1389 impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for traits::WhereClauseAtom<'tcx> {
1390     fn hash_stable<W: StableHasherResult>(&self,
1391                                           hcx: &mut StableHashingContext<'a>,
1392                                           hasher: &mut StableHasher<W>) {
1393         use traits::WhereClauseAtom::*;
1394
1395         mem::discriminant(self).hash_stable(hcx, hasher);
1396         match self {
1397             Implemented(trait_ref) => trait_ref.hash_stable(hcx, hasher),
1398             ProjectionEq(projection) => projection.hash_stable(hcx, hasher),
1399         }
1400     }
1401 }
1402
1403 impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for traits::DomainGoal<'tcx> {
1404     fn hash_stable<W: StableHasherResult>(&self,
1405                                           hcx: &mut StableHashingContext<'a>,
1406                                           hasher: &mut StableHasher<W>) {
1407         use traits::DomainGoal::*;
1408
1409         mem::discriminant(self).hash_stable(hcx, hasher);
1410         match self {
1411             Holds(where_clause) |
1412             WellFormed(where_clause) |
1413             FromEnv(where_clause) => where_clause.hash_stable(hcx, hasher),
1414
1415             WellFormedTy(ty) => ty.hash_stable(hcx, hasher),
1416             Normalize(projection) => projection.hash_stable(hcx, hasher),
1417             FromEnvTy(ty) => ty.hash_stable(hcx, hasher),
1418             RegionOutlives(predicate) => predicate.hash_stable(hcx, hasher),
1419             TypeOutlives(predicate) => predicate.hash_stable(hcx, hasher),
1420         }
1421     }
1422 }
1423
1424 impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for traits::Goal<'tcx> {
1425     fn hash_stable<W: StableHasherResult>(&self,
1426                                           hcx: &mut StableHashingContext<'a>,
1427                                           hasher: &mut StableHasher<W>) {
1428         use traits::Goal::*;
1429
1430         mem::discriminant(self).hash_stable(hcx, hasher);
1431         match self {
1432             Implies(hypotheses, goal) => {
1433                 hypotheses.hash_stable(hcx, hasher);
1434                 goal.hash_stable(hcx, hasher);
1435             },
1436             And(goal1, goal2) => {
1437                 goal1.hash_stable(hcx, hasher);
1438                 goal2.hash_stable(hcx, hasher);
1439             }
1440             Not(goal) => goal.hash_stable(hcx, hasher),
1441             DomainGoal(domain_goal) => domain_goal.hash_stable(hcx, hasher),
1442             Quantified(quantifier, goal) => {
1443                 quantifier.hash_stable(hcx, hasher);
1444                 goal.hash_stable(hcx, hasher);
1445             },
1446             CannotProve => { },
1447         }
1448     }
1449 }
1450
1451 impl_stable_hash_for!(
1452     impl<'tcx> for struct traits::ProgramClause<'tcx> {
1453         goal, hypotheses
1454     }
1455 );
1456
1457 impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for traits::Clause<'tcx> {
1458     fn hash_stable<W: StableHasherResult>(&self,
1459                                           hcx: &mut StableHashingContext<'a>,
1460                                           hasher: &mut StableHasher<W>) {
1461         use traits::Clause::*;
1462
1463         mem::discriminant(self).hash_stable(hcx, hasher);
1464         match self {
1465             Implies(clause) => clause.hash_stable(hcx, hasher),
1466             ForAll(clause) => clause.hash_stable(hcx, hasher),
1467         }
1468     }
1469 }
1470
1471 impl_stable_hash_for!(enum traits::QuantifierKind {
1472     Universal,
1473     Existential
1474 });