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