]> git.lizzy.rs Git - rust.git/blob - src/librustc/ich/impls_hir.rs
call it `hir::VisibilityKind` instead of `hir::Visibility_:*`
[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     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<'a> HashStable<StableHashingContext<'a>> for hir::GenericParamKind {
211     fn hash_stable<W: StableHasherResult>(&self,
212                                           hcx: &mut StableHashingContext<'a>,
213                                           hasher: &mut StableHasher<W>) {
214         mem::discriminant(self).hash_stable(hcx, hasher);
215         match self {
216             hir::GenericParamKind::Lifetime { in_band } => {
217                 in_band.hash_stable(hcx, hasher);
218             }
219             hir::GenericParamKind::Type { ref default, synthetic } => {
220                 default.hash_stable(hcx, hasher);
221                 synthetic.hash_stable(hcx, hasher);
222             }
223         }
224     }
225 }
226
227 impl_stable_hash_for!(struct hir::Generics {
228     params,
229     where_clause,
230     span
231 });
232
233 impl_stable_hash_for!(enum hir::SyntheticTyParamKind {
234     ImplTrait
235 });
236
237 impl_stable_hash_for!(struct hir::WhereClause {
238     id,
239     predicates
240 });
241
242 impl_stable_hash_for!(enum hir::WherePredicate {
243     BoundPredicate(pred),
244     RegionPredicate(pred),
245     EqPredicate(pred)
246 });
247
248 impl_stable_hash_for!(struct hir::WhereBoundPredicate {
249     span,
250     bound_generic_params,
251     bounded_ty,
252     bounds
253 });
254
255 impl_stable_hash_for!(struct hir::WhereRegionPredicate {
256     span,
257     lifetime,
258     bounds
259 });
260
261 impl_stable_hash_for!(struct hir::WhereEqPredicate {
262     id,
263     span,
264     lhs_ty,
265     rhs_ty
266 });
267
268 impl_stable_hash_for!(struct hir::MutTy {
269     ty,
270     mutbl
271 });
272
273 impl_stable_hash_for!(struct hir::MethodSig {
274     header,
275     decl
276 });
277
278 impl_stable_hash_for!(struct hir::TypeBinding {
279     id,
280     ident -> (ident.name),
281     ty,
282     span
283 });
284
285 impl_stable_hash_for!(struct hir::FnHeader {
286     unsafety,
287     constness,
288     asyncness,
289     abi
290 });
291
292 impl<'a> HashStable<StableHashingContext<'a>> for hir::Ty {
293     fn hash_stable<W: StableHasherResult>(&self,
294                                           hcx: &mut StableHashingContext<'a>,
295                                           hasher: &mut StableHasher<W>) {
296         hcx.while_hashing_hir_bodies(true, |hcx| {
297             let hir::Ty {
298                 id: _,
299                 hir_id: _,
300                 ref node,
301                 ref span,
302             } = *self;
303
304             node.hash_stable(hcx, hasher);
305             span.hash_stable(hcx, hasher);
306         })
307     }
308 }
309
310 impl_stable_hash_for!(enum hir::PrimTy {
311     TyInt(int_ty),
312     TyUint(uint_ty),
313     TyFloat(float_ty),
314     TyStr,
315     TyBool,
316     TyChar
317 });
318
319 impl_stable_hash_for!(struct hir::BareFnTy {
320     unsafety,
321     abi,
322     generic_params,
323     decl,
324     arg_names
325 });
326
327 impl_stable_hash_for!(struct hir::ExistTy {
328     generics,
329     impl_trait_fn,
330     bounds
331 });
332
333 impl_stable_hash_for!(enum hir::Ty_ {
334     TySlice(t),
335     TyArray(t, body_id),
336     TyPtr(t),
337     TyRptr(lifetime, t),
338     TyBareFn(t),
339     TyNever,
340     TyTup(ts),
341     TyPath(qpath),
342     TyTraitObject(trait_refs, lifetime),
343     TyImplTraitExistential(existty, def_id, lifetimes),
344     TyTypeof(body_id),
345     TyErr,
346     TyInfer
347 });
348
349 impl_stable_hash_for!(struct hir::FnDecl {
350     inputs,
351     output,
352     variadic,
353     has_implicit_self
354 });
355
356 impl_stable_hash_for!(enum hir::FunctionRetTy {
357     DefaultReturn(span),
358     Return(t)
359 });
360
361 impl_stable_hash_for!(struct hir::TraitRef {
362     // Don't hash the ref_id. It is tracked via the thing it is used to access
363     ref_id -> _,
364     path,
365 });
366
367 impl_stable_hash_for!(struct hir::PolyTraitRef {
368     bound_generic_params,
369     trait_ref,
370     span
371 });
372
373 impl_stable_hash_for!(enum hir::QPath {
374     Resolved(t, path),
375     TypeRelative(t, path_segment)
376 });
377
378 impl_stable_hash_for!(struct hir::MacroDef {
379     name,
380     vis,
381     attrs,
382     id,
383     span,
384     legacy,
385     body
386 });
387
388 impl_stable_hash_for!(struct hir::Block {
389     stmts,
390     expr,
391     id -> _,
392     hir_id -> _,
393     rules,
394     span,
395     targeted_by_break,
396     recovered,
397 });
398
399 impl_stable_hash_for!(struct hir::Pat {
400     id -> _,
401     hir_id -> _,
402     node,
403     span,
404 });
405
406 impl_stable_hash_for_spanned!(hir::FieldPat);
407
408 impl_stable_hash_for!(struct hir::FieldPat {
409     id -> _,
410     ident -> (ident.name),
411     pat,
412     is_shorthand,
413 });
414
415 impl_stable_hash_for!(enum hir::BindingAnnotation {
416     Unannotated,
417     Mutable,
418     Ref,
419     RefMut
420 });
421
422 impl_stable_hash_for!(enum hir::RangeEnd {
423     Included,
424     Excluded
425 });
426
427 impl_stable_hash_for!(enum hir::PatKind {
428     Wild,
429     Binding(binding_mode, var, name, sub),
430     Struct(path, field_pats, dotdot),
431     TupleStruct(path, field_pats, dotdot),
432     Path(path),
433     Tuple(field_pats, dotdot),
434     Box(sub),
435     Ref(sub, mutability),
436     Lit(expr),
437     Range(start, end, end_kind),
438     Slice(one, two, three)
439 });
440
441 impl_stable_hash_for!(enum hir::BinOp_ {
442     BiAdd,
443     BiSub,
444     BiMul,
445     BiDiv,
446     BiRem,
447     BiAnd,
448     BiOr,
449     BiBitXor,
450     BiBitAnd,
451     BiBitOr,
452     BiShl,
453     BiShr,
454     BiEq,
455     BiLt,
456     BiLe,
457     BiNe,
458     BiGe,
459     BiGt
460 });
461
462 impl_stable_hash_for_spanned!(hir::BinOp_);
463
464 impl_stable_hash_for!(enum hir::UnOp {
465     UnDeref,
466     UnNot,
467     UnNeg
468 });
469
470 impl_stable_hash_for_spanned!(hir::Stmt_);
471
472 impl_stable_hash_for!(struct hir::Local {
473     pat,
474     ty,
475     init,
476     id,
477     hir_id,
478     span,
479     attrs,
480     source
481 });
482
483 impl_stable_hash_for_spanned!(hir::Decl_);
484 impl_stable_hash_for!(enum hir::Decl_ {
485     DeclLocal(local),
486     DeclItem(item_id)
487 });
488
489 impl_stable_hash_for!(struct hir::Arm {
490     attrs,
491     pats,
492     guard,
493     body
494 });
495
496 impl_stable_hash_for!(struct hir::Field {
497     id -> _,
498     ident,
499     expr,
500     span,
501     is_shorthand,
502 });
503
504 impl_stable_hash_for_spanned!(ast::Name);
505
506
507 impl_stable_hash_for!(enum hir::BlockCheckMode {
508     DefaultBlock,
509     UnsafeBlock(src),
510     PushUnsafeBlock(src),
511     PopUnsafeBlock(src)
512 });
513
514 impl_stable_hash_for!(enum hir::UnsafeSource {
515     CompilerGenerated,
516     UserProvided
517 });
518
519 impl_stable_hash_for!(struct hir::AnonConst {
520     id,
521     hir_id,
522     body
523 });
524
525 impl<'a> HashStable<StableHashingContext<'a>> for hir::Expr {
526     fn hash_stable<W: StableHasherResult>(&self,
527                                           hcx: &mut StableHashingContext<'a>,
528                                           hasher: &mut StableHasher<W>) {
529         hcx.while_hashing_hir_bodies(true, |hcx| {
530             let hir::Expr {
531                 id: _,
532                 hir_id: _,
533                 ref span,
534                 ref node,
535                 ref attrs
536             } = *self;
537
538             span.hash_stable(hcx, hasher);
539             node.hash_stable(hcx, hasher);
540             attrs.hash_stable(hcx, hasher);
541         })
542     }
543 }
544
545 impl_stable_hash_for!(enum hir::Expr_ {
546     ExprBox(sub),
547     ExprArray(subs),
548     ExprCall(callee, args),
549     ExprMethodCall(segment, span, args),
550     ExprTup(fields),
551     ExprBinary(op, lhs, rhs),
552     ExprUnary(op, operand),
553     ExprLit(value),
554     ExprCast(expr, t),
555     ExprType(expr, t),
556     ExprIf(cond, then, els),
557     ExprWhile(cond, body, label),
558     ExprLoop(body, label, loop_src),
559     ExprMatch(matchee, arms, match_src),
560     ExprClosure(capture_clause, decl, body_id, span, gen),
561     ExprBlock(blk, label),
562     ExprAssign(lhs, rhs),
563     ExprAssignOp(op, lhs, rhs),
564     ExprField(owner, ident),
565     ExprIndex(lhs, rhs),
566     ExprPath(path),
567     ExprAddrOf(mutability, sub),
568     ExprBreak(destination, sub),
569     ExprContinue(destination),
570     ExprRet(val),
571     ExprInlineAsm(asm, inputs, outputs),
572     ExprStruct(path, fields, base),
573     ExprRepeat(val, times),
574     ExprYield(val)
575 });
576
577 impl_stable_hash_for!(enum hir::LocalSource {
578     Normal,
579     ForLoopDesugar
580 });
581
582 impl_stable_hash_for!(enum hir::LoopSource {
583     Loop,
584     WhileLet,
585     ForLoop
586 });
587
588 impl<'a> HashStable<StableHashingContext<'a>> for hir::MatchSource {
589     fn hash_stable<W: StableHasherResult>(&self,
590                                           hcx: &mut StableHashingContext<'a>,
591                                           hasher: &mut StableHasher<W>) {
592         use hir::MatchSource;
593
594         mem::discriminant(self).hash_stable(hcx, hasher);
595         match *self {
596             MatchSource::Normal |
597             MatchSource::WhileLetDesugar |
598             MatchSource::ForLoopDesugar |
599             MatchSource::TryDesugar => {
600                 // No fields to hash.
601             }
602             MatchSource::IfLetDesugar { contains_else_clause } => {
603                 contains_else_clause.hash_stable(hcx, hasher);
604             }
605         }
606     }
607 }
608
609 impl_stable_hash_for!(enum hir::GeneratorMovability {
610     Static,
611     Movable
612 });
613
614 impl_stable_hash_for!(enum hir::CaptureClause {
615     CaptureByValue,
616     CaptureByRef
617 });
618
619 impl_stable_hash_for_spanned!(usize);
620
621 impl_stable_hash_for!(struct hir::Destination {
622     label,
623     target_id
624 });
625
626 impl_stable_hash_for_spanned!(ast::Ident);
627
628 impl_stable_hash_for!(enum hir::LoopIdError {
629     OutsideLoopScope,
630     UnlabeledCfInWhileCondition,
631     UnresolvedLabel
632 });
633
634 impl_stable_hash_for!(struct ast::Ident {
635     name,
636     span,
637 });
638
639 impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitItem {
640     fn hash_stable<W: StableHasherResult>(&self,
641                                           hcx: &mut StableHashingContext<'a>,
642                                           hasher: &mut StableHasher<W>) {
643         let hir::TraitItem {
644             id: _,
645             hir_id: _,
646             ident,
647             ref attrs,
648             ref generics,
649             ref node,
650             span
651         } = *self;
652
653         hcx.hash_hir_item_like(|hcx| {
654             ident.name.hash_stable(hcx, hasher);
655             attrs.hash_stable(hcx, hasher);
656             generics.hash_stable(hcx, hasher);
657             node.hash_stable(hcx, hasher);
658             span.hash_stable(hcx, hasher);
659         });
660     }
661 }
662
663 impl_stable_hash_for!(enum hir::TraitMethod {
664     Required(name),
665     Provided(body)
666 });
667
668 impl_stable_hash_for!(enum hir::TraitItemKind {
669     Const(t, body),
670     Method(sig, method),
671     Type(bounds, rhs)
672 });
673
674 impl<'a> HashStable<StableHashingContext<'a>> for hir::ImplItem {
675     fn hash_stable<W: StableHasherResult>(&self,
676                                           hcx: &mut StableHashingContext<'a>,
677                                           hasher: &mut StableHasher<W>) {
678         let hir::ImplItem {
679             id: _,
680             hir_id: _,
681             ident,
682             ref vis,
683             defaultness,
684             ref attrs,
685             ref generics,
686             ref node,
687             span
688         } = *self;
689
690         hcx.hash_hir_item_like(|hcx| {
691             ident.name.hash_stable(hcx, hasher);
692             vis.hash_stable(hcx, hasher);
693             defaultness.hash_stable(hcx, hasher);
694             attrs.hash_stable(hcx, hasher);
695             generics.hash_stable(hcx, hasher);
696             node.hash_stable(hcx, hasher);
697             span.hash_stable(hcx, hasher);
698         });
699     }
700 }
701
702 impl_stable_hash_for!(enum hir::ImplItemKind {
703     Const(t, body),
704     Method(sig, body),
705     Type(t)
706 });
707
708 impl_stable_hash_for!(enum ::syntax::ast::CrateSugar {
709     JustCrate,
710     PubCrate,
711 });
712
713 impl<'a> HashStable<StableHashingContext<'a>> for hir::VisibilityKind {
714     fn hash_stable<W: StableHasherResult>(&self,
715                                           hcx: &mut StableHashingContext<'a>,
716                                           hasher: &mut StableHasher<W>) {
717         mem::discriminant(self).hash_stable(hcx, hasher);
718         match *self {
719             hir::VisibilityKind::Public |
720             hir::VisibilityKind::Inherited => {
721                 // No fields to hash.
722             }
723             hir::VisibilityKind::Crate(sugar) => {
724                 sugar.hash_stable(hcx, hasher);
725             }
726             hir::VisibilityKind::Restricted { ref path, id } => {
727                 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
728                     id.hash_stable(hcx, hasher);
729                 });
730                 path.hash_stable(hcx, hasher);
731             }
732         }
733     }
734 }
735
736 impl_stable_hash_for_spanned!(hir::VisibilityKind);
737
738 impl<'a> HashStable<StableHashingContext<'a>> for hir::Defaultness {
739     fn hash_stable<W: StableHasherResult>(&self,
740                                           hcx: &mut StableHashingContext<'a>,
741                                           hasher: &mut StableHasher<W>) {
742         mem::discriminant(self).hash_stable(hcx, hasher);
743         match *self {
744             hir::Defaultness::Final => {
745                 // No fields to hash.
746             }
747             hir::Defaultness::Default { has_value } => {
748                 has_value.hash_stable(hcx, hasher);
749             }
750         }
751     }
752 }
753
754 impl_stable_hash_for!(enum hir::ImplPolarity {
755     Positive,
756     Negative
757 });
758
759 impl_stable_hash_for!(struct hir::Mod {
760     inner,
761     // We are not hashing the IDs of the items contained in the module.
762     // This is harmless and matches the current behavior but it's not
763     // actually correct. See issue #40876.
764     item_ids -> _,
765 });
766
767 impl_stable_hash_for!(struct hir::ForeignMod {
768     abi,
769     items
770 });
771
772 impl_stable_hash_for!(struct hir::EnumDef {
773     variants
774 });
775
776 impl_stable_hash_for!(struct hir::Variant_ {
777     name,
778     attrs,
779     data,
780     disr_expr
781 });
782
783 impl_stable_hash_for_spanned!(hir::Variant_);
784
785 impl_stable_hash_for!(enum hir::UseKind {
786     Single,
787     Glob,
788     ListStem
789 });
790
791 impl_stable_hash_for!(struct hir::StructField {
792     span,
793     ident -> (ident.name),
794     vis,
795     id,
796     ty,
797     attrs
798 });
799
800 impl_stable_hash_for!(enum hir::VariantData {
801     Struct(fields, id),
802     Tuple(fields, id),
803     Unit(id)
804 });
805
806 impl<'a> HashStable<StableHashingContext<'a>> for hir::Item {
807     fn hash_stable<W: StableHasherResult>(&self,
808                                           hcx: &mut StableHashingContext<'a>,
809                                           hasher: &mut StableHasher<W>) {
810         let hir::Item {
811             name,
812             ref attrs,
813             id: _,
814             hir_id: _,
815             ref node,
816             ref vis,
817             span
818         } = *self;
819
820         hcx.hash_hir_item_like(|hcx| {
821             name.hash_stable(hcx, hasher);
822             attrs.hash_stable(hcx, hasher);
823             node.hash_stable(hcx, hasher);
824             vis.hash_stable(hcx, hasher);
825             span.hash_stable(hcx, hasher);
826         });
827     }
828 }
829
830 impl_stable_hash_for!(enum hir::Item_ {
831     ItemExternCrate(orig_name),
832     ItemUse(path, use_kind),
833     ItemStatic(ty, mutability, body_id),
834     ItemConst(ty, body_id),
835     ItemFn(fn_decl, header, generics, body_id),
836     ItemMod(module),
837     ItemForeignMod(foreign_mod),
838     ItemGlobalAsm(global_asm),
839     ItemTy(ty, generics),
840     ItemExistential(exist),
841     ItemEnum(enum_def, generics),
842     ItemStruct(variant_data, generics),
843     ItemUnion(variant_data, generics),
844     ItemTrait(is_auto, unsafety, generics, bounds, item_refs),
845     ItemTraitAlias(generics, bounds),
846     ItemImpl(unsafety, impl_polarity, impl_defaultness, generics, trait_ref, ty, impl_item_refs)
847 });
848
849 impl_stable_hash_for!(struct hir::TraitItemRef {
850     id,
851     ident -> (ident.name),
852     kind,
853     span,
854     defaultness
855 });
856
857 impl_stable_hash_for!(struct hir::ImplItemRef {
858     id,
859     ident -> (ident.name),
860     kind,
861     span,
862     vis,
863     defaultness
864 });
865
866 impl<'a> HashStable<StableHashingContext<'a>> for hir::AssociatedItemKind {
867     fn hash_stable<W: StableHasherResult>(&self,
868                                           hcx: &mut StableHashingContext<'a>,
869                                           hasher: &mut StableHasher<W>) {
870         mem::discriminant(self).hash_stable(hcx, hasher);
871         match *self {
872             hir::AssociatedItemKind::Const |
873             hir::AssociatedItemKind::Type => {
874                 // No fields to hash.
875             }
876             hir::AssociatedItemKind::Method { has_self } => {
877                 has_self.hash_stable(hcx, hasher);
878             }
879         }
880     }
881 }
882
883 impl_stable_hash_for!(struct hir::ForeignItem {
884     name,
885     attrs,
886     node,
887     id,
888     span,
889     vis
890 });
891
892 impl_stable_hash_for!(enum hir::ForeignItem_ {
893     ForeignItemFn(fn_decl, arg_names, generics),
894     ForeignItemStatic(ty, is_mutbl),
895     ForeignItemType
896 });
897
898 impl_stable_hash_for!(enum hir::Stmt_ {
899     StmtDecl(decl, id),
900     StmtExpr(expr, id),
901     StmtSemi(expr, id)
902 });
903
904 impl_stable_hash_for!(struct hir::Arg {
905     pat,
906     id,
907     hir_id
908 });
909
910 impl<'a> HashStable<StableHashingContext<'a>> for hir::Body {
911     fn hash_stable<W: StableHasherResult>(&self,
912                                           hcx: &mut StableHashingContext<'a>,
913                                           hasher: &mut StableHasher<W>) {
914         let hir::Body {
915             ref arguments,
916             ref value,
917             is_generator,
918         } = *self;
919
920         hcx.with_node_id_hashing_mode(NodeIdHashingMode::Ignore, |hcx| {
921             arguments.hash_stable(hcx, hasher);
922             value.hash_stable(hcx, hasher);
923             is_generator.hash_stable(hcx, hasher);
924         });
925     }
926 }
927
928 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::BodyId {
929     type KeyType = (DefPathHash, hir::ItemLocalId);
930
931     #[inline]
932     fn to_stable_hash_key(&self,
933                           hcx: &StableHashingContext<'a>)
934                           -> (DefPathHash, hir::ItemLocalId) {
935         let hir::BodyId { node_id } = *self;
936         node_id.to_stable_hash_key(hcx)
937     }
938 }
939
940 impl_stable_hash_for!(struct hir::InlineAsmOutput {
941     constraint,
942     is_rw,
943     is_indirect
944 });
945
946 impl_stable_hash_for!(struct hir::GlobalAsm {
947     asm,
948     ctxt -> _, // This is used for error reporting
949 });
950
951 impl_stable_hash_for!(struct hir::InlineAsm {
952     asm,
953     asm_str_style,
954     outputs,
955     inputs,
956     clobbers,
957     volatile,
958     alignstack,
959     dialect,
960     ctxt -> _, // This is used for error reporting
961 });
962
963 impl_stable_hash_for!(enum hir::def::CtorKind {
964     Fn,
965     Const,
966     Fictive
967 });
968
969 impl_stable_hash_for!(enum hir::def::Def {
970     Mod(def_id),
971     Struct(def_id),
972     Union(def_id),
973     Enum(def_id),
974     Existential(def_id),
975     Variant(def_id),
976     Trait(def_id),
977     TyAlias(def_id),
978     TraitAlias(def_id),
979     AssociatedTy(def_id),
980     PrimTy(prim_ty),
981     TyParam(def_id),
982     SelfTy(trait_def_id, impl_def_id),
983     TyForeign(def_id),
984     Fn(def_id),
985     Const(def_id),
986     Static(def_id, is_mutbl),
987     StructCtor(def_id, ctor_kind),
988     VariantCtor(def_id, ctor_kind),
989     Method(def_id),
990     AssociatedConst(def_id),
991     Local(def_id),
992     Upvar(def_id, index, expr_id),
993     Label(node_id),
994     Macro(def_id, macro_kind),
995     GlobalAsm(def_id),
996     Err
997 });
998
999 impl_stable_hash_for!(enum hir::Mutability {
1000     MutMutable,
1001     MutImmutable
1002 });
1003
1004 impl_stable_hash_for!(enum hir::IsAuto {
1005     Yes,
1006     No
1007 });
1008
1009 impl_stable_hash_for!(enum hir::Unsafety {
1010     Unsafe,
1011     Normal
1012 });
1013
1014 impl_stable_hash_for!(enum hir::IsAsync {
1015     Async,
1016     NotAsync
1017 });
1018
1019 impl_stable_hash_for!(enum hir::Constness {
1020     Const,
1021     NotConst
1022 });
1023
1024 impl<'a> HashStable<StableHashingContext<'a>> for hir::def_id::DefIndex {
1025
1026     fn hash_stable<W: StableHasherResult>(&self,
1027                                           hcx: &mut StableHashingContext<'a>,
1028                                           hasher: &mut StableHasher<W>) {
1029         hcx.local_def_path_hash(*self).hash_stable(hcx, hasher);
1030     }
1031 }
1032
1033 impl<'a> ToStableHashKey<StableHashingContext<'a>>
1034 for hir::def_id::DefIndex {
1035     type KeyType = DefPathHash;
1036
1037     #[inline]
1038     fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
1039          hcx.local_def_path_hash(*self)
1040     }
1041 }
1042
1043 impl_stable_hash_for!(struct hir::def::Export {
1044     ident,
1045     def,
1046     vis,
1047     span
1048 });
1049
1050 impl<'a> HashStable<StableHashingContext<'a>> for ::middle::lang_items::LangItem {
1051     fn hash_stable<W: StableHasherResult>(&self,
1052                                           _: &mut StableHashingContext<'a>,
1053                                           hasher: &mut StableHasher<W>) {
1054         ::std::hash::Hash::hash(self, hasher);
1055     }
1056 }
1057
1058 impl_stable_hash_for!(struct ::middle::lang_items::LanguageItems {
1059     items,
1060     missing
1061 });
1062
1063 impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitCandidate {
1064     fn hash_stable<W: StableHasherResult>(&self,
1065                                           hcx: &mut StableHashingContext<'a>,
1066                                           hasher: &mut StableHasher<W>) {
1067         hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
1068             let hir::TraitCandidate {
1069                 def_id,
1070                 import_id,
1071             } = *self;
1072
1073             def_id.hash_stable(hcx, hasher);
1074             import_id.hash_stable(hcx, hasher);
1075         });
1076     }
1077 }
1078
1079 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::TraitCandidate {
1080     type KeyType = (DefPathHash, Option<(DefPathHash, hir::ItemLocalId)>);
1081
1082     fn to_stable_hash_key(&self,
1083                           hcx: &StableHashingContext<'a>)
1084                           -> Self::KeyType {
1085         let hir::TraitCandidate {
1086             def_id,
1087             import_id,
1088         } = *self;
1089
1090         let import_id = import_id.map(|node_id| hcx.node_to_hir_id(node_id))
1091                                  .map(|hir_id| (hcx.local_def_path_hash(hir_id.owner),
1092                                                 hir_id.local_id));
1093         (hcx.def_path_hash(def_id), import_id)
1094     }
1095 }
1096
1097 impl_stable_hash_for!(struct hir::CodegenFnAttrs {
1098     flags,
1099     inline,
1100     export_name,
1101     target_features,
1102     linkage,
1103 });
1104
1105 impl<'hir> HashStable<StableHashingContext<'hir>> for hir::CodegenFnAttrFlags
1106 {
1107     fn hash_stable<W: StableHasherResult>(&self,
1108                                           hcx: &mut StableHashingContext<'hir>,
1109                                           hasher: &mut StableHasher<W>) {
1110         self.bits().hash_stable(hcx, hasher);
1111     }
1112 }
1113
1114 impl<'hir> HashStable<StableHashingContext<'hir>> for attr::InlineAttr {
1115     fn hash_stable<W: StableHasherResult>(&self,
1116                                           hcx: &mut StableHashingContext<'hir>,
1117                                           hasher: &mut StableHasher<W>) {
1118         mem::discriminant(self).hash_stable(hcx, hasher);
1119     }
1120 }
1121
1122 impl_stable_hash_for!(struct hir::Freevar {
1123     def,
1124     span
1125 });