]> git.lizzy.rs Git - rust.git/blob - src/librustc/ich/impls_hir.rs
3f1899bc54fb4c2e1e34b1c548cb51fcc3726e6b
[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<'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     Int(int_ty),
312     Uint(uint_ty),
313     Float(float_ty),
314     Str,
315     Bool,
316     Char
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::TyKind {
334     Slice(t),
335     Array(t, body_id),
336     Ptr(t),
337     Rptr(lifetime, t),
338     BareFn(t),
339     Never,
340     Tup(ts),
341     Path(qpath),
342     TraitObject(trait_refs, lifetime),
343     Typeof(body_id),
344     Err,
345     Infer
346 });
347
348 impl_stable_hash_for!(struct hir::FnDecl {
349     inputs,
350     output,
351     variadic,
352     has_implicit_self
353 });
354
355 impl_stable_hash_for!(enum hir::FunctionRetTy {
356     DefaultReturn(span),
357     Return(t)
358 });
359
360 impl_stable_hash_for!(struct hir::TraitRef {
361     // Don't hash the ref_id. It is tracked via the thing it is used to access
362     ref_id -> _,
363     hir_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::BinOpKind {
442     Add,
443     Sub,
444     Mul,
445     Div,
446     Rem,
447     And,
448     Or,
449     BitXor,
450     BitAnd,
451     BitOr,
452     Shl,
453     Shr,
454     Eq,
455     Lt,
456     Le,
457     Ne,
458     Ge,
459     Gt
460 });
461
462 impl_stable_hash_for_spanned!(hir::BinOpKind);
463
464 impl_stable_hash_for!(enum hir::UnOp {
465     UnDeref,
466     UnNot,
467     UnNeg
468 });
469
470 impl_stable_hash_for_spanned!(hir::StmtKind);
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::DeclKind);
484 impl_stable_hash_for!(enum hir::DeclKind {
485     Local(local),
486     Item(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!(enum hir::Guard {
497     If(expr),
498 });
499
500 impl_stable_hash_for!(struct hir::Field {
501     id -> _,
502     ident,
503     expr,
504     span,
505     is_shorthand,
506 });
507
508 impl_stable_hash_for_spanned!(ast::Name);
509
510
511 impl_stable_hash_for!(enum hir::BlockCheckMode {
512     DefaultBlock,
513     UnsafeBlock(src),
514     PushUnsafeBlock(src),
515     PopUnsafeBlock(src)
516 });
517
518 impl_stable_hash_for!(enum hir::UnsafeSource {
519     CompilerGenerated,
520     UserProvided
521 });
522
523 impl_stable_hash_for!(struct hir::AnonConst {
524     id,
525     hir_id,
526     body
527 });
528
529 impl<'a> HashStable<StableHashingContext<'a>> for hir::Expr {
530     fn hash_stable<W: StableHasherResult>(&self,
531                                           hcx: &mut StableHashingContext<'a>,
532                                           hasher: &mut StableHasher<W>) {
533         hcx.while_hashing_hir_bodies(true, |hcx| {
534             let hir::Expr {
535                 id: _,
536                 hir_id: _,
537                 ref span,
538                 ref node,
539                 ref attrs
540             } = *self;
541
542             span.hash_stable(hcx, hasher);
543             node.hash_stable(hcx, hasher);
544             attrs.hash_stable(hcx, hasher);
545         })
546     }
547 }
548
549 impl_stable_hash_for!(enum hir::ExprKind {
550     Box(sub),
551     Array(subs),
552     Call(callee, args),
553     MethodCall(segment, span, args),
554     Tup(fields),
555     Binary(op, lhs, rhs),
556     Unary(op, operand),
557     Lit(value),
558     Cast(expr, t),
559     Type(expr, t),
560     If(cond, then, els),
561     While(cond, body, label),
562     Loop(body, label, loop_src),
563     Match(matchee, arms, match_src),
564     Closure(capture_clause, decl, body_id, span, gen),
565     Block(blk, label),
566     Assign(lhs, rhs),
567     AssignOp(op, lhs, rhs),
568     Field(owner, ident),
569     Index(lhs, rhs),
570     Path(path),
571     AddrOf(mutability, sub),
572     Break(destination, sub),
573     Continue(destination),
574     Ret(val),
575     InlineAsm(asm, inputs, outputs),
576     Struct(path, fields, base),
577     Repeat(val, times),
578     Yield(val)
579 });
580
581 impl_stable_hash_for!(enum hir::LocalSource {
582     Normal,
583     ForLoopDesugar
584 });
585
586 impl_stable_hash_for!(enum hir::LoopSource {
587     Loop,
588     WhileLet,
589     ForLoop
590 });
591
592 impl<'a> HashStable<StableHashingContext<'a>> for hir::MatchSource {
593     fn hash_stable<W: StableHasherResult>(&self,
594                                           hcx: &mut StableHashingContext<'a>,
595                                           hasher: &mut StableHasher<W>) {
596         use hir::MatchSource;
597
598         mem::discriminant(self).hash_stable(hcx, hasher);
599         match *self {
600             MatchSource::Normal |
601             MatchSource::WhileLetDesugar |
602             MatchSource::ForLoopDesugar |
603             MatchSource::TryDesugar => {
604                 // No fields to hash.
605             }
606             MatchSource::IfLetDesugar { contains_else_clause } => {
607                 contains_else_clause.hash_stable(hcx, hasher);
608             }
609         }
610     }
611 }
612
613 impl_stable_hash_for!(enum hir::GeneratorMovability {
614     Static,
615     Movable
616 });
617
618 impl_stable_hash_for!(enum hir::CaptureClause {
619     CaptureByValue,
620     CaptureByRef
621 });
622
623 impl_stable_hash_for_spanned!(usize);
624
625 impl_stable_hash_for!(struct hir::Destination {
626     label,
627     target_id
628 });
629
630 impl_stable_hash_for_spanned!(ast::Ident);
631
632 impl_stable_hash_for!(enum hir::LoopIdError {
633     OutsideLoopScope,
634     UnlabeledCfInWhileCondition,
635     UnresolvedLabel
636 });
637
638 impl_stable_hash_for!(struct ast::Ident {
639     name,
640     span,
641 });
642
643 impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitItem {
644     fn hash_stable<W: StableHasherResult>(&self,
645                                           hcx: &mut StableHashingContext<'a>,
646                                           hasher: &mut StableHasher<W>) {
647         let hir::TraitItem {
648             id: _,
649             hir_id: _,
650             ident,
651             ref attrs,
652             ref generics,
653             ref node,
654             span
655         } = *self;
656
657         hcx.hash_hir_item_like(|hcx| {
658             ident.name.hash_stable(hcx, hasher);
659             attrs.hash_stable(hcx, hasher);
660             generics.hash_stable(hcx, hasher);
661             node.hash_stable(hcx, hasher);
662             span.hash_stable(hcx, hasher);
663         });
664     }
665 }
666
667 impl_stable_hash_for!(enum hir::TraitMethod {
668     Required(name),
669     Provided(body)
670 });
671
672 impl_stable_hash_for!(enum hir::TraitItemKind {
673     Const(t, body),
674     Method(sig, method),
675     Type(bounds, rhs)
676 });
677
678 impl<'a> HashStable<StableHashingContext<'a>> for hir::ImplItem {
679     fn hash_stable<W: StableHasherResult>(&self,
680                                           hcx: &mut StableHashingContext<'a>,
681                                           hasher: &mut StableHasher<W>) {
682         let hir::ImplItem {
683             id: _,
684             hir_id: _,
685             ident,
686             ref vis,
687             defaultness,
688             ref attrs,
689             ref generics,
690             ref node,
691             span
692         } = *self;
693
694         hcx.hash_hir_item_like(|hcx| {
695             ident.name.hash_stable(hcx, hasher);
696             vis.hash_stable(hcx, hasher);
697             defaultness.hash_stable(hcx, hasher);
698             attrs.hash_stable(hcx, hasher);
699             generics.hash_stable(hcx, hasher);
700             node.hash_stable(hcx, hasher);
701             span.hash_stable(hcx, hasher);
702         });
703     }
704 }
705
706 impl_stable_hash_for!(enum hir::ImplItemKind {
707     Const(t, body),
708     Method(sig, body),
709     Existential(bounds),
710     Type(t)
711 });
712
713 impl_stable_hash_for!(enum ::syntax::ast::CrateSugar {
714     JustCrate,
715     PubCrate,
716 });
717
718 impl<'a> HashStable<StableHashingContext<'a>> for hir::VisibilityKind {
719     fn hash_stable<W: StableHasherResult>(&self,
720                                           hcx: &mut StableHashingContext<'a>,
721                                           hasher: &mut StableHasher<W>) {
722         mem::discriminant(self).hash_stable(hcx, hasher);
723         match *self {
724             hir::VisibilityKind::Public |
725             hir::VisibilityKind::Inherited => {
726                 // No fields to hash.
727             }
728             hir::VisibilityKind::Crate(sugar) => {
729                 sugar.hash_stable(hcx, hasher);
730             }
731             hir::VisibilityKind::Restricted { ref path, id, hir_id } => {
732                 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
733                     id.hash_stable(hcx, hasher);
734                     hir_id.hash_stable(hcx, hasher);
735                 });
736                 path.hash_stable(hcx, hasher);
737             }
738         }
739     }
740 }
741
742 impl_stable_hash_for_spanned!(hir::VisibilityKind);
743
744 impl<'a> HashStable<StableHashingContext<'a>> for hir::Defaultness {
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::Defaultness::Final => {
751                 // No fields to hash.
752             }
753             hir::Defaultness::Default { has_value } => {
754                 has_value.hash_stable(hcx, hasher);
755             }
756         }
757     }
758 }
759
760 impl_stable_hash_for!(enum hir::ImplPolarity {
761     Positive,
762     Negative
763 });
764
765 impl<'a> HashStable<StableHashingContext<'a>> for hir::Mod {
766     fn hash_stable<W: StableHasherResult>(&self,
767                                           hcx: &mut StableHashingContext<'a>,
768                                           hasher: &mut StableHasher<W>) {
769         let hir::Mod {
770             inner: ref inner_span,
771             ref item_ids,
772         } = *self;
773
774         inner_span.hash_stable(hcx, hasher);
775
776         // Combining the DefPathHashes directly is faster than feeding them
777         // into the hasher. Because we use a commutative combine, we also don't
778         // have to sort the array.
779         let item_ids_hash = item_ids
780             .iter()
781             .map(|id| {
782                 let (def_path_hash, local_id) = id.id.to_stable_hash_key(hcx);
783                 debug_assert_eq!(local_id, hir::ItemLocalId(0));
784                 def_path_hash.0
785             }).fold(Fingerprint::ZERO, |a, b| {
786                 a.combine_commutative(b)
787             });
788
789         item_ids.len().hash_stable(hcx, hasher);
790         item_ids_hash.hash_stable(hcx, hasher);
791     }
792 }
793
794 impl_stable_hash_for!(struct hir::ForeignMod {
795     abi,
796     items
797 });
798
799 impl_stable_hash_for!(struct hir::EnumDef {
800     variants
801 });
802
803 impl_stable_hash_for!(struct hir::VariantKind {
804     name,
805     attrs,
806     data,
807     disr_expr
808 });
809
810 impl_stable_hash_for_spanned!(hir::VariantKind);
811
812 impl_stable_hash_for!(enum hir::UseKind {
813     Single,
814     Glob,
815     ListStem
816 });
817
818 impl_stable_hash_for!(struct hir::StructField {
819     span,
820     ident -> (ident.name),
821     vis,
822     id,
823     ty,
824     attrs
825 });
826
827 impl_stable_hash_for!(enum hir::VariantData {
828     Struct(fields, id),
829     Tuple(fields, id),
830     Unit(id)
831 });
832
833 impl<'a> HashStable<StableHashingContext<'a>> for hir::Item {
834     fn hash_stable<W: StableHasherResult>(&self,
835                                           hcx: &mut StableHashingContext<'a>,
836                                           hasher: &mut StableHasher<W>) {
837         let hir::Item {
838             name,
839             ref attrs,
840             id: _,
841             hir_id: _,
842             ref node,
843             ref vis,
844             span
845         } = *self;
846
847         hcx.hash_hir_item_like(|hcx| {
848             name.hash_stable(hcx, hasher);
849             attrs.hash_stable(hcx, hasher);
850             node.hash_stable(hcx, hasher);
851             vis.hash_stable(hcx, hasher);
852             span.hash_stable(hcx, hasher);
853         });
854     }
855 }
856
857 impl_stable_hash_for!(enum hir::ItemKind {
858     ExternCrate(orig_name),
859     Use(path, use_kind),
860     Static(ty, mutability, body_id),
861     Const(ty, body_id),
862     Fn(fn_decl, header, generics, body_id),
863     Mod(module),
864     ForeignMod(foreign_mod),
865     GlobalAsm(global_asm),
866     Ty(ty, generics),
867     Existential(exist),
868     Enum(enum_def, generics),
869     Struct(variant_data, generics),
870     Union(variant_data, generics),
871     Trait(is_auto, unsafety, generics, bounds, item_refs),
872     TraitAlias(generics, bounds),
873     Impl(unsafety, impl_polarity, impl_defaultness, generics, trait_ref, ty, impl_item_refs)
874 });
875
876 impl_stable_hash_for!(struct hir::TraitItemRef {
877     id,
878     ident -> (ident.name),
879     kind,
880     span,
881     defaultness
882 });
883
884 impl_stable_hash_for!(struct hir::ImplItemRef {
885     id,
886     ident -> (ident.name),
887     kind,
888     span,
889     vis,
890     defaultness
891 });
892
893 impl<'a> HashStable<StableHashingContext<'a>> for hir::AssociatedItemKind {
894     fn hash_stable<W: StableHasherResult>(&self,
895                                           hcx: &mut StableHashingContext<'a>,
896                                           hasher: &mut StableHasher<W>) {
897         mem::discriminant(self).hash_stable(hcx, hasher);
898         match *self {
899             hir::AssociatedItemKind::Const |
900             hir::AssociatedItemKind::Existential |
901             hir::AssociatedItemKind::Type => {
902                 // No fields to hash.
903             }
904             hir::AssociatedItemKind::Method { has_self } => {
905                 has_self.hash_stable(hcx, hasher);
906             }
907         }
908     }
909 }
910
911 impl_stable_hash_for!(struct hir::ForeignItem {
912     name,
913     attrs,
914     node,
915     id,
916     span,
917     vis
918 });
919
920 impl_stable_hash_for!(enum hir::ForeignItemKind {
921     Fn(fn_decl, arg_names, generics),
922     Static(ty, is_mutbl),
923     Type
924 });
925
926 impl_stable_hash_for!(enum hir::StmtKind {
927     Decl(decl, id),
928     Expr(expr, id),
929     Semi(expr, id)
930 });
931
932 impl_stable_hash_for!(struct hir::Arg {
933     pat,
934     id,
935     hir_id
936 });
937
938 impl<'a> HashStable<StableHashingContext<'a>> for hir::Body {
939     fn hash_stable<W: StableHasherResult>(&self,
940                                           hcx: &mut StableHashingContext<'a>,
941                                           hasher: &mut StableHasher<W>) {
942         let hir::Body {
943             ref arguments,
944             ref value,
945             is_generator,
946         } = *self;
947
948         hcx.with_node_id_hashing_mode(NodeIdHashingMode::Ignore, |hcx| {
949             arguments.hash_stable(hcx, hasher);
950             value.hash_stable(hcx, hasher);
951             is_generator.hash_stable(hcx, hasher);
952         });
953     }
954 }
955
956 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::BodyId {
957     type KeyType = (DefPathHash, hir::ItemLocalId);
958
959     #[inline]
960     fn to_stable_hash_key(&self,
961                           hcx: &StableHashingContext<'a>)
962                           -> (DefPathHash, hir::ItemLocalId) {
963         let hir::BodyId { node_id } = *self;
964         node_id.to_stable_hash_key(hcx)
965     }
966 }
967
968 impl_stable_hash_for!(struct hir::InlineAsmOutput {
969     constraint,
970     is_rw,
971     is_indirect
972 });
973
974 impl_stable_hash_for!(struct hir::GlobalAsm {
975     asm,
976     ctxt -> _, // This is used for error reporting
977 });
978
979 impl_stable_hash_for!(struct hir::InlineAsm {
980     asm,
981     asm_str_style,
982     outputs,
983     inputs,
984     clobbers,
985     volatile,
986     alignstack,
987     dialect,
988     ctxt -> _, // This is used for error reporting
989 });
990
991 impl_stable_hash_for!(enum hir::def::CtorKind {
992     Fn,
993     Const,
994     Fictive
995 });
996
997 impl_stable_hash_for!(enum hir::def::NonMacroAttrKind {
998     Builtin,
999     Tool,
1000     DeriveHelper,
1001     Custom,
1002 });
1003
1004 impl_stable_hash_for!(enum hir::def::Def {
1005     Mod(def_id),
1006     Struct(def_id),
1007     Union(def_id),
1008     Enum(def_id),
1009     Existential(def_id),
1010     Variant(def_id),
1011     Trait(def_id),
1012     TyAlias(def_id),
1013     TraitAlias(def_id),
1014     AssociatedTy(def_id),
1015     AssociatedExistential(def_id),
1016     PrimTy(prim_ty),
1017     TyParam(def_id),
1018     SelfTy(trait_def_id, impl_def_id),
1019     ForeignTy(def_id),
1020     Fn(def_id),
1021     Const(def_id),
1022     Static(def_id, is_mutbl),
1023     StructCtor(def_id, ctor_kind),
1024     VariantCtor(def_id, ctor_kind),
1025     Method(def_id),
1026     AssociatedConst(def_id),
1027     Local(def_id),
1028     Upvar(def_id, index, expr_id),
1029     Label(node_id),
1030     Macro(def_id, macro_kind),
1031     ToolMod,
1032     NonMacroAttr(attr_kind),
1033     Err
1034 });
1035
1036 impl_stable_hash_for!(enum hir::Mutability {
1037     MutMutable,
1038     MutImmutable
1039 });
1040
1041 impl_stable_hash_for!(enum hir::IsAuto {
1042     Yes,
1043     No
1044 });
1045
1046 impl_stable_hash_for!(enum hir::Unsafety {
1047     Unsafe,
1048     Normal
1049 });
1050
1051 impl_stable_hash_for!(enum hir::IsAsync {
1052     Async,
1053     NotAsync
1054 });
1055
1056 impl_stable_hash_for!(enum hir::Constness {
1057     Const,
1058     NotConst
1059 });
1060
1061 impl<'a> HashStable<StableHashingContext<'a>> for hir::def_id::DefIndex {
1062
1063     fn hash_stable<W: StableHasherResult>(&self,
1064                                           hcx: &mut StableHashingContext<'a>,
1065                                           hasher: &mut StableHasher<W>) {
1066         hcx.local_def_path_hash(*self).hash_stable(hcx, hasher);
1067     }
1068 }
1069
1070 impl<'a> ToStableHashKey<StableHashingContext<'a>>
1071 for hir::def_id::DefIndex {
1072     type KeyType = DefPathHash;
1073
1074     #[inline]
1075     fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
1076          hcx.local_def_path_hash(*self)
1077     }
1078 }
1079
1080 impl_stable_hash_for!(struct hir::def::Export {
1081     ident,
1082     def,
1083     vis,
1084     span
1085 });
1086
1087 impl_stable_hash_for!(struct ::middle::lib_features::LibFeatures {
1088     stable,
1089     unstable
1090 });
1091
1092 impl<'a> HashStable<StableHashingContext<'a>> for ::middle::lang_items::LangItem {
1093     fn hash_stable<W: StableHasherResult>(&self,
1094                                           _: &mut StableHashingContext<'a>,
1095                                           hasher: &mut StableHasher<W>) {
1096         ::std::hash::Hash::hash(self, hasher);
1097     }
1098 }
1099
1100 impl_stable_hash_for!(struct ::middle::lang_items::LanguageItems {
1101     items,
1102     missing
1103 });
1104
1105 impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitCandidate {
1106     fn hash_stable<W: StableHasherResult>(&self,
1107                                           hcx: &mut StableHashingContext<'a>,
1108                                           hasher: &mut StableHasher<W>) {
1109         hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
1110             let hir::TraitCandidate {
1111                 def_id,
1112                 import_id,
1113             } = *self;
1114
1115             def_id.hash_stable(hcx, hasher);
1116             import_id.hash_stable(hcx, hasher);
1117         });
1118     }
1119 }
1120
1121 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::TraitCandidate {
1122     type KeyType = (DefPathHash, Option<(DefPathHash, hir::ItemLocalId)>);
1123
1124     fn to_stable_hash_key(&self,
1125                           hcx: &StableHashingContext<'a>)
1126                           -> Self::KeyType {
1127         let hir::TraitCandidate {
1128             def_id,
1129             import_id,
1130         } = *self;
1131
1132         let import_id = import_id.map(|node_id| hcx.node_to_hir_id(node_id))
1133                                  .map(|hir_id| (hcx.local_def_path_hash(hir_id.owner),
1134                                                 hir_id.local_id));
1135         (hcx.def_path_hash(def_id), import_id)
1136     }
1137 }
1138
1139 impl_stable_hash_for!(struct hir::CodegenFnAttrs {
1140     flags,
1141     inline,
1142     export_name,
1143     link_name,
1144     target_features,
1145     linkage,
1146     link_section,
1147 });
1148
1149 impl<'hir> HashStable<StableHashingContext<'hir>> for hir::CodegenFnAttrFlags
1150 {
1151     fn hash_stable<W: StableHasherResult>(&self,
1152                                           hcx: &mut StableHashingContext<'hir>,
1153                                           hasher: &mut StableHasher<W>) {
1154         self.bits().hash_stable(hcx, hasher);
1155     }
1156 }
1157
1158 impl<'hir> HashStable<StableHashingContext<'hir>> for attr::InlineAttr {
1159     fn hash_stable<W: StableHasherResult>(&self,
1160                                           hcx: &mut StableHashingContext<'hir>,
1161                                           hasher: &mut StableHasher<W>) {
1162         mem::discriminant(self).hash_stable(hcx, hasher);
1163     }
1164 }
1165
1166 impl_stable_hash_for!(struct hir::Freevar {
1167     def,
1168     span
1169 });