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