]> git.lizzy.rs Git - rust.git/blob - src/librustc/ich/impls_hir.rs
Auto merge of #53533 - withoutboats:error-source, r=withoutboats
[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!(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::ExprKind {
546     Box(sub),
547     Array(subs),
548     Call(callee, args),
549     MethodCall(segment, span, args),
550     Tup(fields),
551     Binary(op, lhs, rhs),
552     Unary(op, operand),
553     Lit(value),
554     Cast(expr, t),
555     Type(expr, t),
556     If(cond, then, els),
557     While(cond, body, label),
558     Loop(body, label, loop_src),
559     Match(matchee, arms, match_src),
560     Closure(capture_clause, decl, body_id, span, gen),
561     Block(blk, label),
562     Assign(lhs, rhs),
563     AssignOp(op, lhs, rhs),
564     Field(owner, ident),
565     Index(lhs, rhs),
566     Path(path),
567     AddrOf(mutability, sub),
568     Break(destination, sub),
569     Continue(destination),
570     Ret(val),
571     InlineAsm(asm, inputs, outputs),
572     Struct(path, fields, base),
573     Repeat(val, times),
574     Yield(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     Existential(bounds),
706     Type(t)
707 });
708
709 impl_stable_hash_for!(enum ::syntax::ast::CrateSugar {
710     JustCrate,
711     PubCrate,
712 });
713
714 impl<'a> HashStable<StableHashingContext<'a>> for hir::VisibilityKind {
715     fn hash_stable<W: StableHasherResult>(&self,
716                                           hcx: &mut StableHashingContext<'a>,
717                                           hasher: &mut StableHasher<W>) {
718         mem::discriminant(self).hash_stable(hcx, hasher);
719         match *self {
720             hir::VisibilityKind::Public |
721             hir::VisibilityKind::Inherited => {
722                 // No fields to hash.
723             }
724             hir::VisibilityKind::Crate(sugar) => {
725                 sugar.hash_stable(hcx, hasher);
726             }
727             hir::VisibilityKind::Restricted { ref path, id, hir_id } => {
728                 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
729                     id.hash_stable(hcx, hasher);
730                     hir_id.hash_stable(hcx, hasher);
731                 });
732                 path.hash_stable(hcx, hasher);
733             }
734         }
735     }
736 }
737
738 impl_stable_hash_for_spanned!(hir::VisibilityKind);
739
740 impl<'a> HashStable<StableHashingContext<'a>> for hir::Defaultness {
741     fn hash_stable<W: StableHasherResult>(&self,
742                                           hcx: &mut StableHashingContext<'a>,
743                                           hasher: &mut StableHasher<W>) {
744         mem::discriminant(self).hash_stable(hcx, hasher);
745         match *self {
746             hir::Defaultness::Final => {
747                 // No fields to hash.
748             }
749             hir::Defaultness::Default { has_value } => {
750                 has_value.hash_stable(hcx, hasher);
751             }
752         }
753     }
754 }
755
756 impl_stable_hash_for!(enum hir::ImplPolarity {
757     Positive,
758     Negative
759 });
760
761 impl<'a> HashStable<StableHashingContext<'a>> for hir::Mod {
762     fn hash_stable<W: StableHasherResult>(&self,
763                                           hcx: &mut StableHashingContext<'a>,
764                                           hasher: &mut StableHasher<W>) {
765         let hir::Mod {
766             inner: ref inner_span,
767             ref item_ids,
768         } = *self;
769
770         inner_span.hash_stable(hcx, hasher);
771
772         // Combining the DefPathHashes directly is faster than feeding them
773         // into the hasher. Because we use a commutative combine, we also don't
774         // have to sort the array.
775         let item_ids_hash = item_ids
776             .iter()
777             .map(|id| {
778                 let (def_path_hash, local_id) = id.id.to_stable_hash_key(hcx);
779                 debug_assert_eq!(local_id, hir::ItemLocalId(0));
780                 def_path_hash.0
781             }).fold(Fingerprint::ZERO, |a, b| {
782                 a.combine_commutative(b)
783             });
784
785         item_ids.len().hash_stable(hcx, hasher);
786         item_ids_hash.hash_stable(hcx, hasher);
787     }
788 }
789
790 impl_stable_hash_for!(struct hir::ForeignMod {
791     abi,
792     items
793 });
794
795 impl_stable_hash_for!(struct hir::EnumDef {
796     variants
797 });
798
799 impl_stable_hash_for!(struct hir::VariantKind {
800     name,
801     attrs,
802     data,
803     disr_expr
804 });
805
806 impl_stable_hash_for_spanned!(hir::VariantKind);
807
808 impl_stable_hash_for!(enum hir::UseKind {
809     Single,
810     Glob,
811     ListStem
812 });
813
814 impl_stable_hash_for!(struct hir::StructField {
815     span,
816     ident -> (ident.name),
817     vis,
818     id,
819     ty,
820     attrs
821 });
822
823 impl_stable_hash_for!(enum hir::VariantData {
824     Struct(fields, id),
825     Tuple(fields, id),
826     Unit(id)
827 });
828
829 impl<'a> HashStable<StableHashingContext<'a>> for hir::Item {
830     fn hash_stable<W: StableHasherResult>(&self,
831                                           hcx: &mut StableHashingContext<'a>,
832                                           hasher: &mut StableHasher<W>) {
833         let hir::Item {
834             name,
835             ref attrs,
836             id: _,
837             hir_id: _,
838             ref node,
839             ref vis,
840             span
841         } = *self;
842
843         hcx.hash_hir_item_like(|hcx| {
844             name.hash_stable(hcx, hasher);
845             attrs.hash_stable(hcx, hasher);
846             node.hash_stable(hcx, hasher);
847             vis.hash_stable(hcx, hasher);
848             span.hash_stable(hcx, hasher);
849         });
850     }
851 }
852
853 impl_stable_hash_for!(enum hir::ItemKind {
854     ExternCrate(orig_name),
855     Use(path, use_kind),
856     Static(ty, mutability, body_id),
857     Const(ty, body_id),
858     Fn(fn_decl, header, generics, body_id),
859     Mod(module),
860     ForeignMod(foreign_mod),
861     GlobalAsm(global_asm),
862     Ty(ty, generics),
863     Existential(exist),
864     Enum(enum_def, generics),
865     Struct(variant_data, generics),
866     Union(variant_data, generics),
867     Trait(is_auto, unsafety, generics, bounds, item_refs),
868     TraitAlias(generics, bounds),
869     Impl(unsafety, impl_polarity, impl_defaultness, generics, trait_ref, ty, impl_item_refs)
870 });
871
872 impl_stable_hash_for!(struct hir::TraitItemRef {
873     id,
874     ident -> (ident.name),
875     kind,
876     span,
877     defaultness
878 });
879
880 impl_stable_hash_for!(struct hir::ImplItemRef {
881     id,
882     ident -> (ident.name),
883     kind,
884     span,
885     vis,
886     defaultness
887 });
888
889 impl<'a> HashStable<StableHashingContext<'a>> for hir::AssociatedItemKind {
890     fn hash_stable<W: StableHasherResult>(&self,
891                                           hcx: &mut StableHashingContext<'a>,
892                                           hasher: &mut StableHasher<W>) {
893         mem::discriminant(self).hash_stable(hcx, hasher);
894         match *self {
895             hir::AssociatedItemKind::Const |
896             hir::AssociatedItemKind::Existential |
897             hir::AssociatedItemKind::Type => {
898                 // No fields to hash.
899             }
900             hir::AssociatedItemKind::Method { has_self } => {
901                 has_self.hash_stable(hcx, hasher);
902             }
903         }
904     }
905 }
906
907 impl_stable_hash_for!(struct hir::ForeignItem {
908     name,
909     attrs,
910     node,
911     id,
912     span,
913     vis
914 });
915
916 impl_stable_hash_for!(enum hir::ForeignItemKind {
917     Fn(fn_decl, arg_names, generics),
918     Static(ty, is_mutbl),
919     Type
920 });
921
922 impl_stable_hash_for!(enum hir::StmtKind {
923     Decl(decl, id),
924     Expr(expr, id),
925     Semi(expr, id)
926 });
927
928 impl_stable_hash_for!(struct hir::Arg {
929     pat,
930     id,
931     hir_id
932 });
933
934 impl<'a> HashStable<StableHashingContext<'a>> for hir::Body {
935     fn hash_stable<W: StableHasherResult>(&self,
936                                           hcx: &mut StableHashingContext<'a>,
937                                           hasher: &mut StableHasher<W>) {
938         let hir::Body {
939             ref arguments,
940             ref value,
941             is_generator,
942         } = *self;
943
944         hcx.with_node_id_hashing_mode(NodeIdHashingMode::Ignore, |hcx| {
945             arguments.hash_stable(hcx, hasher);
946             value.hash_stable(hcx, hasher);
947             is_generator.hash_stable(hcx, hasher);
948         });
949     }
950 }
951
952 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::BodyId {
953     type KeyType = (DefPathHash, hir::ItemLocalId);
954
955     #[inline]
956     fn to_stable_hash_key(&self,
957                           hcx: &StableHashingContext<'a>)
958                           -> (DefPathHash, hir::ItemLocalId) {
959         let hir::BodyId { node_id } = *self;
960         node_id.to_stable_hash_key(hcx)
961     }
962 }
963
964 impl_stable_hash_for!(struct hir::InlineAsmOutput {
965     constraint,
966     is_rw,
967     is_indirect
968 });
969
970 impl_stable_hash_for!(struct hir::GlobalAsm {
971     asm,
972     ctxt -> _, // This is used for error reporting
973 });
974
975 impl_stable_hash_for!(struct hir::InlineAsm {
976     asm,
977     asm_str_style,
978     outputs,
979     inputs,
980     clobbers,
981     volatile,
982     alignstack,
983     dialect,
984     ctxt -> _, // This is used for error reporting
985 });
986
987 impl_stable_hash_for!(enum hir::def::CtorKind {
988     Fn,
989     Const,
990     Fictive
991 });
992
993 impl_stable_hash_for!(enum hir::def::NonMacroAttrKind {
994     Builtin,
995     Tool,
996     DeriveHelper,
997     Custom,
998 });
999
1000 impl_stable_hash_for!(enum hir::def::Def {
1001     Mod(def_id),
1002     Struct(def_id),
1003     Union(def_id),
1004     Enum(def_id),
1005     Existential(def_id),
1006     Variant(def_id),
1007     Trait(def_id),
1008     TyAlias(def_id),
1009     TraitAlias(def_id),
1010     AssociatedTy(def_id),
1011     AssociatedExistential(def_id),
1012     PrimTy(prim_ty),
1013     TyParam(def_id),
1014     SelfTy(trait_def_id, impl_def_id),
1015     ForeignTy(def_id),
1016     Fn(def_id),
1017     Const(def_id),
1018     Static(def_id, is_mutbl),
1019     StructCtor(def_id, ctor_kind),
1020     VariantCtor(def_id, ctor_kind),
1021     Method(def_id),
1022     AssociatedConst(def_id),
1023     Local(def_id),
1024     Upvar(def_id, index, expr_id),
1025     Label(node_id),
1026     Macro(def_id, macro_kind),
1027     ToolMod,
1028     NonMacroAttr(attr_kind),
1029     Err
1030 });
1031
1032 impl_stable_hash_for!(enum hir::Mutability {
1033     MutMutable,
1034     MutImmutable
1035 });
1036
1037 impl_stable_hash_for!(enum hir::IsAuto {
1038     Yes,
1039     No
1040 });
1041
1042 impl_stable_hash_for!(enum hir::Unsafety {
1043     Unsafe,
1044     Normal
1045 });
1046
1047 impl_stable_hash_for!(enum hir::IsAsync {
1048     Async,
1049     NotAsync
1050 });
1051
1052 impl_stable_hash_for!(enum hir::Constness {
1053     Const,
1054     NotConst
1055 });
1056
1057 impl<'a> HashStable<StableHashingContext<'a>> for hir::def_id::DefIndex {
1058
1059     fn hash_stable<W: StableHasherResult>(&self,
1060                                           hcx: &mut StableHashingContext<'a>,
1061                                           hasher: &mut StableHasher<W>) {
1062         hcx.local_def_path_hash(*self).hash_stable(hcx, hasher);
1063     }
1064 }
1065
1066 impl<'a> ToStableHashKey<StableHashingContext<'a>>
1067 for hir::def_id::DefIndex {
1068     type KeyType = DefPathHash;
1069
1070     #[inline]
1071     fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
1072          hcx.local_def_path_hash(*self)
1073     }
1074 }
1075
1076 impl_stable_hash_for!(struct hir::def::Export {
1077     ident,
1078     def,
1079     vis,
1080     span
1081 });
1082
1083 impl_stable_hash_for!(struct ::middle::lib_features::LibFeatures {
1084     stable,
1085     unstable
1086 });
1087
1088 impl<'a> HashStable<StableHashingContext<'a>> for ::middle::lang_items::LangItem {
1089     fn hash_stable<W: StableHasherResult>(&self,
1090                                           _: &mut StableHashingContext<'a>,
1091                                           hasher: &mut StableHasher<W>) {
1092         ::std::hash::Hash::hash(self, hasher);
1093     }
1094 }
1095
1096 impl_stable_hash_for!(struct ::middle::lang_items::LanguageItems {
1097     items,
1098     missing
1099 });
1100
1101 impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitCandidate {
1102     fn hash_stable<W: StableHasherResult>(&self,
1103                                           hcx: &mut StableHashingContext<'a>,
1104                                           hasher: &mut StableHasher<W>) {
1105         hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
1106             let hir::TraitCandidate {
1107                 def_id,
1108                 import_id,
1109             } = *self;
1110
1111             def_id.hash_stable(hcx, hasher);
1112             import_id.hash_stable(hcx, hasher);
1113         });
1114     }
1115 }
1116
1117 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::TraitCandidate {
1118     type KeyType = (DefPathHash, Option<(DefPathHash, hir::ItemLocalId)>);
1119
1120     fn to_stable_hash_key(&self,
1121                           hcx: &StableHashingContext<'a>)
1122                           -> Self::KeyType {
1123         let hir::TraitCandidate {
1124             def_id,
1125             import_id,
1126         } = *self;
1127
1128         let import_id = import_id.map(|node_id| hcx.node_to_hir_id(node_id))
1129                                  .map(|hir_id| (hcx.local_def_path_hash(hir_id.owner),
1130                                                 hir_id.local_id));
1131         (hcx.def_path_hash(def_id), import_id)
1132     }
1133 }
1134
1135 impl_stable_hash_for!(struct hir::CodegenFnAttrs {
1136     flags,
1137     inline,
1138     export_name,
1139     link_name,
1140     target_features,
1141     linkage,
1142     link_section,
1143 });
1144
1145 impl<'hir> HashStable<StableHashingContext<'hir>> for hir::CodegenFnAttrFlags
1146 {
1147     fn hash_stable<W: StableHasherResult>(&self,
1148                                           hcx: &mut StableHashingContext<'hir>,
1149                                           hasher: &mut StableHasher<W>) {
1150         self.bits().hash_stable(hcx, hasher);
1151     }
1152 }
1153
1154 impl<'hir> HashStable<StableHashingContext<'hir>> for attr::InlineAttr {
1155     fn hash_stable<W: StableHasherResult>(&self,
1156                                           hcx: &mut StableHashingContext<'hir>,
1157                                           hasher: &mut StableHasher<W>) {
1158         mem::discriminant(self).hash_stable(hcx, hasher);
1159     }
1160 }
1161
1162 impl_stable_hash_for!(struct hir::Freevar {
1163     def,
1164     span
1165 });