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