]> git.lizzy.rs Git - rust.git/blob - src/librustc/ich/impls_hir.rs
882194ae64e79df096a3df67768edc4a432b512c
[rust.git] / src / librustc / ich / impls_hir.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 HIR data
12 //! types in no particular order.
13
14 use hir;
15 use hir::map::DefPathHash;
16 use hir::def_id::{DefId, LocalDefId, CrateNum, CRATE_DEF_INDEX};
17 use ich::{StableHashingContext, NodeIdHashingMode};
18 use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey,
19                                            StableHasher, StableHasherResult};
20 use std::mem;
21 use syntax::ast;
22 use syntax::attr;
23
24 impl<'a> HashStable<StableHashingContext<'a>> for DefId {
25     #[inline]
26     fn hash_stable<W: StableHasherResult>(&self,
27                                           hcx: &mut StableHashingContext<'a>,
28                                           hasher: &mut StableHasher<W>) {
29         hcx.def_path_hash(*self).hash_stable(hcx, hasher);
30     }
31 }
32
33 impl<'a> ToStableHashKey<StableHashingContext<'a>> for DefId {
34     type KeyType = DefPathHash;
35
36     #[inline]
37     fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
38         hcx.def_path_hash(*self)
39     }
40 }
41
42 impl<'a> HashStable<StableHashingContext<'a>> for LocalDefId {
43     #[inline]
44     fn hash_stable<W: StableHasherResult>(&self,
45                                           hcx: &mut StableHashingContext<'a>,
46                                           hasher: &mut StableHasher<W>) {
47         hcx.def_path_hash(self.to_def_id()).hash_stable(hcx, hasher);
48     }
49 }
50
51 impl<'a> ToStableHashKey<StableHashingContext<'a>> for LocalDefId {
52     type KeyType = DefPathHash;
53
54     #[inline]
55     fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
56         hcx.def_path_hash(self.to_def_id())
57     }
58 }
59
60 impl<'a> HashStable<StableHashingContext<'a>> for CrateNum {
61     #[inline]
62     fn hash_stable<W: StableHasherResult>(&self,
63                                           hcx: &mut StableHashingContext<'a>,
64                                           hasher: &mut StableHasher<W>) {
65         hcx.def_path_hash(DefId {
66             krate: *self,
67             index: CRATE_DEF_INDEX
68         }).hash_stable(hcx, hasher);
69     }
70 }
71
72 impl<'a> ToStableHashKey<StableHashingContext<'a>> for CrateNum {
73     type KeyType = DefPathHash;
74
75     #[inline]
76     fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
77         let def_id = DefId { krate: *self, index: CRATE_DEF_INDEX };
78         def_id.to_stable_hash_key(hcx)
79     }
80 }
81
82 impl_stable_hash_for!(tuple_struct hir::ItemLocalId { index });
83
84 impl<'a> ToStableHashKey<StableHashingContext<'a>>
85 for hir::ItemLocalId {
86     type KeyType = hir::ItemLocalId;
87
88     #[inline]
89     fn to_stable_hash_key(&self,
90                           _: &StableHashingContext<'a>)
91                           -> hir::ItemLocalId {
92         *self
93     }
94 }
95
96 // The following implementations of HashStable for ItemId, TraitItemId, and
97 // ImplItemId deserve special attention. Normally we do not hash NodeIds within
98 // the HIR, since they just signify a HIR nodes own path. But ItemId et al
99 // are used when another item in the HIR is *referenced* and we certainly
100 // want to pick up on a reference changing its target, so we hash the NodeIds
101 // in "DefPath Mode".
102
103 impl<'a> HashStable<StableHashingContext<'a>> for hir::ItemId {
104     fn hash_stable<W: StableHasherResult>(&self,
105                                           hcx: &mut StableHashingContext<'a>,
106                                           hasher: &mut StableHasher<W>) {
107         let hir::ItemId {
108             id
109         } = *self;
110
111         hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
112             id.hash_stable(hcx, hasher);
113         })
114     }
115 }
116
117 impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitItemId {
118     fn hash_stable<W: StableHasherResult>(&self,
119                                           hcx: &mut StableHashingContext<'a>,
120                                           hasher: &mut StableHasher<W>) {
121         let hir::TraitItemId {
122             node_id
123         } = * self;
124
125         hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
126             node_id.hash_stable(hcx, hasher);
127         })
128     }
129 }
130
131 impl<'a> HashStable<StableHashingContext<'a>> for hir::ImplItemId {
132     fn hash_stable<W: StableHasherResult>(&self,
133                                           hcx: &mut StableHashingContext<'a>,
134                                           hasher: &mut StableHasher<W>) {
135         let hir::ImplItemId {
136             node_id
137         } = * self;
138
139         hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
140             node_id.hash_stable(hcx, hasher);
141         })
142     }
143 }
144
145 impl_stable_hash_for!(enum hir::ParamName {
146     Plain(name),
147     Fresh(index)
148 });
149
150 impl_stable_hash_for!(enum hir::LifetimeName {
151     Param(param_name),
152     Implicit,
153     Underscore,
154     Static,
155 });
156
157 impl_stable_hash_for!(struct hir::Label {
158     span,
159     name
160 });
161
162 impl_stable_hash_for!(struct hir::Lifetime {
163     id,
164     span,
165     name
166 });
167
168 impl_stable_hash_for!(struct hir::Path {
169     span,
170     def,
171     segments
172 });
173
174 impl_stable_hash_for!(struct hir::PathSegment {
175     name,
176     infer_types,
177     args
178 });
179
180 impl_stable_hash_for!(enum hir::GenericArg {
181     Lifetime(lt),
182     Type(ty)
183 });
184
185 impl_stable_hash_for!(struct hir::GenericArgs {
186     args,
187     bindings,
188     parenthesized
189 });
190
191 impl_stable_hash_for!(enum hir::GenericBound {
192     Trait(poly_trait_ref, trait_bound_modifier),
193     Outlives(lifetime)
194 });
195
196 impl_stable_hash_for!(enum hir::TraitBoundModifier {
197     None,
198     Maybe
199 });
200
201 impl_stable_hash_for!(struct hir::GenericParam {
202     id,
203     name,
204     span,
205     pure_wrt_drop,
206     attrs,
207     bounds,
208     kind
209 });
210
211 impl<'a> HashStable<StableHashingContext<'a>> for hir::GenericParamKind {
212     fn hash_stable<W: StableHasherResult>(&self,
213                                           hcx: &mut StableHashingContext<'a>,
214                                           hasher: &mut StableHasher<W>) {
215         mem::discriminant(self).hash_stable(hcx, hasher);
216         match self {
217             hir::GenericParamKind::Lifetime { in_band } => {
218                 in_band.hash_stable(hcx, hasher);
219             }
220             hir::GenericParamKind::Type { ref default, synthetic } => {
221                 default.hash_stable(hcx, hasher);
222                 synthetic.hash_stable(hcx, hasher);
223             }
224         }
225     }
226 }
227
228 impl_stable_hash_for!(struct hir::Generics {
229     params,
230     where_clause,
231     span
232 });
233
234 impl_stable_hash_for!(enum hir::SyntheticTyParamKind {
235     ImplTrait
236 });
237
238 impl_stable_hash_for!(struct hir::WhereClause {
239     id,
240     predicates
241 });
242
243 impl_stable_hash_for!(enum hir::WherePredicate {
244     BoundPredicate(pred),
245     RegionPredicate(pred),
246     EqPredicate(pred)
247 });
248
249 impl_stable_hash_for!(struct hir::WhereBoundPredicate {
250     span,
251     bound_generic_params,
252     bounded_ty,
253     bounds
254 });
255
256 impl_stable_hash_for!(struct hir::WhereRegionPredicate {
257     span,
258     lifetime,
259     bounds
260 });
261
262 impl_stable_hash_for!(struct hir::WhereEqPredicate {
263     id,
264     span,
265     lhs_ty,
266     rhs_ty
267 });
268
269 impl_stable_hash_for!(struct hir::MutTy {
270     ty,
271     mutbl
272 });
273
274 impl_stable_hash_for!(struct hir::MethodSig {
275     unsafety,
276     constness,
277     abi,
278     decl
279 });
280
281 impl_stable_hash_for!(struct hir::TypeBinding {
282     id,
283     name,
284     ty,
285     span
286 });
287
288 impl<'a> HashStable<StableHashingContext<'a>> for hir::Ty {
289     fn hash_stable<W: StableHasherResult>(&self,
290                                           hcx: &mut StableHashingContext<'a>,
291                                           hasher: &mut StableHasher<W>) {
292         hcx.while_hashing_hir_bodies(true, |hcx| {
293             let hir::Ty {
294                 id: _,
295                 hir_id: _,
296                 ref node,
297                 ref span,
298             } = *self;
299
300             node.hash_stable(hcx, hasher);
301             span.hash_stable(hcx, hasher);
302         })
303     }
304 }
305
306 impl_stable_hash_for!(enum hir::PrimTy {
307     TyInt(int_ty),
308     TyUint(uint_ty),
309     TyFloat(float_ty),
310     TyStr,
311     TyBool,
312     TyChar
313 });
314
315 impl_stable_hash_for!(struct hir::BareFnTy {
316     unsafety,
317     abi,
318     generic_params,
319     decl,
320     arg_names
321 });
322
323 impl_stable_hash_for!(struct hir::ExistTy {
324     generics,
325     impl_trait_fn,
326     bounds
327 });
328
329 impl_stable_hash_for!(enum hir::Ty_ {
330     TySlice(t),
331     TyArray(t, body_id),
332     TyPtr(t),
333     TyRptr(lifetime, t),
334     TyBareFn(t),
335     TyNever,
336     TyTup(ts),
337     TyPath(qpath),
338     TyTraitObject(trait_refs, lifetime),
339     TyImplTraitExistential(existty, def_id, lifetimes),
340     TyTypeof(body_id),
341     TyErr,
342     TyInfer
343 });
344
345 impl_stable_hash_for!(struct hir::FnDecl {
346     inputs,
347     output,
348     variadic,
349     has_implicit_self
350 });
351
352 impl_stable_hash_for!(enum hir::FunctionRetTy {
353     DefaultReturn(span),
354     Return(t)
355 });
356
357 impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitRef {
358     fn hash_stable<W: StableHasherResult>(&self,
359                                           hcx: &mut StableHashingContext<'a>,
360                                           hasher: &mut StableHasher<W>) {
361         let hir::TraitRef {
362             ref path,
363             // Don't hash the ref_id. It is tracked via the thing it is used to access
364             ref_id: _,
365         } = *self;
366
367         path.hash_stable(hcx, hasher);
368     }
369 }
370
371
372 impl_stable_hash_for!(struct hir::PolyTraitRef {
373     bound_generic_params,
374     trait_ref,
375     span
376 });
377
378 impl_stable_hash_for!(enum hir::QPath {
379     Resolved(t, path),
380     TypeRelative(t, path_segment)
381 });
382
383 impl_stable_hash_for!(struct hir::MacroDef {
384     name,
385     vis,
386     attrs,
387     id,
388     span,
389     legacy,
390     body
391 });
392
393
394 impl<'a> HashStable<StableHashingContext<'a>> for hir::Block {
395     fn hash_stable<W: StableHasherResult>(&self,
396                                           hcx: &mut StableHashingContext<'a>,
397                                           hasher: &mut StableHasher<W>) {
398         let hir::Block {
399             ref stmts,
400             ref expr,
401             id: _,
402             hir_id: _,
403             rules,
404             span,
405             targeted_by_break,
406             recovered,
407         } = *self;
408
409         stmts.hash_stable(hcx, hasher);
410         expr.hash_stable(hcx, hasher);
411         rules.hash_stable(hcx, hasher);
412         span.hash_stable(hcx, hasher);
413         recovered.hash_stable(hcx, hasher);
414         targeted_by_break.hash_stable(hcx, hasher);
415     }
416 }
417
418 impl<'a> HashStable<StableHashingContext<'a>> for hir::Pat {
419     fn hash_stable<W: StableHasherResult>(&self,
420                                           hcx: &mut StableHashingContext<'a>,
421                                           hasher: &mut StableHasher<W>) {
422         let hir::Pat {
423             id: _,
424             hir_id: _,
425             ref node,
426             ref span
427         } = *self;
428
429
430         node.hash_stable(hcx, hasher);
431         span.hash_stable(hcx, hasher);
432     }
433 }
434
435 impl_stable_hash_for_spanned!(hir::FieldPat);
436
437 impl<'a> HashStable<StableHashingContext<'a>> for hir::FieldPat {
438     fn hash_stable<W: StableHasherResult>(&self,
439                                           hcx: &mut StableHashingContext<'a>,
440                                           hasher: &mut StableHasher<W>) {
441         let hir::FieldPat {
442             id: _,
443             ident,
444             ref pat,
445             is_shorthand,
446         } = *self;
447
448         ident.hash_stable(hcx, hasher);
449         pat.hash_stable(hcx, hasher);
450         is_shorthand.hash_stable(hcx, hasher);
451     }
452 }
453
454 impl_stable_hash_for!(enum hir::BindingAnnotation {
455     Unannotated,
456     Mutable,
457     Ref,
458     RefMut
459 });
460
461 impl_stable_hash_for!(enum hir::RangeEnd {
462     Included,
463     Excluded
464 });
465
466 impl_stable_hash_for!(enum hir::PatKind {
467     Wild,
468     Binding(binding_mode, var, name, sub),
469     Struct(path, field_pats, dotdot),
470     TupleStruct(path, field_pats, dotdot),
471     Path(path),
472     Tuple(field_pats, dotdot),
473     Box(sub),
474     Ref(sub, mutability),
475     Lit(expr),
476     Range(start, end, end_kind),
477     Slice(one, two, three)
478 });
479
480 impl_stable_hash_for!(enum hir::BinOp_ {
481     BiAdd,
482     BiSub,
483     BiMul,
484     BiDiv,
485     BiRem,
486     BiAnd,
487     BiOr,
488     BiBitXor,
489     BiBitAnd,
490     BiBitOr,
491     BiShl,
492     BiShr,
493     BiEq,
494     BiLt,
495     BiLe,
496     BiNe,
497     BiGe,
498     BiGt
499 });
500
501 impl_stable_hash_for_spanned!(hir::BinOp_);
502
503 impl_stable_hash_for!(enum hir::UnOp {
504     UnDeref,
505     UnNot,
506     UnNeg
507 });
508
509 impl_stable_hash_for_spanned!(hir::Stmt_);
510
511 impl_stable_hash_for!(struct hir::Local {
512     pat,
513     ty,
514     init,
515     id,
516     hir_id,
517     span,
518     attrs,
519     source
520 });
521
522 impl_stable_hash_for_spanned!(hir::Decl_);
523 impl_stable_hash_for!(enum hir::Decl_ {
524     DeclLocal(local),
525     DeclItem(item_id)
526 });
527
528 impl_stable_hash_for!(struct hir::Arm {
529     attrs,
530     pats,
531     guard,
532     body
533 });
534
535 impl<'a> HashStable<StableHashingContext<'a>> for hir::Field {
536     fn hash_stable<W: StableHasherResult>(&self,
537                                           hcx: &mut StableHashingContext<'a>,
538                                           hasher: &mut StableHasher<W>) {
539         let hir::Field {
540             id: _,
541             ident,
542             ref expr,
543             span,
544             is_shorthand,
545         } = *self;
546
547         ident.hash_stable(hcx, hasher);
548         expr.hash_stable(hcx, hasher);
549         span.hash_stable(hcx, hasher);
550         is_shorthand.hash_stable(hcx, hasher);
551     }
552 }
553
554 impl_stable_hash_for_spanned!(ast::Name);
555
556
557 impl_stable_hash_for!(enum hir::BlockCheckMode {
558     DefaultBlock,
559     UnsafeBlock(src),
560     PushUnsafeBlock(src),
561     PopUnsafeBlock(src)
562 });
563
564 impl_stable_hash_for!(enum hir::UnsafeSource {
565     CompilerGenerated,
566     UserProvided
567 });
568
569 impl_stable_hash_for!(struct hir::AnonConst {
570     id,
571     hir_id,
572     body
573 });
574
575 impl<'a> HashStable<StableHashingContext<'a>> for hir::Expr {
576     fn hash_stable<W: StableHasherResult>(&self,
577                                           hcx: &mut StableHashingContext<'a>,
578                                           hasher: &mut StableHasher<W>) {
579         hcx.while_hashing_hir_bodies(true, |hcx| {
580             let hir::Expr {
581                 id: _,
582                 hir_id: _,
583                 ref span,
584                 ref node,
585                 ref attrs
586             } = *self;
587
588             span.hash_stable(hcx, hasher);
589             node.hash_stable(hcx, hasher);
590             attrs.hash_stable(hcx, hasher);
591         })
592     }
593 }
594
595 impl_stable_hash_for!(enum hir::Expr_ {
596     ExprBox(sub),
597     ExprArray(subs),
598     ExprCall(callee, args),
599     ExprMethodCall(segment, span, args),
600     ExprTup(fields),
601     ExprBinary(op, lhs, rhs),
602     ExprUnary(op, operand),
603     ExprLit(value),
604     ExprCast(expr, t),
605     ExprType(expr, t),
606     ExprIf(cond, then, els),
607     ExprWhile(cond, body, label),
608     ExprLoop(body, label, loop_src),
609     ExprMatch(matchee, arms, match_src),
610     ExprClosure(capture_clause, decl, body_id, span, gen),
611     ExprBlock(blk, label),
612     ExprAssign(lhs, rhs),
613     ExprAssignOp(op, lhs, rhs),
614     ExprField(owner, ident),
615     ExprIndex(lhs, rhs),
616     ExprPath(path),
617     ExprAddrOf(mutability, sub),
618     ExprBreak(destination, sub),
619     ExprAgain(destination),
620     ExprRet(val),
621     ExprInlineAsm(asm, inputs, outputs),
622     ExprStruct(path, fields, base),
623     ExprRepeat(val, times),
624     ExprYield(val)
625 });
626
627 impl_stable_hash_for!(enum hir::LocalSource {
628     Normal,
629     ForLoopDesugar
630 });
631
632 impl_stable_hash_for!(enum hir::LoopSource {
633     Loop,
634     WhileLet,
635     ForLoop
636 });
637
638 impl<'a> HashStable<StableHashingContext<'a>> for hir::MatchSource {
639     fn hash_stable<W: StableHasherResult>(&self,
640                                           hcx: &mut StableHashingContext<'a>,
641                                           hasher: &mut StableHasher<W>) {
642         use hir::MatchSource;
643
644         mem::discriminant(self).hash_stable(hcx, hasher);
645         match *self {
646             MatchSource::Normal |
647             MatchSource::WhileLetDesugar |
648             MatchSource::ForLoopDesugar |
649             MatchSource::TryDesugar => {
650                 // No fields to hash.
651             }
652             MatchSource::IfLetDesugar { contains_else_clause } => {
653                 contains_else_clause.hash_stable(hcx, hasher);
654             }
655         }
656     }
657 }
658
659 impl_stable_hash_for!(enum hir::GeneratorMovability {
660     Static,
661     Movable
662 });
663
664 impl_stable_hash_for!(enum hir::CaptureClause {
665     CaptureByValue,
666     CaptureByRef
667 });
668
669 impl_stable_hash_for_spanned!(usize);
670
671 impl_stable_hash_for!(struct hir::Destination {
672     label,
673     target_id
674 });
675
676 impl_stable_hash_for_spanned!(ast::Ident);
677
678 impl_stable_hash_for!(enum hir::LoopIdError {
679     OutsideLoopScope,
680     UnlabeledCfInWhileCondition,
681     UnresolvedLabel
682 });
683
684 impl<'a> HashStable<StableHashingContext<'a>> for ast::Ident {
685     fn hash_stable<W: StableHasherResult>(&self,
686                                           hcx: &mut StableHashingContext<'a>,
687                                           hasher: &mut StableHasher<W>) {
688         let ast::Ident {
689             name,
690             span,
691         } = *self;
692
693         name.hash_stable(hcx, hasher);
694         span.hash_stable(hcx, hasher);
695     }
696 }
697
698 impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitItem {
699     fn hash_stable<W: StableHasherResult>(&self,
700                                           hcx: &mut StableHashingContext<'a>,
701                                           hasher: &mut StableHasher<W>) {
702         let hir::TraitItem {
703             id: _,
704             hir_id: _,
705             name,
706             ref attrs,
707             ref generics,
708             ref node,
709             span
710         } = *self;
711
712         hcx.hash_hir_item_like(|hcx| {
713             name.hash_stable(hcx, hasher);
714             attrs.hash_stable(hcx, hasher);
715             generics.hash_stable(hcx, hasher);
716             node.hash_stable(hcx, hasher);
717             span.hash_stable(hcx, hasher);
718         });
719     }
720 }
721
722 impl_stable_hash_for!(enum hir::TraitMethod {
723     Required(name),
724     Provided(body)
725 });
726
727 impl_stable_hash_for!(enum hir::TraitItemKind {
728     Const(t, body),
729     Method(sig, method),
730     Type(bounds, rhs)
731 });
732
733 impl<'a> HashStable<StableHashingContext<'a>> for hir::ImplItem {
734     fn hash_stable<W: StableHasherResult>(&self,
735                                           hcx: &mut StableHashingContext<'a>,
736                                           hasher: &mut StableHasher<W>) {
737         let hir::ImplItem {
738             id: _,
739             hir_id: _,
740             name,
741             ref vis,
742             defaultness,
743             ref attrs,
744             ref generics,
745             ref node,
746             span
747         } = *self;
748
749         hcx.hash_hir_item_like(|hcx| {
750             name.hash_stable(hcx, hasher);
751             vis.hash_stable(hcx, hasher);
752             defaultness.hash_stable(hcx, hasher);
753             attrs.hash_stable(hcx, hasher);
754             generics.hash_stable(hcx, hasher);
755             node.hash_stable(hcx, hasher);
756             span.hash_stable(hcx, hasher);
757         });
758     }
759 }
760
761 impl_stable_hash_for!(enum hir::ImplItemKind {
762     Const(t, body),
763     Method(sig, body),
764     Type(t)
765 });
766
767 impl_stable_hash_for!(enum ::syntax::ast::CrateSugar {
768     JustCrate,
769     PubCrate,
770 });
771
772 impl<'a> HashStable<StableHashingContext<'a>> for hir::Visibility {
773     fn hash_stable<W: StableHasherResult>(&self,
774                                           hcx: &mut StableHashingContext<'a>,
775                                           hasher: &mut StableHasher<W>) {
776         mem::discriminant(self).hash_stable(hcx, hasher);
777         match *self {
778             hir::Visibility::Public |
779             hir::Visibility::Inherited => {
780                 // No fields to hash.
781             }
782             hir::Visibility::Crate(sugar) => {
783                 sugar.hash_stable(hcx, hasher);
784             }
785             hir::Visibility::Restricted { ref path, id } => {
786                 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
787                     id.hash_stable(hcx, hasher);
788                 });
789                 path.hash_stable(hcx, hasher);
790             }
791         }
792     }
793 }
794
795 impl<'a> HashStable<StableHashingContext<'a>> for hir::Defaultness {
796     fn hash_stable<W: StableHasherResult>(&self,
797                                           hcx: &mut StableHashingContext<'a>,
798                                           hasher: &mut StableHasher<W>) {
799         mem::discriminant(self).hash_stable(hcx, hasher);
800         match *self {
801             hir::Defaultness::Final => {
802                 // No fields to hash.
803             }
804             hir::Defaultness::Default { has_value } => {
805                 has_value.hash_stable(hcx, hasher);
806             }
807         }
808     }
809 }
810
811 impl_stable_hash_for!(enum hir::ImplPolarity {
812     Positive,
813     Negative
814 });
815
816 impl<'a> HashStable<StableHashingContext<'a>> for hir::Mod {
817     fn hash_stable<W: StableHasherResult>(&self,
818                                           hcx: &mut StableHashingContext<'a>,
819                                           hasher: &mut StableHasher<W>) {
820         let hir::Mod {
821             inner,
822             // We are not hashing the IDs of the items contained in the module.
823             // This is harmless and matches the current behavior but it's not
824             // actually correct. See issue #40876.
825             item_ids: _,
826         } = *self;
827
828         inner.hash_stable(hcx, hasher);
829     }
830 }
831
832 impl_stable_hash_for!(struct hir::ForeignMod {
833     abi,
834     items
835 });
836
837 impl_stable_hash_for!(struct hir::EnumDef {
838     variants
839 });
840
841 impl_stable_hash_for!(struct hir::Variant_ {
842     name,
843     attrs,
844     data,
845     disr_expr
846 });
847
848 impl_stable_hash_for_spanned!(hir::Variant_);
849
850 impl_stable_hash_for!(enum hir::UseKind {
851     Single,
852     Glob,
853     ListStem
854 });
855
856 impl_stable_hash_for!(struct hir::StructField {
857     span,
858     ident,
859     vis,
860     id,
861     ty,
862     attrs
863 });
864
865 impl_stable_hash_for!(enum hir::VariantData {
866     Struct(fields, id),
867     Tuple(fields, id),
868     Unit(id)
869 });
870
871 impl<'a> HashStable<StableHashingContext<'a>> for hir::Item {
872     fn hash_stable<W: StableHasherResult>(&self,
873                                           hcx: &mut StableHashingContext<'a>,
874                                           hasher: &mut StableHasher<W>) {
875         let hir::Item {
876             name,
877             ref attrs,
878             id: _,
879             hir_id: _,
880             ref node,
881             ref vis,
882             span
883         } = *self;
884
885         hcx.hash_hir_item_like(|hcx| {
886             name.hash_stable(hcx, hasher);
887             attrs.hash_stable(hcx, hasher);
888             node.hash_stable(hcx, hasher);
889             vis.hash_stable(hcx, hasher);
890             span.hash_stable(hcx, hasher);
891         });
892     }
893 }
894
895 impl_stable_hash_for!(enum hir::Item_ {
896     ItemExternCrate(orig_name),
897     ItemUse(path, use_kind),
898     ItemStatic(ty, mutability, body_id),
899     ItemConst(ty, body_id),
900     ItemFn(fn_decl, unsafety, constness, abi, generics, body_id),
901     ItemMod(module),
902     ItemForeignMod(foreign_mod),
903     ItemGlobalAsm(global_asm),
904     ItemTy(ty, generics),
905     ItemExistential(exist),
906     ItemEnum(enum_def, generics),
907     ItemStruct(variant_data, generics),
908     ItemUnion(variant_data, generics),
909     ItemTrait(is_auto, unsafety, generics, bounds, item_refs),
910     ItemTraitAlias(generics, bounds),
911     ItemImpl(unsafety, impl_polarity, impl_defaultness, generics, trait_ref, ty, impl_item_refs)
912 });
913
914 impl_stable_hash_for!(struct hir::TraitItemRef {
915     id,
916     name,
917     kind,
918     span,
919     defaultness
920 });
921
922 impl_stable_hash_for!(struct hir::ImplItemRef {
923     id,
924     name,
925     kind,
926     span,
927     vis,
928     defaultness
929 });
930
931 impl<'a> HashStable<StableHashingContext<'a>>
932 for hir::AssociatedItemKind {
933     fn hash_stable<W: StableHasherResult>(&self,
934                                           hcx: &mut StableHashingContext<'a>,
935                                           hasher: &mut StableHasher<W>) {
936         mem::discriminant(self).hash_stable(hcx, hasher);
937         match *self {
938             hir::AssociatedItemKind::Const |
939             hir::AssociatedItemKind::Type => {
940                 // No fields to hash.
941             }
942             hir::AssociatedItemKind::Method { has_self } => {
943                 has_self.hash_stable(hcx, hasher);
944             }
945         }
946     }
947 }
948
949 impl_stable_hash_for!(struct hir::ForeignItem {
950     name,
951     attrs,
952     node,
953     id,
954     span,
955     vis
956 });
957
958 impl_stable_hash_for!(enum hir::ForeignItem_ {
959     ForeignItemFn(fn_decl, arg_names, generics),
960     ForeignItemStatic(ty, is_mutbl),
961     ForeignItemType
962 });
963
964 impl_stable_hash_for!(enum hir::Stmt_ {
965     StmtDecl(decl, id),
966     StmtExpr(expr, id),
967     StmtSemi(expr, id)
968 });
969
970 impl_stable_hash_for!(struct hir::Arg {
971     pat,
972     id,
973     hir_id
974 });
975
976 impl<'a> HashStable<StableHashingContext<'a>> for hir::Body {
977     fn hash_stable<W: StableHasherResult>(&self,
978                                           hcx: &mut StableHashingContext<'a>,
979                                           hasher: &mut StableHasher<W>) {
980         let hir::Body {
981             ref arguments,
982             ref value,
983             is_generator,
984         } = *self;
985
986         hcx.with_node_id_hashing_mode(NodeIdHashingMode::Ignore, |hcx| {
987             arguments.hash_stable(hcx, hasher);
988             value.hash_stable(hcx, hasher);
989             is_generator.hash_stable(hcx, hasher);
990         });
991     }
992 }
993
994 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::BodyId {
995     type KeyType = (DefPathHash, hir::ItemLocalId);
996
997     #[inline]
998     fn to_stable_hash_key(&self,
999                           hcx: &StableHashingContext<'a>)
1000                           -> (DefPathHash, hir::ItemLocalId) {
1001         let hir::BodyId { node_id } = *self;
1002         node_id.to_stable_hash_key(hcx)
1003     }
1004 }
1005
1006 impl_stable_hash_for!(struct hir::InlineAsmOutput {
1007     constraint,
1008     is_rw,
1009     is_indirect
1010 });
1011
1012 impl<'a> HashStable<StableHashingContext<'a>> for hir::GlobalAsm {
1013     fn hash_stable<W: StableHasherResult>(&self,
1014                                           hcx: &mut StableHashingContext<'a>,
1015                                           hasher: &mut StableHasher<W>) {
1016         let hir::GlobalAsm {
1017             asm,
1018             ctxt: _
1019         } = *self;
1020
1021         asm.hash_stable(hcx, hasher);
1022     }
1023 }
1024
1025 impl<'a> HashStable<StableHashingContext<'a>> for hir::InlineAsm {
1026     fn hash_stable<W: StableHasherResult>(&self,
1027                                           hcx: &mut StableHashingContext<'a>,
1028                                           hasher: &mut StableHasher<W>) {
1029         let hir::InlineAsm {
1030             asm,
1031             asm_str_style,
1032             ref outputs,
1033             ref inputs,
1034             ref clobbers,
1035             volatile,
1036             alignstack,
1037             dialect,
1038             ctxt: _, // This is used for error reporting
1039         } = *self;
1040
1041         asm.hash_stable(hcx, hasher);
1042         asm_str_style.hash_stable(hcx, hasher);
1043         outputs.hash_stable(hcx, hasher);
1044         inputs.hash_stable(hcx, hasher);
1045         clobbers.hash_stable(hcx, hasher);
1046         volatile.hash_stable(hcx, hasher);
1047         alignstack.hash_stable(hcx, hasher);
1048         dialect.hash_stable(hcx, hasher);
1049     }
1050 }
1051
1052 impl_stable_hash_for!(enum hir::def::CtorKind {
1053     Fn,
1054     Const,
1055     Fictive
1056 });
1057
1058 impl_stable_hash_for!(enum hir::def::Def {
1059     Mod(def_id),
1060     Struct(def_id),
1061     Union(def_id),
1062     Enum(def_id),
1063     Existential(def_id),
1064     Variant(def_id),
1065     Trait(def_id),
1066     TyAlias(def_id),
1067     TraitAlias(def_id),
1068     AssociatedTy(def_id),
1069     PrimTy(prim_ty),
1070     TyParam(def_id),
1071     SelfTy(trait_def_id, impl_def_id),
1072     TyForeign(def_id),
1073     Fn(def_id),
1074     Const(def_id),
1075     Static(def_id, is_mutbl),
1076     StructCtor(def_id, ctor_kind),
1077     VariantCtor(def_id, ctor_kind),
1078     Method(def_id),
1079     AssociatedConst(def_id),
1080     Local(def_id),
1081     Upvar(def_id, index, expr_id),
1082     Label(node_id),
1083     Macro(def_id, macro_kind),
1084     GlobalAsm(def_id),
1085     Err
1086 });
1087
1088 impl_stable_hash_for!(enum hir::Mutability {
1089     MutMutable,
1090     MutImmutable
1091 });
1092
1093 impl_stable_hash_for!(enum hir::IsAuto {
1094     Yes,
1095     No
1096 });
1097
1098 impl_stable_hash_for!(enum hir::Unsafety {
1099     Unsafe,
1100     Normal
1101 });
1102
1103
1104 impl_stable_hash_for!(enum hir::Constness {
1105     Const,
1106     NotConst
1107 });
1108
1109 impl<'a> HashStable<StableHashingContext<'a>>
1110 for hir::def_id::DefIndex {
1111
1112     fn hash_stable<W: StableHasherResult>(&self,
1113                                           hcx: &mut StableHashingContext<'a>,
1114                                           hasher: &mut StableHasher<W>) {
1115         hcx.local_def_path_hash(*self).hash_stable(hcx, hasher);
1116     }
1117 }
1118
1119 impl<'a> ToStableHashKey<StableHashingContext<'a>>
1120 for hir::def_id::DefIndex {
1121     type KeyType = DefPathHash;
1122
1123     #[inline]
1124     fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
1125          hcx.local_def_path_hash(*self)
1126     }
1127 }
1128
1129 impl_stable_hash_for!(struct hir::def::Export {
1130     ident,
1131     def,
1132     vis,
1133     span
1134 });
1135
1136 impl<'a> HashStable<StableHashingContext<'a>>
1137 for ::middle::lang_items::LangItem {
1138     fn hash_stable<W: StableHasherResult>(&self,
1139                                           _: &mut StableHashingContext<'a>,
1140                                           hasher: &mut StableHasher<W>) {
1141         ::std::hash::Hash::hash(self, hasher);
1142     }
1143 }
1144
1145 impl_stable_hash_for!(struct ::middle::lang_items::LanguageItems {
1146     items,
1147     missing
1148 });
1149
1150 impl<'a> HashStable<StableHashingContext<'a>>
1151 for hir::TraitCandidate {
1152     fn hash_stable<W: StableHasherResult>(&self,
1153                                           hcx: &mut StableHashingContext<'a>,
1154                                           hasher: &mut StableHasher<W>) {
1155         hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
1156             let hir::TraitCandidate {
1157                 def_id,
1158                 import_id,
1159             } = *self;
1160
1161             def_id.hash_stable(hcx, hasher);
1162             import_id.hash_stable(hcx, hasher);
1163         });
1164     }
1165 }
1166
1167 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::TraitCandidate {
1168     type KeyType = (DefPathHash, Option<(DefPathHash, hir::ItemLocalId)>);
1169
1170     fn to_stable_hash_key(&self,
1171                           hcx: &StableHashingContext<'a>)
1172                           -> Self::KeyType {
1173         let hir::TraitCandidate {
1174             def_id,
1175             import_id,
1176         } = *self;
1177
1178         let import_id = import_id.map(|node_id| hcx.node_to_hir_id(node_id))
1179                                  .map(|hir_id| (hcx.local_def_path_hash(hir_id.owner),
1180                                                 hir_id.local_id));
1181         (hcx.def_path_hash(def_id), import_id)
1182     }
1183 }
1184
1185 impl<'hir> HashStable<StableHashingContext<'hir>> for hir::CodegenFnAttrs
1186 {
1187     fn hash_stable<W: StableHasherResult>(&self,
1188                                           hcx: &mut StableHashingContext<'hir>,
1189                                           hasher: &mut StableHasher<W>) {
1190         let hir::CodegenFnAttrs {
1191             flags,
1192             inline,
1193             export_name,
1194             ref target_features,
1195             linkage,
1196         } = *self;
1197
1198         flags.hash_stable(hcx, hasher);
1199         inline.hash_stable(hcx, hasher);
1200         export_name.hash_stable(hcx, hasher);
1201         target_features.hash_stable(hcx, hasher);
1202         linkage.hash_stable(hcx, hasher);
1203     }
1204 }
1205
1206 impl<'hir> HashStable<StableHashingContext<'hir>> for hir::CodegenFnAttrFlags
1207 {
1208     fn hash_stable<W: StableHasherResult>(&self,
1209                                           hcx: &mut StableHashingContext<'hir>,
1210                                           hasher: &mut StableHasher<W>) {
1211         self.bits().hash_stable(hcx, hasher);
1212     }
1213 }
1214
1215 impl<'hir> HashStable<StableHashingContext<'hir>> for attr::InlineAttr {
1216     fn hash_stable<W: StableHasherResult>(&self,
1217                                           hcx: &mut StableHashingContext<'hir>,
1218                                           hasher: &mut StableHasher<W>) {
1219         mem::discriminant(self).hash_stable(hcx, hasher);
1220     }
1221 }
1222
1223 impl_stable_hash_for!(struct hir::Freevar {
1224     def,
1225     span
1226 });