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