]> git.lizzy.rs Git - rust.git/blob - src/librustc/ich/impls_ty.rs
Merge branch 'refactor-select' of https://github.com/aravind-pg/rust into update...
[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 traits;
23 use ty;
24
25 impl<'gcx, T> HashStable<StableHashingContext<'gcx>>
26 for &'gcx ty::Slice<T>
27     where T: HashStable<StableHashingContext<'gcx>> {
28     fn hash_stable<W: StableHasherResult>(&self,
29                                           hcx: &mut StableHashingContext<'gcx>,
30                                           hasher: &mut StableHasher<W>) {
31         thread_local! {
32             static CACHE: RefCell<FxHashMap<(usize, usize), Fingerprint>> =
33                 RefCell::new(FxHashMap());
34         }
35
36         let hash = CACHE.with(|cache| {
37             let key = (self.as_ptr() as usize, self.len());
38             if let Some(&hash) = cache.borrow().get(&key) {
39                 return hash;
40             }
41
42             let mut hasher = StableHasher::new();
43             (&self[..]).hash_stable(hcx, &mut hasher);
44
45             let hash: Fingerprint = hasher.finish();
46             cache.borrow_mut().insert(key, hash);
47             hash
48         });
49
50         hash.hash_stable(hcx, hasher);
51     }
52 }
53
54 impl<'gcx> HashStable<StableHashingContext<'gcx>>
55 for ty::subst::Kind<'gcx> {
56     fn hash_stable<W: StableHasherResult>(&self,
57                                           hcx: &mut StableHashingContext<'gcx>,
58                                           hasher: &mut StableHasher<W>) {
59         self.unpack().hash_stable(hcx, hasher);
60     }
61 }
62
63 impl<'gcx> HashStable<StableHashingContext<'gcx>>
64 for ty::subst::UnpackedKind<'gcx> {
65     fn hash_stable<W: StableHasherResult>(&self,
66                                           hcx: &mut StableHashingContext<'gcx>,
67                                           hasher: &mut StableHasher<W>) {
68         match self {
69             ty::subst::UnpackedKind::Lifetime(lt) => lt.hash_stable(hcx, hasher),
70             ty::subst::UnpackedKind::Type(ty) => ty.hash_stable(hcx, hasher),
71         }
72     }
73 }
74
75 impl<'gcx> HashStable<StableHashingContext<'gcx>>
76 for ty::RegionKind {
77     fn hash_stable<W: StableHasherResult>(&self,
78                                           hcx: &mut StableHashingContext<'gcx>,
79                                           hasher: &mut StableHasher<W>) {
80         mem::discriminant(self).hash_stable(hcx, hasher);
81         match *self {
82             ty::ReErased |
83             ty::ReStatic |
84             ty::ReEmpty => {
85                 // No variant fields to hash for these ...
86             }
87             ty::ReLateBound(db, ty::BrAnon(i)) => {
88                 db.depth.hash_stable(hcx, hasher);
89                 i.hash_stable(hcx, hasher);
90             }
91             ty::ReLateBound(db, ty::BrNamed(def_id, name)) => {
92                 db.depth.hash_stable(hcx, hasher);
93                 def_id.hash_stable(hcx, hasher);
94                 name.hash_stable(hcx, hasher);
95             }
96             ty::ReLateBound(db, ty::BrEnv) => {
97                 db.depth.hash_stable(hcx, hasher);
98             }
99             ty::ReEarlyBound(ty::EarlyBoundRegion { def_id, index, name }) => {
100                 def_id.hash_stable(hcx, hasher);
101                 index.hash_stable(hcx, hasher);
102                 name.hash_stable(hcx, hasher);
103             }
104             ty::ReScope(scope) => {
105                 scope.hash_stable(hcx, hasher);
106             }
107             ty::ReFree(ref free_region) => {
108                 free_region.hash_stable(hcx, hasher);
109             }
110             ty::ReClosureBound(vid) => {
111                 vid.hash_stable(hcx, hasher);
112             }
113             ty::ReLateBound(..) |
114             ty::ReVar(..) |
115             ty::ReSkolemized(..) => {
116                 bug!("TypeIdHasher: unexpected region {:?}", *self)
117             }
118         }
119     }
120 }
121
122 impl<'gcx> HashStable<StableHashingContext<'gcx>> for ty::RegionVid {
123     #[inline]
124     fn hash_stable<W: StableHasherResult>(&self,
125                                           hcx: &mut StableHashingContext<'gcx>,
126                                           hasher: &mut StableHasher<W>) {
127         use rustc_data_structures::indexed_vec::Idx;
128         self.index().hash_stable(hcx, hasher);
129     }
130 }
131
132 impl<'gcx> HashStable<StableHashingContext<'gcx>>
133 for ty::adjustment::AutoBorrow<'gcx> {
134     fn hash_stable<W: StableHasherResult>(&self,
135                                           hcx: &mut StableHashingContext<'gcx>,
136                                           hasher: &mut StableHasher<W>) {
137         mem::discriminant(self).hash_stable(hcx, hasher);
138         match *self {
139             ty::adjustment::AutoBorrow::Ref(ref region, mutability) => {
140                 region.hash_stable(hcx, hasher);
141                 mutability.hash_stable(hcx, hasher);
142             }
143             ty::adjustment::AutoBorrow::RawPtr(mutability) => {
144                 mutability.hash_stable(hcx, hasher);
145             }
146         }
147     }
148 }
149
150 impl<'gcx> HashStable<StableHashingContext<'gcx>>
151 for ty::adjustment::Adjust<'gcx> {
152     fn hash_stable<W: StableHasherResult>(&self,
153                                           hcx: &mut StableHashingContext<'gcx>,
154                                           hasher: &mut StableHasher<W>) {
155         mem::discriminant(self).hash_stable(hcx, hasher);
156         match *self {
157             ty::adjustment::Adjust::NeverToAny |
158             ty::adjustment::Adjust::ReifyFnPointer |
159             ty::adjustment::Adjust::UnsafeFnPointer |
160             ty::adjustment::Adjust::ClosureFnPointer |
161             ty::adjustment::Adjust::MutToConstPointer |
162             ty::adjustment::Adjust::Unsize => {}
163             ty::adjustment::Adjust::Deref(ref overloaded) => {
164                 overloaded.hash_stable(hcx, hasher);
165             }
166             ty::adjustment::Adjust::Borrow(ref autoref) => {
167                 autoref.hash_stable(hcx, hasher);
168             }
169         }
170     }
171 }
172
173 impl_stable_hash_for!(struct ty::adjustment::Adjustment<'tcx> { kind, target });
174 impl_stable_hash_for!(struct ty::adjustment::OverloadedDeref<'tcx> { region, mutbl });
175 impl_stable_hash_for!(struct ty::UpvarBorrow<'tcx> { kind, region });
176
177 impl<'gcx> HashStable<StableHashingContext<'gcx>> for ty::adjustment::AutoBorrowMutability {
178     fn hash_stable<W: StableHasherResult>(&self,
179                                           hcx: &mut StableHashingContext<'gcx>,
180                                           hasher: &mut StableHasher<W>) {
181         mem::discriminant(self).hash_stable(hcx, hasher);
182         match *self {
183             ty::adjustment::AutoBorrowMutability::Mutable { ref allow_two_phase_borrow } => {
184                 allow_two_phase_borrow.hash_stable(hcx, hasher);
185             }
186             ty::adjustment::AutoBorrowMutability::Immutable => {}
187         }
188     }
189 }
190
191 impl_stable_hash_for!(struct ty::UpvarId { var_id, closure_expr_id });
192
193 impl_stable_hash_for!(enum ty::BorrowKind {
194     ImmBorrow,
195     UniqueImmBorrow,
196     MutBorrow
197 });
198
199 impl<'gcx> HashStable<StableHashingContext<'gcx>>
200 for ty::UpvarCapture<'gcx> {
201     fn hash_stable<W: StableHasherResult>(&self,
202                                           hcx: &mut StableHashingContext<'gcx>,
203                                           hasher: &mut StableHasher<W>) {
204         mem::discriminant(self).hash_stable(hcx, hasher);
205         match *self {
206             ty::UpvarCapture::ByValue => {}
207             ty::UpvarCapture::ByRef(ref up_var_borrow) => {
208                 up_var_borrow.hash_stable(hcx, hasher);
209             }
210         }
211     }
212 }
213
214 impl_stable_hash_for!(struct ty::GenSig<'tcx> {
215     yield_ty,
216     return_ty
217 });
218
219 impl_stable_hash_for!(struct ty::FnSig<'tcx> {
220     inputs_and_output,
221     variadic,
222     unsafety,
223     abi
224 });
225
226 impl<'gcx, T> HashStable<StableHashingContext<'gcx>> for ty::Binder<T>
227     where T: HashStable<StableHashingContext<'gcx>>
228 {
229     fn hash_stable<W: StableHasherResult>(&self,
230                                           hcx: &mut StableHashingContext<'gcx>,
231                                           hasher: &mut StableHasher<W>) {
232         let ty::Binder(ref inner) = *self;
233         inner.hash_stable(hcx, hasher);
234     }
235 }
236
237 impl_stable_hash_for!(enum ty::ClosureKind { Fn, FnMut, FnOnce });
238
239 impl_stable_hash_for!(enum ty::Visibility {
240     Public,
241     Restricted(def_id),
242     Invisible
243 });
244
245 impl_stable_hash_for!(struct ty::TraitRef<'tcx> { def_id, substs });
246 impl_stable_hash_for!(struct ty::TraitPredicate<'tcx> { trait_ref });
247 impl_stable_hash_for!(struct ty::SubtypePredicate<'tcx> { a_is_expected, a, b });
248
249 impl<'gcx, A, B> HashStable<StableHashingContext<'gcx>>
250 for ty::OutlivesPredicate<A, B>
251     where A: HashStable<StableHashingContext<'gcx>>,
252           B: HashStable<StableHashingContext<'gcx>>,
253 {
254     fn hash_stable<W: StableHasherResult>(&self,
255                                           hcx: &mut StableHashingContext<'gcx>,
256                                           hasher: &mut StableHasher<W>) {
257         let ty::OutlivesPredicate(ref a, ref b) = *self;
258         a.hash_stable(hcx, hasher);
259         b.hash_stable(hcx, hasher);
260     }
261 }
262
263 impl_stable_hash_for!(struct ty::ProjectionPredicate<'tcx> { projection_ty, ty });
264 impl_stable_hash_for!(struct ty::ProjectionTy<'tcx> { substs, item_def_id });
265
266
267 impl<'gcx> HashStable<StableHashingContext<'gcx>> for ty::Predicate<'gcx> {
268     fn hash_stable<W: StableHasherResult>(&self,
269                                           hcx: &mut StableHashingContext<'gcx>,
270                                           hasher: &mut StableHasher<W>) {
271         mem::discriminant(self).hash_stable(hcx, hasher);
272         match *self {
273             ty::Predicate::Trait(ref pred) => {
274                 pred.hash_stable(hcx, hasher);
275             }
276             ty::Predicate::Subtype(ref pred) => {
277                 pred.hash_stable(hcx, hasher);
278             }
279             ty::Predicate::RegionOutlives(ref pred) => {
280                 pred.hash_stable(hcx, hasher);
281             }
282             ty::Predicate::TypeOutlives(ref pred) => {
283                 pred.hash_stable(hcx, hasher);
284             }
285             ty::Predicate::Projection(ref pred) => {
286                 pred.hash_stable(hcx, hasher);
287             }
288             ty::Predicate::WellFormed(ty) => {
289                 ty.hash_stable(hcx, hasher);
290             }
291             ty::Predicate::ObjectSafe(def_id) => {
292                 def_id.hash_stable(hcx, hasher);
293             }
294             ty::Predicate::ClosureKind(def_id, closure_substs, closure_kind) => {
295                 def_id.hash_stable(hcx, hasher);
296                 closure_substs.hash_stable(hcx, hasher);
297                 closure_kind.hash_stable(hcx, hasher);
298             }
299             ty::Predicate::ConstEvaluatable(def_id, substs) => {
300                 def_id.hash_stable(hcx, hasher);
301                 substs.hash_stable(hcx, hasher);
302             }
303         }
304     }
305 }
306
307 impl<'gcx> HashStable<StableHashingContext<'gcx>> for ty::AdtFlags {
308     fn hash_stable<W: StableHasherResult>(&self,
309                                           _: &mut StableHashingContext<'gcx>,
310                                           hasher: &mut StableHasher<W>) {
311         std_hash::Hash::hash(self, hasher);
312     }
313 }
314
315 impl_stable_hash_for!(struct ty::VariantDef {
316     did,
317     name,
318     discr,
319     fields,
320     ctor_kind
321 });
322
323 impl_stable_hash_for!(enum ty::VariantDiscr {
324     Explicit(def_id),
325     Relative(distance)
326 });
327
328 impl_stable_hash_for!(struct ty::FieldDef {
329     did,
330     name,
331     vis
332 });
333
334 impl<'gcx> HashStable<StableHashingContext<'gcx>>
335 for ::middle::const_val::ConstVal<'gcx> {
336     fn hash_stable<W: StableHasherResult>(&self,
337                                           hcx: &mut StableHashingContext<'gcx>,
338                                           hasher: &mut StableHasher<W>) {
339         use middle::const_val::ConstVal::*;
340         use middle::const_val::ConstAggregate::*;
341
342         mem::discriminant(self).hash_stable(hcx, hasher);
343
344         match *self {
345             Integral(ref value) => {
346                 value.hash_stable(hcx, hasher);
347             }
348             Float(ref value) => {
349                 value.hash_stable(hcx, hasher);
350             }
351             Str(ref value) => {
352                 value.hash_stable(hcx, hasher);
353             }
354             ByteStr(ref value) => {
355                 value.hash_stable(hcx, hasher);
356             }
357             Bool(value) => {
358                 value.hash_stable(hcx, hasher);
359             }
360             Char(value) => {
361                 value.hash_stable(hcx, hasher);
362             }
363             Variant(def_id) => {
364                 def_id.hash_stable(hcx, hasher);
365             }
366             Function(def_id, substs) => {
367                 def_id.hash_stable(hcx, hasher);
368                 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
369                     substs.hash_stable(hcx, hasher);
370                 });
371             }
372             Aggregate(Struct(ref name_values)) => {
373                 let mut values = name_values.to_vec();
374                 values.sort_unstable_by_key(|&(ref name, _)| name.clone());
375                 values.hash_stable(hcx, hasher);
376             }
377             Aggregate(Tuple(ref value)) => {
378                 value.hash_stable(hcx, hasher);
379             }
380             Aggregate(Array(ref value)) => {
381                 value.hash_stable(hcx, hasher);
382             }
383             Aggregate(Repeat(ref value, times)) => {
384                 value.hash_stable(hcx, hasher);
385                 times.hash_stable(hcx, hasher);
386             }
387             Unevaluated(def_id, substs) => {
388                 def_id.hash_stable(hcx, hasher);
389                 substs.hash_stable(hcx, hasher);
390             }
391         }
392     }
393 }
394
395 impl_stable_hash_for!(struct ::middle::const_val::ByteArray<'tcx> {
396     data
397 });
398
399 impl_stable_hash_for!(struct ty::Const<'tcx> {
400     ty,
401     val
402 });
403
404 impl_stable_hash_for!(struct ::middle::const_val::ConstEvalErr<'tcx> {
405     span,
406     kind
407 });
408
409 impl<'gcx> HashStable<StableHashingContext<'gcx>>
410 for ::middle::const_val::ErrKind<'gcx> {
411     fn hash_stable<W: StableHasherResult>(&self,
412                                           hcx: &mut StableHashingContext<'gcx>,
413                                           hasher: &mut StableHasher<W>) {
414         use middle::const_val::ErrKind::*;
415
416         mem::discriminant(self).hash_stable(hcx, hasher);
417
418         match *self {
419             CannotCast |
420             MissingStructField |
421             NonConstPath |
422             ExpectedConstTuple |
423             ExpectedConstStruct |
424             IndexedNonVec |
425             IndexNotUsize |
426             MiscBinaryOp |
427             MiscCatchAll |
428             IndexOpFeatureGated |
429             TypeckError |
430             CheckMatchError => {
431                 // nothing to do
432             }
433             UnimplementedConstVal(s) => {
434                 s.hash_stable(hcx, hasher);
435             }
436             IndexOutOfBounds { len, index } => {
437                 len.hash_stable(hcx, hasher);
438                 index.hash_stable(hcx, hasher);
439             }
440             Math(ref const_math_err) => {
441                 const_math_err.hash_stable(hcx, hasher);
442             }
443             LayoutError(ref layout_error) => {
444                 layout_error.hash_stable(hcx, hasher);
445             }
446             ErroneousReferencedConstant(ref const_val) => {
447                 const_val.hash_stable(hcx, hasher);
448             }
449         }
450     }
451 }
452
453 impl_stable_hash_for!(struct ty::ClosureSubsts<'tcx> { substs });
454
455 impl_stable_hash_for!(struct ty::GeneratorInterior<'tcx> { witness, movable });
456
457 impl_stable_hash_for!(struct ty::GenericPredicates<'tcx> {
458     parent,
459     predicates
460 });
461
462 impl_stable_hash_for!(enum ty::Variance {
463     Covariant,
464     Invariant,
465     Contravariant,
466     Bivariant
467 });
468
469 impl_stable_hash_for!(enum ty::adjustment::CustomCoerceUnsized {
470     Struct(index)
471 });
472
473 impl<'gcx> HashStable<StableHashingContext<'gcx>> for ty::Generics {
474     fn hash_stable<W: StableHasherResult>(&self,
475                                           hcx: &mut StableHashingContext<'gcx>,
476                                           hasher: &mut StableHasher<W>) {
477         let ty::Generics {
478             parent,
479             parent_regions,
480             parent_types,
481             ref regions,
482             ref types,
483
484             // Reverse map to each `TypeParameterDef`'s `index` field, from
485             // `def_id.index` (`def_id.krate` is the same as the item's).
486             type_param_to_index: _, // Don't hash this
487             has_self,
488             has_late_bound_regions,
489         } = *self;
490
491         parent.hash_stable(hcx, hasher);
492         parent_regions.hash_stable(hcx, hasher);
493         parent_types.hash_stable(hcx, hasher);
494         regions.hash_stable(hcx, hasher);
495         types.hash_stable(hcx, hasher);
496         has_self.hash_stable(hcx, hasher);
497         has_late_bound_regions.hash_stable(hcx, hasher);
498     }
499 }
500
501 impl<'gcx> HashStable<StableHashingContext<'gcx>>
502 for ty::RegionParameterDef {
503     fn hash_stable<W: StableHasherResult>(&self,
504                                           hcx: &mut StableHashingContext<'gcx>,
505                                           hasher: &mut StableHasher<W>) {
506         let ty::RegionParameterDef {
507             name,
508             def_id,
509             index,
510             pure_wrt_drop
511         } = *self;
512
513         name.hash_stable(hcx, hasher);
514         def_id.hash_stable(hcx, hasher);
515         index.hash_stable(hcx, hasher);
516         pure_wrt_drop.hash_stable(hcx, hasher);
517     }
518 }
519
520 impl_stable_hash_for!(struct ty::TypeParameterDef {
521     name,
522     def_id,
523     index,
524     has_default,
525     object_lifetime_default,
526     pure_wrt_drop,
527     synthetic
528 });
529
530 impl<'gcx, T> HashStable<StableHashingContext<'gcx>>
531 for ::middle::resolve_lifetime::Set1<T>
532     where T: HashStable<StableHashingContext<'gcx>>
533 {
534     fn hash_stable<W: StableHasherResult>(&self,
535                                           hcx: &mut StableHashingContext<'gcx>,
536                                           hasher: &mut StableHasher<W>) {
537         use middle::resolve_lifetime::Set1;
538
539         mem::discriminant(self).hash_stable(hcx, hasher);
540         match *self {
541             Set1::Empty |
542             Set1::Many => {
543                 // Nothing to do.
544             }
545             Set1::One(ref value) => {
546                 value.hash_stable(hcx, hasher);
547             }
548         }
549     }
550 }
551
552 impl_stable_hash_for!(enum ::middle::resolve_lifetime::LifetimeDefOrigin {
553     Explicit,
554     InBand
555 });
556
557 impl_stable_hash_for!(enum ::middle::resolve_lifetime::Region {
558     Static,
559     EarlyBound(index, decl, is_in_band),
560     LateBound(db_index, decl, is_in_band),
561     LateBoundAnon(db_index, anon_index),
562     Free(call_site_scope_data, decl)
563 });
564
565 impl_stable_hash_for!(struct ty::DebruijnIndex {
566     depth
567 });
568
569 impl_stable_hash_for!(enum ty::cast::CastKind {
570     CoercionCast,
571     PtrPtrCast,
572     PtrAddrCast,
573     AddrPtrCast,
574     NumericCast,
575     EnumCast,
576     PrimIntCast,
577     U8CharCast,
578     ArrayPtrCast,
579     FnPtrPtrCast,
580     FnPtrAddrCast
581 });
582
583 impl_stable_hash_for!(tuple_struct ::middle::region::FirstStatementIndex { idx });
584 impl_stable_hash_for!(struct ::middle::region::Scope { id, code });
585
586 impl<'gcx> ToStableHashKey<StableHashingContext<'gcx>> for region::Scope {
587     type KeyType = region::Scope;
588
589     #[inline]
590     fn to_stable_hash_key(&self, _: &StableHashingContext<'gcx>) -> region::Scope {
591         *self
592     }
593 }
594
595 impl_stable_hash_for!(struct ::middle::region::BlockRemainder {
596     block,
597     first_statement_index
598 });
599
600 impl_stable_hash_for!(struct ty::adjustment::CoerceUnsizedInfo {
601     custom_kind
602 });
603
604 impl_stable_hash_for!(struct ty::FreeRegion {
605     scope,
606     bound_region
607 });
608
609 impl_stable_hash_for!(enum ty::BoundRegion {
610     BrAnon(index),
611     BrNamed(def_id, name),
612     BrFresh(index),
613     BrEnv
614 });
615
616 impl<'gcx> HashStable<StableHashingContext<'gcx>>
617 for ty::TypeVariants<'gcx>
618 {
619     fn hash_stable<W: StableHasherResult>(&self,
620                                           hcx: &mut StableHashingContext<'gcx>,
621                                           hasher: &mut StableHasher<W>) {
622         use ty::TypeVariants::*;
623
624         mem::discriminant(self).hash_stable(hcx, hasher);
625         match *self {
626             TyBool  |
627             TyChar  |
628             TyStr   |
629             TyError |
630             TyNever => {
631                 // Nothing more to hash.
632             }
633             TyInt(int_ty) => {
634                 int_ty.hash_stable(hcx, hasher);
635             }
636             TyUint(uint_ty) => {
637                 uint_ty.hash_stable(hcx, hasher);
638             }
639             TyFloat(float_ty)  => {
640                 float_ty.hash_stable(hcx, hasher);
641             }
642             TyAdt(adt_def, substs) => {
643                 adt_def.hash_stable(hcx, hasher);
644                 substs.hash_stable(hcx, hasher);
645             }
646             TyArray(inner_ty, len) => {
647                 inner_ty.hash_stable(hcx, hasher);
648                 len.hash_stable(hcx, hasher);
649             }
650             TySlice(inner_ty) => {
651                 inner_ty.hash_stable(hcx, hasher);
652             }
653             TyRawPtr(pointee_ty) => {
654                 pointee_ty.hash_stable(hcx, hasher);
655             }
656             TyRef(region, pointee_ty) => {
657                 region.hash_stable(hcx, hasher);
658                 pointee_ty.hash_stable(hcx, hasher);
659             }
660             TyFnDef(def_id, substs) => {
661                 def_id.hash_stable(hcx, hasher);
662                 substs.hash_stable(hcx, hasher);
663             }
664             TyFnPtr(ref sig) => {
665                 sig.hash_stable(hcx, hasher);
666             }
667             TyDynamic(ref existential_predicates, region) => {
668                 existential_predicates.hash_stable(hcx, hasher);
669                 region.hash_stable(hcx, hasher);
670             }
671             TyClosure(def_id, closure_substs) => {
672                 def_id.hash_stable(hcx, hasher);
673                 closure_substs.hash_stable(hcx, hasher);
674             }
675             TyGenerator(def_id, closure_substs, interior) => {
676                 def_id.hash_stable(hcx, hasher);
677                 closure_substs.hash_stable(hcx, hasher);
678                 interior.hash_stable(hcx, hasher);
679             }
680             TyGeneratorWitness(types) => {
681                 types.hash_stable(hcx, hasher)
682             }
683             TyTuple(inner_tys, from_diverging_type_var) => {
684                 inner_tys.hash_stable(hcx, hasher);
685                 from_diverging_type_var.hash_stable(hcx, hasher);
686             }
687             TyProjection(ref projection_ty) => {
688                 projection_ty.hash_stable(hcx, hasher);
689             }
690             TyAnon(def_id, substs) => {
691                 def_id.hash_stable(hcx, hasher);
692                 substs.hash_stable(hcx, hasher);
693             }
694             TyParam(param_ty) => {
695                 param_ty.hash_stable(hcx, hasher);
696             }
697             TyForeign(def_id) => {
698                 def_id.hash_stable(hcx, hasher);
699             }
700             TyInfer(..) => {
701                 bug!("ty::TypeVariants::hash_stable() - Unexpected variant {:?}.", *self)
702             }
703         }
704     }
705 }
706
707 impl_stable_hash_for!(struct ty::ParamTy {
708     idx,
709     name
710 });
711
712 impl_stable_hash_for!(struct ty::TypeAndMut<'tcx> {
713     ty,
714     mutbl
715 });
716
717 impl<'gcx> HashStable<StableHashingContext<'gcx>>
718 for ty::ExistentialPredicate<'gcx>
719 {
720     fn hash_stable<W: StableHasherResult>(&self,
721                                           hcx: &mut StableHashingContext<'gcx>,
722                                           hasher: &mut StableHasher<W>) {
723         mem::discriminant(self).hash_stable(hcx, hasher);
724         match *self {
725             ty::ExistentialPredicate::Trait(ref trait_ref) => {
726                 trait_ref.hash_stable(hcx, hasher);
727             }
728             ty::ExistentialPredicate::Projection(ref projection) => {
729                 projection.hash_stable(hcx, hasher);
730             }
731             ty::ExistentialPredicate::AutoTrait(def_id) => {
732                 def_id.hash_stable(hcx, hasher);
733             }
734         }
735     }
736 }
737
738 impl_stable_hash_for!(struct ty::ExistentialTraitRef<'tcx> {
739     def_id,
740     substs
741 });
742
743 impl_stable_hash_for!(struct ty::ExistentialProjection<'tcx> {
744     item_def_id,
745     substs,
746     ty
747 });
748
749 impl_stable_hash_for!(struct ty::Instance<'tcx> {
750     def,
751     substs
752 });
753
754 impl<'gcx> HashStable<StableHashingContext<'gcx>> for ty::InstanceDef<'gcx> {
755     fn hash_stable<W: StableHasherResult>(&self,
756                                           hcx: &mut StableHashingContext<'gcx>,
757                                           hasher: &mut StableHasher<W>) {
758         mem::discriminant(self).hash_stable(hcx, hasher);
759
760         match *self {
761             ty::InstanceDef::Item(def_id) => {
762                 def_id.hash_stable(hcx, hasher);
763             }
764             ty::InstanceDef::Intrinsic(def_id) => {
765                 def_id.hash_stable(hcx, hasher);
766             }
767             ty::InstanceDef::FnPtrShim(def_id, ty) => {
768                 def_id.hash_stable(hcx, hasher);
769                 ty.hash_stable(hcx, hasher);
770             }
771             ty::InstanceDef::Virtual(def_id, n) => {
772                 def_id.hash_stable(hcx, hasher);
773                 n.hash_stable(hcx, hasher);
774             }
775             ty::InstanceDef::ClosureOnceShim { call_once } => {
776                 call_once.hash_stable(hcx, hasher);
777             }
778             ty::InstanceDef::DropGlue(def_id, t) => {
779                 def_id.hash_stable(hcx, hasher);
780                 t.hash_stable(hcx, hasher);
781             }
782             ty::InstanceDef::CloneShim(def_id, t) => {
783                 def_id.hash_stable(hcx, hasher);
784                 t.hash_stable(hcx, hasher);
785             }
786         }
787     }
788 }
789
790 impl<'gcx> HashStable<StableHashingContext<'gcx>> for ty::TraitDef {
791     fn hash_stable<W: StableHasherResult>(&self,
792                                           hcx: &mut StableHashingContext<'gcx>,
793                                           hasher: &mut StableHasher<W>) {
794         let ty::TraitDef {
795             // We already have the def_path_hash below, no need to hash it twice
796             def_id: _,
797             unsafety,
798             paren_sugar,
799             has_auto_impl,
800             def_path_hash,
801         } = *self;
802
803         unsafety.hash_stable(hcx, hasher);
804         paren_sugar.hash_stable(hcx, hasher);
805         has_auto_impl.hash_stable(hcx, hasher);
806         def_path_hash.hash_stable(hcx, hasher);
807     }
808 }
809
810 impl_stable_hash_for!(struct ty::Destructor {
811     did
812 });
813
814 impl_stable_hash_for!(struct ty::DtorckConstraint<'tcx> {
815     outlives,
816     dtorck_types
817 });
818
819
820 impl<'gcx> HashStable<StableHashingContext<'gcx>> for ty::CrateVariancesMap {
821     fn hash_stable<W: StableHasherResult>(&self,
822                                           hcx: &mut StableHashingContext<'gcx>,
823                                           hasher: &mut StableHasher<W>) {
824         let ty::CrateVariancesMap {
825             ref variances,
826             // This is just an irrelevant helper value.
827             empty_variance: _,
828         } = *self;
829
830         variances.hash_stable(hcx, hasher);
831     }
832 }
833
834 impl_stable_hash_for!(struct ty::AssociatedItem {
835     def_id,
836     name,
837     kind,
838     vis,
839     defaultness,
840     container,
841     method_has_self_argument
842 });
843
844 impl_stable_hash_for!(enum ty::AssociatedKind {
845     Const,
846     Method,
847     Type
848 });
849
850 impl_stable_hash_for!(enum ty::AssociatedItemContainer {
851     TraitContainer(def_id),
852     ImplContainer(def_id)
853 });
854
855
856 impl<'gcx, T> HashStable<StableHashingContext<'gcx>>
857 for ty::steal::Steal<T>
858     where T: HashStable<StableHashingContext<'gcx>>
859 {
860     fn hash_stable<W: StableHasherResult>(&self,
861                                           hcx: &mut StableHashingContext<'gcx>,
862                                           hasher: &mut StableHasher<W>) {
863         self.borrow().hash_stable(hcx, hasher);
864     }
865 }
866
867 impl_stable_hash_for!(struct ty::ParamEnv<'tcx> {
868     caller_bounds,
869     universe,
870     reveal
871 });
872
873 impl_stable_hash_for!(enum traits::Reveal {
874     UserFacing,
875     All
876 });
877
878 impl_stable_hash_for!(enum ::middle::privacy::AccessLevel {
879     Reachable,
880     Exported,
881     Public
882 });
883
884 impl<'gcx> HashStable<StableHashingContext<'gcx>>
885 for ::middle::privacy::AccessLevels {
886     fn hash_stable<W: StableHasherResult>(&self,
887                                           hcx: &mut StableHashingContext<'gcx>,
888                                           hasher: &mut StableHasher<W>) {
889         hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
890             let ::middle::privacy::AccessLevels {
891                 ref map
892             } = *self;
893
894             map.hash_stable(hcx, hasher);
895         });
896     }
897 }
898
899 impl_stable_hash_for!(struct ty::CrateInherentImpls {
900     inherent_impls
901 });
902
903 impl_stable_hash_for!(enum ::session::CompileIncomplete {
904     Stopped,
905     Errored(error_reported)
906 });
907
908 impl_stable_hash_for!(struct ::util::common::ErrorReported {});
909
910 impl_stable_hash_for!(tuple_struct ::middle::reachable::ReachableSet {
911     reachable_set
912 });
913
914 impl<'gcx, N> HashStable<StableHashingContext<'gcx>>
915 for traits::Vtable<'gcx, N> where N: HashStable<StableHashingContext<'gcx>> {
916     fn hash_stable<W: StableHasherResult>(&self,
917                                           hcx: &mut StableHashingContext<'gcx>,
918                                           hasher: &mut StableHasher<W>) {
919         use traits::Vtable::*;
920
921         mem::discriminant(self).hash_stable(hcx, hasher);
922
923         match self {
924             &VtableImpl(ref table_impl) => table_impl.hash_stable(hcx, hasher),
925             &VtableAutoImpl(ref table_def_impl) => table_def_impl.hash_stable(hcx, hasher),
926             &VtableParam(ref table_param) => table_param.hash_stable(hcx, hasher),
927             &VtableObject(ref table_obj) => table_obj.hash_stable(hcx, hasher),
928             &VtableBuiltin(ref table_builtin) => table_builtin.hash_stable(hcx, hasher),
929             &VtableClosure(ref table_closure) => table_closure.hash_stable(hcx, hasher),
930             &VtableFnPointer(ref table_fn_pointer) => table_fn_pointer.hash_stable(hcx, hasher),
931             &VtableGenerator(ref table_generator) => table_generator.hash_stable(hcx, hasher),
932         }
933     }
934 }
935
936 impl<'gcx, N> HashStable<StableHashingContext<'gcx>>
937 for traits::VtableImplData<'gcx, N> where N: HashStable<StableHashingContext<'gcx>> {
938     fn hash_stable<W: StableHasherResult>(&self,
939                                           hcx: &mut StableHashingContext<'gcx>,
940                                           hasher: &mut StableHasher<W>) {
941         let traits::VtableImplData {
942             impl_def_id,
943             substs,
944             ref nested,
945         } = *self;
946         impl_def_id.hash_stable(hcx, hasher);
947         substs.hash_stable(hcx, hasher);
948         nested.hash_stable(hcx, hasher);
949     }
950 }
951
952 impl<'gcx, N> HashStable<StableHashingContext<'gcx>>
953 for traits::VtableAutoImplData<N> where N: HashStable<StableHashingContext<'gcx>> {
954     fn hash_stable<W: StableHasherResult>(&self,
955                                           hcx: &mut StableHashingContext<'gcx>,
956                                           hasher: &mut StableHasher<W>) {
957         let traits::VtableAutoImplData {
958             trait_def_id,
959             ref nested,
960         } = *self;
961         trait_def_id.hash_stable(hcx, hasher);
962         nested.hash_stable(hcx, hasher);
963     }
964 }
965
966 impl<'gcx, N> HashStable<StableHashingContext<'gcx>>
967 for traits::VtableObjectData<'gcx, N> where N: HashStable<StableHashingContext<'gcx>> {
968     fn hash_stable<W: StableHasherResult>(&self,
969                                           hcx: &mut StableHashingContext<'gcx>,
970                                           hasher: &mut StableHasher<W>) {
971         let traits::VtableObjectData {
972             upcast_trait_ref,
973             vtable_base,
974             ref nested,
975         } = *self;
976         upcast_trait_ref.hash_stable(hcx, hasher);
977         vtable_base.hash_stable(hcx, hasher);
978         nested.hash_stable(hcx, hasher);
979     }
980 }
981
982 impl<'gcx, N> HashStable<StableHashingContext<'gcx>>
983 for traits::VtableBuiltinData<N> where N: HashStable<StableHashingContext<'gcx>> {
984     fn hash_stable<W: StableHasherResult>(&self,
985                                           hcx: &mut StableHashingContext<'gcx>,
986                                           hasher: &mut StableHasher<W>) {
987         let traits::VtableBuiltinData {
988             ref nested,
989         } = *self;
990         nested.hash_stable(hcx, hasher);
991     }
992 }
993
994 impl<'gcx, N> HashStable<StableHashingContext<'gcx>>
995 for traits::VtableClosureData<'gcx, N> where N: HashStable<StableHashingContext<'gcx>> {
996     fn hash_stable<W: StableHasherResult>(&self,
997                                           hcx: &mut StableHashingContext<'gcx>,
998                                           hasher: &mut StableHasher<W>) {
999         let traits::VtableClosureData {
1000             closure_def_id,
1001             substs,
1002             ref nested,
1003         } = *self;
1004         closure_def_id.hash_stable(hcx, hasher);
1005         substs.hash_stable(hcx, hasher);
1006         nested.hash_stable(hcx, hasher);
1007     }
1008 }
1009
1010 impl<'gcx, N> HashStable<StableHashingContext<'gcx>>
1011 for traits::VtableFnPointerData<'gcx, N> where N: HashStable<StableHashingContext<'gcx>> {
1012     fn hash_stable<W: StableHasherResult>(&self,
1013                                           hcx: &mut StableHashingContext<'gcx>,
1014                                           hasher: &mut StableHasher<W>) {
1015         let traits::VtableFnPointerData {
1016             fn_ty,
1017             ref nested,
1018         } = *self;
1019         fn_ty.hash_stable(hcx, hasher);
1020         nested.hash_stable(hcx, hasher);
1021     }
1022 }
1023
1024 impl<'gcx, N> HashStable<StableHashingContext<'gcx>>
1025 for traits::VtableGeneratorData<'gcx, N> where N: HashStable<StableHashingContext<'gcx>> {
1026     fn hash_stable<W: StableHasherResult>(&self,
1027                                           hcx: &mut StableHashingContext<'gcx>,
1028                                           hasher: &mut StableHasher<W>) {
1029         let traits::VtableGeneratorData {
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<'gcx> HashStable<StableHashingContext<'gcx>>
1041 for ty::UniverseIndex {
1042     fn hash_stable<W: StableHasherResult>(&self,
1043                                           hcx: &mut StableHashingContext<'gcx>,
1044                                           hasher: &mut StableHasher<W>) {
1045         self.depth().hash_stable(hcx, hasher);
1046     }
1047 }