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