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