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