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