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