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