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