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