]> git.lizzy.rs Git - rust.git/blob - src/librustc/ich/impls_hir.rs
69872cffdc1b1ea54891628ce55e3583690f1d7c
[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     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::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     path,
364 });
365
366 impl_stable_hash_for!(struct hir::PolyTraitRef {
367     bound_generic_params,
368     trait_ref,
369     span
370 });
371
372 impl_stable_hash_for!(enum hir::QPath {
373     Resolved(t, path),
374     TypeRelative(t, path_segment)
375 });
376
377 impl_stable_hash_for!(struct hir::MacroDef {
378     name,
379     vis,
380     attrs,
381     id,
382     span,
383     legacy,
384     body
385 });
386
387 impl_stable_hash_for!(struct hir::Block {
388     stmts,
389     expr,
390     id -> _,
391     hir_id -> _,
392     rules,
393     span,
394     targeted_by_break,
395     recovered,
396 });
397
398 impl_stable_hash_for!(struct hir::Pat {
399     id -> _,
400     hir_id -> _,
401     node,
402     span,
403 });
404
405 impl_stable_hash_for_spanned!(hir::FieldPat);
406
407 impl_stable_hash_for!(struct hir::FieldPat {
408     id -> _,
409     ident -> (ident.name),
410     pat,
411     is_shorthand,
412 });
413
414 impl_stable_hash_for!(enum hir::BindingAnnotation {
415     Unannotated,
416     Mutable,
417     Ref,
418     RefMut
419 });
420
421 impl_stable_hash_for!(enum hir::RangeEnd {
422     Included,
423     Excluded
424 });
425
426 impl_stable_hash_for!(enum hir::PatKind {
427     Wild,
428     Binding(binding_mode, var, name, sub),
429     Struct(path, field_pats, dotdot),
430     TupleStruct(path, field_pats, dotdot),
431     Path(path),
432     Tuple(field_pats, dotdot),
433     Box(sub),
434     Ref(sub, mutability),
435     Lit(expr),
436     Range(start, end, end_kind),
437     Slice(one, two, three)
438 });
439
440 impl_stable_hash_for!(enum hir::BinOpKind {
441     Add,
442     Sub,
443     Mul,
444     Div,
445     Rem,
446     And,
447     Or,
448     BitXor,
449     BitAnd,
450     BitOr,
451     Shl,
452     Shr,
453     Eq,
454     Lt,
455     Le,
456     Ne,
457     Ge,
458     Gt
459 });
460
461 impl_stable_hash_for_spanned!(hir::BinOpKind);
462
463 impl_stable_hash_for!(enum hir::UnOp {
464     UnDeref,
465     UnNot,
466     UnNeg
467 });
468
469 impl_stable_hash_for_spanned!(hir::StmtKind);
470
471 impl_stable_hash_for!(struct hir::Local {
472     pat,
473     ty,
474     init,
475     id,
476     hir_id,
477     span,
478     attrs,
479     source
480 });
481
482 impl_stable_hash_for_spanned!(hir::DeclKind);
483 impl_stable_hash_for!(enum hir::DeclKind {
484     Local(local),
485     Item(item_id)
486 });
487
488 impl_stable_hash_for!(struct hir::Arm {
489     attrs,
490     pats,
491     guard,
492     body
493 });
494
495 impl_stable_hash_for!(struct hir::Field {
496     id -> _,
497     ident,
498     expr,
499     span,
500     is_shorthand,
501 });
502
503 impl_stable_hash_for_spanned!(ast::Name);
504
505
506 impl_stable_hash_for!(enum hir::BlockCheckMode {
507     DefaultBlock,
508     UnsafeBlock(src),
509     PushUnsafeBlock(src),
510     PopUnsafeBlock(src)
511 });
512
513 impl_stable_hash_for!(enum hir::UnsafeSource {
514     CompilerGenerated,
515     UserProvided
516 });
517
518 impl_stable_hash_for!(struct hir::AnonConst {
519     id,
520     hir_id,
521     body
522 });
523
524 impl<'a> HashStable<StableHashingContext<'a>> for hir::Expr {
525     fn hash_stable<W: StableHasherResult>(&self,
526                                           hcx: &mut StableHashingContext<'a>,
527                                           hasher: &mut StableHasher<W>) {
528         hcx.while_hashing_hir_bodies(true, |hcx| {
529             let hir::Expr {
530                 id: _,
531                 hir_id: _,
532                 ref span,
533                 ref node,
534                 ref attrs
535             } = *self;
536
537             span.hash_stable(hcx, hasher);
538             node.hash_stable(hcx, hasher);
539             attrs.hash_stable(hcx, hasher);
540         })
541     }
542 }
543
544 impl_stable_hash_for!(enum hir::ExprKind {
545     Box(sub),
546     Array(subs),
547     Call(callee, args),
548     MethodCall(segment, span, args),
549     Tup(fields),
550     Binary(op, lhs, rhs),
551     Unary(op, operand),
552     Lit(value),
553     Cast(expr, t),
554     Type(expr, t),
555     If(cond, then, els),
556     While(cond, body, label),
557     Loop(body, label, loop_src),
558     Match(matchee, arms, match_src),
559     Closure(capture_clause, decl, body_id, span, gen),
560     Block(blk, label),
561     Assign(lhs, rhs),
562     AssignOp(op, lhs, rhs),
563     Field(owner, ident),
564     Index(lhs, rhs),
565     Path(path),
566     AddrOf(mutability, sub),
567     Break(destination, sub),
568     Continue(destination),
569     Ret(val),
570     InlineAsm(asm, inputs, outputs),
571     Struct(path, fields, base),
572     Repeat(val, times),
573     Yield(val)
574 });
575
576 impl_stable_hash_for!(enum hir::LocalSource {
577     Normal,
578     ForLoopDesugar
579 });
580
581 impl_stable_hash_for!(enum hir::LoopSource {
582     Loop,
583     WhileLet,
584     ForLoop
585 });
586
587 impl<'a> HashStable<StableHashingContext<'a>> for hir::MatchSource {
588     fn hash_stable<W: StableHasherResult>(&self,
589                                           hcx: &mut StableHashingContext<'a>,
590                                           hasher: &mut StableHasher<W>) {
591         use hir::MatchSource;
592
593         mem::discriminant(self).hash_stable(hcx, hasher);
594         match *self {
595             MatchSource::Normal |
596             MatchSource::WhileLetDesugar |
597             MatchSource::ForLoopDesugar |
598             MatchSource::TryDesugar => {
599                 // No fields to hash.
600             }
601             MatchSource::IfLetDesugar { contains_else_clause } => {
602                 contains_else_clause.hash_stable(hcx, hasher);
603             }
604         }
605     }
606 }
607
608 impl_stable_hash_for!(enum hir::GeneratorMovability {
609     Static,
610     Movable
611 });
612
613 impl_stable_hash_for!(enum hir::CaptureClause {
614     CaptureByValue,
615     CaptureByRef
616 });
617
618 impl_stable_hash_for_spanned!(usize);
619
620 impl_stable_hash_for!(struct hir::Destination {
621     label,
622     target_id
623 });
624
625 impl_stable_hash_for_spanned!(ast::Ident);
626
627 impl_stable_hash_for!(enum hir::LoopIdError {
628     OutsideLoopScope,
629     UnlabeledCfInWhileCondition,
630     UnresolvedLabel
631 });
632
633 impl_stable_hash_for!(struct ast::Ident {
634     name,
635     span,
636 });
637
638 impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitItem {
639     fn hash_stable<W: StableHasherResult>(&self,
640                                           hcx: &mut StableHashingContext<'a>,
641                                           hasher: &mut StableHasher<W>) {
642         let hir::TraitItem {
643             id: _,
644             hir_id: _,
645             ident,
646             ref attrs,
647             ref generics,
648             ref node,
649             span
650         } = *self;
651
652         hcx.hash_hir_item_like(|hcx| {
653             ident.name.hash_stable(hcx, hasher);
654             attrs.hash_stable(hcx, hasher);
655             generics.hash_stable(hcx, hasher);
656             node.hash_stable(hcx, hasher);
657             span.hash_stable(hcx, hasher);
658         });
659     }
660 }
661
662 impl_stable_hash_for!(enum hir::TraitMethod {
663     Required(name),
664     Provided(body)
665 });
666
667 impl_stable_hash_for!(enum hir::TraitItemKind {
668     Const(t, body),
669     Method(sig, method),
670     Type(bounds, rhs)
671 });
672
673 impl<'a> HashStable<StableHashingContext<'a>> for hir::ImplItem {
674     fn hash_stable<W: StableHasherResult>(&self,
675                                           hcx: &mut StableHashingContext<'a>,
676                                           hasher: &mut StableHasher<W>) {
677         let hir::ImplItem {
678             id: _,
679             hir_id: _,
680             ident,
681             ref vis,
682             defaultness,
683             ref attrs,
684             ref generics,
685             ref node,
686             span
687         } = *self;
688
689         hcx.hash_hir_item_like(|hcx| {
690             ident.name.hash_stable(hcx, hasher);
691             vis.hash_stable(hcx, hasher);
692             defaultness.hash_stable(hcx, hasher);
693             attrs.hash_stable(hcx, hasher);
694             generics.hash_stable(hcx, hasher);
695             node.hash_stable(hcx, hasher);
696             span.hash_stable(hcx, hasher);
697         });
698     }
699 }
700
701 impl_stable_hash_for!(enum hir::ImplItemKind {
702     Const(t, body),
703     Method(sig, body),
704     Existential(bounds),
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<'a> HashStable<StableHashingContext<'a>> for hir::Mod {
760     fn hash_stable<W: StableHasherResult>(&self,
761                                           hcx: &mut StableHashingContext<'a>,
762                                           hasher: &mut StableHasher<W>) {
763         let hir::Mod {
764             inner: ref inner_span,
765             ref item_ids,
766         } = *self;
767
768         inner_span.hash_stable(hcx, hasher);
769
770         // Combining the DefPathHashes directly is faster than feeding them
771         // into the hasher. Because we use a commutative combine, we also don't
772         // have to sort the array.
773         let item_ids_hash = item_ids
774             .iter()
775             .map(|id| {
776                 let (def_path_hash, local_id) = id.id.to_stable_hash_key(hcx);
777                 debug_assert_eq!(local_id, hir::ItemLocalId(0));
778                 def_path_hash.0
779             }).fold(Fingerprint::ZERO, |a, b| {
780                 a.combine_commutative(b)
781             });
782
783         item_ids.len().hash_stable(hcx, hasher);
784         item_ids_hash.hash_stable(hcx, hasher);
785     }
786 }
787
788 impl_stable_hash_for!(struct hir::ForeignMod {
789     abi,
790     items
791 });
792
793 impl_stable_hash_for!(struct hir::EnumDef {
794     variants
795 });
796
797 impl_stable_hash_for!(struct hir::VariantKind {
798     name,
799     attrs,
800     data,
801     disr_expr
802 });
803
804 impl_stable_hash_for_spanned!(hir::VariantKind);
805
806 impl_stable_hash_for!(enum hir::UseKind {
807     Single,
808     Glob,
809     ListStem
810 });
811
812 impl_stable_hash_for!(struct hir::StructField {
813     span,
814     ident -> (ident.name),
815     vis,
816     id,
817     ty,
818     attrs
819 });
820
821 impl_stable_hash_for!(enum hir::VariantData {
822     Struct(fields, id),
823     Tuple(fields, id),
824     Unit(id)
825 });
826
827 impl<'a> HashStable<StableHashingContext<'a>> for hir::Item {
828     fn hash_stable<W: StableHasherResult>(&self,
829                                           hcx: &mut StableHashingContext<'a>,
830                                           hasher: &mut StableHasher<W>) {
831         let hir::Item {
832             name,
833             ref attrs,
834             id: _,
835             hir_id: _,
836             ref node,
837             ref vis,
838             span
839         } = *self;
840
841         hcx.hash_hir_item_like(|hcx| {
842             name.hash_stable(hcx, hasher);
843             attrs.hash_stable(hcx, hasher);
844             node.hash_stable(hcx, hasher);
845             vis.hash_stable(hcx, hasher);
846             span.hash_stable(hcx, hasher);
847         });
848     }
849 }
850
851 impl_stable_hash_for!(enum hir::ItemKind {
852     ExternCrate(orig_name),
853     Use(path, use_kind),
854     Static(ty, mutability, body_id),
855     Const(ty, body_id),
856     Fn(fn_decl, header, generics, body_id),
857     Mod(module),
858     ForeignMod(foreign_mod),
859     GlobalAsm(global_asm),
860     Ty(ty, generics),
861     Existential(exist),
862     Enum(enum_def, generics),
863     Struct(variant_data, generics),
864     Union(variant_data, generics),
865     Trait(is_auto, unsafety, generics, bounds, item_refs),
866     TraitAlias(generics, bounds),
867     Impl(unsafety, impl_polarity, impl_defaultness, generics, trait_ref, ty, impl_item_refs)
868 });
869
870 impl_stable_hash_for!(struct hir::TraitItemRef {
871     id,
872     ident -> (ident.name),
873     kind,
874     span,
875     defaultness
876 });
877
878 impl_stable_hash_for!(struct hir::ImplItemRef {
879     id,
880     ident -> (ident.name),
881     kind,
882     span,
883     vis,
884     defaultness
885 });
886
887 impl<'a> HashStable<StableHashingContext<'a>> for hir::AssociatedItemKind {
888     fn hash_stable<W: StableHasherResult>(&self,
889                                           hcx: &mut StableHashingContext<'a>,
890                                           hasher: &mut StableHasher<W>) {
891         mem::discriminant(self).hash_stable(hcx, hasher);
892         match *self {
893             hir::AssociatedItemKind::Const |
894             hir::AssociatedItemKind::Existential |
895             hir::AssociatedItemKind::Type => {
896                 // No fields to hash.
897             }
898             hir::AssociatedItemKind::Method { has_self } => {
899                 has_self.hash_stable(hcx, hasher);
900             }
901         }
902     }
903 }
904
905 impl_stable_hash_for!(struct hir::ForeignItem {
906     name,
907     attrs,
908     node,
909     id,
910     span,
911     vis
912 });
913
914 impl_stable_hash_for!(enum hir::ForeignItemKind {
915     Fn(fn_decl, arg_names, generics),
916     Static(ty, is_mutbl),
917     Type
918 });
919
920 impl_stable_hash_for!(enum hir::StmtKind {
921     Decl(decl, id),
922     Expr(expr, id),
923     Semi(expr, id)
924 });
925
926 impl_stable_hash_for!(struct hir::Arg {
927     pat,
928     id,
929     hir_id
930 });
931
932 impl<'a> HashStable<StableHashingContext<'a>> for hir::Body {
933     fn hash_stable<W: StableHasherResult>(&self,
934                                           hcx: &mut StableHashingContext<'a>,
935                                           hasher: &mut StableHasher<W>) {
936         let hir::Body {
937             ref arguments,
938             ref value,
939             is_generator,
940         } = *self;
941
942         hcx.with_node_id_hashing_mode(NodeIdHashingMode::Ignore, |hcx| {
943             arguments.hash_stable(hcx, hasher);
944             value.hash_stable(hcx, hasher);
945             is_generator.hash_stable(hcx, hasher);
946         });
947     }
948 }
949
950 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::BodyId {
951     type KeyType = (DefPathHash, hir::ItemLocalId);
952
953     #[inline]
954     fn to_stable_hash_key(&self,
955                           hcx: &StableHashingContext<'a>)
956                           -> (DefPathHash, hir::ItemLocalId) {
957         let hir::BodyId { node_id } = *self;
958         node_id.to_stable_hash_key(hcx)
959     }
960 }
961
962 impl_stable_hash_for!(struct hir::InlineAsmOutput {
963     constraint,
964     is_rw,
965     is_indirect
966 });
967
968 impl_stable_hash_for!(struct hir::GlobalAsm {
969     asm,
970     ctxt -> _, // This is used for error reporting
971 });
972
973 impl_stable_hash_for!(struct hir::InlineAsm {
974     asm,
975     asm_str_style,
976     outputs,
977     inputs,
978     clobbers,
979     volatile,
980     alignstack,
981     dialect,
982     ctxt -> _, // This is used for error reporting
983 });
984
985 impl_stable_hash_for!(enum hir::def::CtorKind {
986     Fn,
987     Const,
988     Fictive
989 });
990
991 impl_stable_hash_for!(enum hir::def::Def {
992     Mod(def_id),
993     Struct(def_id),
994     Union(def_id),
995     Enum(def_id),
996     Existential(def_id),
997     Variant(def_id),
998     Trait(def_id),
999     TyAlias(def_id),
1000     TraitAlias(def_id),
1001     AssociatedTy(def_id),
1002     AssociatedExistential(def_id),
1003     PrimTy(prim_ty),
1004     TyParam(def_id),
1005     SelfTy(trait_def_id, impl_def_id),
1006     TyForeign(def_id),
1007     Fn(def_id),
1008     Const(def_id),
1009     Static(def_id, is_mutbl),
1010     StructCtor(def_id, ctor_kind),
1011     VariantCtor(def_id, ctor_kind),
1012     Method(def_id),
1013     AssociatedConst(def_id),
1014     Local(def_id),
1015     Upvar(def_id, index, expr_id),
1016     Label(node_id),
1017     Macro(def_id, macro_kind),
1018     ToolMod,
1019     NonMacroAttr,
1020     Err
1021 });
1022
1023 impl_stable_hash_for!(enum hir::Mutability {
1024     MutMutable,
1025     MutImmutable
1026 });
1027
1028 impl_stable_hash_for!(enum hir::IsAuto {
1029     Yes,
1030     No
1031 });
1032
1033 impl_stable_hash_for!(enum hir::Unsafety {
1034     Unsafe,
1035     Normal
1036 });
1037
1038 impl_stable_hash_for!(enum hir::IsAsync {
1039     Async,
1040     NotAsync
1041 });
1042
1043 impl_stable_hash_for!(enum hir::Constness {
1044     Const,
1045     NotConst
1046 });
1047
1048 impl<'a> HashStable<StableHashingContext<'a>> for hir::def_id::DefIndex {
1049
1050     fn hash_stable<W: StableHasherResult>(&self,
1051                                           hcx: &mut StableHashingContext<'a>,
1052                                           hasher: &mut StableHasher<W>) {
1053         hcx.local_def_path_hash(*self).hash_stable(hcx, hasher);
1054     }
1055 }
1056
1057 impl<'a> ToStableHashKey<StableHashingContext<'a>>
1058 for hir::def_id::DefIndex {
1059     type KeyType = DefPathHash;
1060
1061     #[inline]
1062     fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
1063          hcx.local_def_path_hash(*self)
1064     }
1065 }
1066
1067 impl_stable_hash_for!(struct hir::def::Export {
1068     ident,
1069     def,
1070     vis,
1071     span
1072 });
1073
1074 impl_stable_hash_for!(struct ::middle::lib_features::LibFeatures {
1075     stable,
1076     unstable
1077 });
1078
1079 impl<'a> HashStable<StableHashingContext<'a>> for ::middle::lang_items::LangItem {
1080     fn hash_stable<W: StableHasherResult>(&self,
1081                                           _: &mut StableHashingContext<'a>,
1082                                           hasher: &mut StableHasher<W>) {
1083         ::std::hash::Hash::hash(self, hasher);
1084     }
1085 }
1086
1087 impl_stable_hash_for!(struct ::middle::lang_items::LanguageItems {
1088     items,
1089     missing
1090 });
1091
1092 impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitCandidate {
1093     fn hash_stable<W: StableHasherResult>(&self,
1094                                           hcx: &mut StableHashingContext<'a>,
1095                                           hasher: &mut StableHasher<W>) {
1096         hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
1097             let hir::TraitCandidate {
1098                 def_id,
1099                 import_id,
1100             } = *self;
1101
1102             def_id.hash_stable(hcx, hasher);
1103             import_id.hash_stable(hcx, hasher);
1104         });
1105     }
1106 }
1107
1108 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::TraitCandidate {
1109     type KeyType = (DefPathHash, Option<(DefPathHash, hir::ItemLocalId)>);
1110
1111     fn to_stable_hash_key(&self,
1112                           hcx: &StableHashingContext<'a>)
1113                           -> Self::KeyType {
1114         let hir::TraitCandidate {
1115             def_id,
1116             import_id,
1117         } = *self;
1118
1119         let import_id = import_id.map(|node_id| hcx.node_to_hir_id(node_id))
1120                                  .map(|hir_id| (hcx.local_def_path_hash(hir_id.owner),
1121                                                 hir_id.local_id));
1122         (hcx.def_path_hash(def_id), import_id)
1123     }
1124 }
1125
1126 impl_stable_hash_for!(struct hir::CodegenFnAttrs {
1127     flags,
1128     inline,
1129     export_name,
1130     target_features,
1131     linkage,
1132     link_section,
1133 });
1134
1135 impl<'hir> HashStable<StableHashingContext<'hir>> for hir::CodegenFnAttrFlags
1136 {
1137     fn hash_stable<W: StableHasherResult>(&self,
1138                                           hcx: &mut StableHashingContext<'hir>,
1139                                           hasher: &mut StableHasher<W>) {
1140         self.bits().hash_stable(hcx, hasher);
1141     }
1142 }
1143
1144 impl<'hir> HashStable<StableHashingContext<'hir>> for attr::InlineAttr {
1145     fn hash_stable<W: StableHasherResult>(&self,
1146                                           hcx: &mut StableHashingContext<'hir>,
1147                                           hasher: &mut StableHasher<W>) {
1148         mem::discriminant(self).hash_stable(hcx, hasher);
1149     }
1150 }
1151
1152 impl_stable_hash_for!(struct hir::Freevar {
1153     def,
1154     span
1155 });