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