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