]> git.lizzy.rs Git - rust.git/blob - src/librustc/ich/impls_hir.rs
daf59cafc164f90ee643c0049f28d40467116418
[rust.git] / src / librustc / ich / impls_hir.rs
1 // Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 //! This module contains `HashStable` implementations for various HIR data
12 //! types in no particular order.
13
14 use hir;
15 use hir::map::DefPathHash;
16 use hir::def_id::{DefId, LocalDefId, CrateNum, CRATE_DEF_INDEX};
17 use ich::{StableHashingContext, NodeIdHashingMode};
18 use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey,
19                                            StableHasher, StableHasherResult};
20 use std::mem;
21 use syntax::ast;
22 use syntax::attr;
23
24 impl<'a> HashStable<StableHashingContext<'a>> for DefId {
25     #[inline]
26     fn hash_stable<W: StableHasherResult>(&self,
27                                           hcx: &mut StableHashingContext<'a>,
28                                           hasher: &mut StableHasher<W>) {
29         hcx.def_path_hash(*self).hash_stable(hcx, hasher);
30     }
31 }
32
33 impl<'a> ToStableHashKey<StableHashingContext<'a>> for DefId {
34     type KeyType = DefPathHash;
35
36     #[inline]
37     fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
38         hcx.def_path_hash(*self)
39     }
40 }
41
42 impl<'a> HashStable<StableHashingContext<'a>> for LocalDefId {
43     #[inline]
44     fn hash_stable<W: StableHasherResult>(&self,
45                                           hcx: &mut StableHashingContext<'a>,
46                                           hasher: &mut StableHasher<W>) {
47         hcx.def_path_hash(self.to_def_id()).hash_stable(hcx, hasher);
48     }
49 }
50
51 impl<'a> ToStableHashKey<StableHashingContext<'a>> for LocalDefId {
52     type KeyType = DefPathHash;
53
54     #[inline]
55     fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
56         hcx.def_path_hash(self.to_def_id())
57     }
58 }
59
60 impl<'a> HashStable<StableHashingContext<'a>> for CrateNum {
61     #[inline]
62     fn hash_stable<W: StableHasherResult>(&self,
63                                           hcx: &mut StableHashingContext<'a>,
64                                           hasher: &mut StableHasher<W>) {
65         hcx.def_path_hash(DefId {
66             krate: *self,
67             index: CRATE_DEF_INDEX
68         }).hash_stable(hcx, hasher);
69     }
70 }
71
72 impl<'a> ToStableHashKey<StableHashingContext<'a>> for CrateNum {
73     type KeyType = DefPathHash;
74
75     #[inline]
76     fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
77         let def_id = DefId { krate: *self, index: CRATE_DEF_INDEX };
78         def_id.to_stable_hash_key(hcx)
79     }
80 }
81
82 impl_stable_hash_for!(tuple_struct hir::ItemLocalId { index });
83
84 impl<'a> ToStableHashKey<StableHashingContext<'a>>
85 for hir::ItemLocalId {
86     type KeyType = hir::ItemLocalId;
87
88     #[inline]
89     fn to_stable_hash_key(&self,
90                           _: &StableHashingContext<'a>)
91                           -> hir::ItemLocalId {
92         *self
93     }
94 }
95
96 // The following implementations of HashStable for ItemId, TraitItemId, and
97 // ImplItemId deserve special attention. Normally we do not hash NodeIds within
98 // the HIR, since they just signify a HIR nodes own path. But ItemId et al
99 // are used when another item in the HIR is *referenced* and we certainly
100 // want to pick up on a reference changing its target, so we hash the NodeIds
101 // in "DefPath Mode".
102
103 impl<'a> HashStable<StableHashingContext<'a>> for hir::ItemId {
104     fn hash_stable<W: StableHasherResult>(&self,
105                                           hcx: &mut StableHashingContext<'a>,
106                                           hasher: &mut StableHasher<W>) {
107         let hir::ItemId {
108             id
109         } = *self;
110
111         hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
112             id.hash_stable(hcx, hasher);
113         })
114     }
115 }
116
117 impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitItemId {
118     fn hash_stable<W: StableHasherResult>(&self,
119                                           hcx: &mut StableHashingContext<'a>,
120                                           hasher: &mut StableHasher<W>) {
121         let hir::TraitItemId {
122             node_id
123         } = * self;
124
125         hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
126             node_id.hash_stable(hcx, hasher);
127         })
128     }
129 }
130
131 impl<'a> HashStable<StableHashingContext<'a>> for hir::ImplItemId {
132     fn hash_stable<W: StableHasherResult>(&self,
133                                           hcx: &mut StableHashingContext<'a>,
134                                           hasher: &mut StableHasher<W>) {
135         let hir::ImplItemId {
136             node_id
137         } = * self;
138
139         hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
140             node_id.hash_stable(hcx, hasher);
141         })
142     }
143 }
144
145 impl_stable_hash_for!(enum hir::LifetimeName {
146     Implicit,
147     Underscore,
148     Fresh(index),
149     Static,
150     Name(name)
151 });
152
153 impl_stable_hash_for!(struct hir::Label {
154     span,
155     name
156 });
157
158 impl_stable_hash_for!(struct hir::Lifetime {
159     id,
160     span,
161     name
162 });
163
164 impl_stable_hash_for!(struct hir::LifetimeDef {
165     lifetime,
166     bounds,
167     pure_wrt_drop,
168     in_band
169 });
170
171 impl_stable_hash_for!(struct hir::Path {
172     span,
173     def,
174     segments
175 });
176
177 impl_stable_hash_for!(struct hir::PathSegment {
178     name,
179     infer_types,
180     parameters
181 });
182
183 impl_stable_hash_for!(struct hir::PathParameters {
184     lifetimes,
185     types,
186     bindings,
187     parenthesized
188 });
189
190 impl_stable_hash_for!(enum hir::TyParamBound {
191     TraitTyParamBound(poly_trait_ref, trait_bound_modifier),
192     RegionTyParamBound(lifetime)
193 });
194
195 impl_stable_hash_for!(enum hir::TraitBoundModifier {
196     None,
197     Maybe
198 });
199
200 impl_stable_hash_for!(struct hir::TyParam {
201     name,
202     id,
203     bounds,
204     default,
205     span,
206     pure_wrt_drop,
207     synthetic,
208     attrs
209 });
210
211 impl_stable_hash_for!(enum hir::GenericParam {
212     Lifetime(lifetime_def),
213     Type(ty_param)
214 });
215
216 impl_stable_hash_for!(struct hir::Generics {
217     params,
218     where_clause,
219     span
220 });
221
222 impl_stable_hash_for!(enum hir::SyntheticTyParamKind {
223     ImplTrait
224 });
225
226 impl_stable_hash_for!(struct hir::WhereClause {
227     id,
228     predicates
229 });
230
231 impl_stable_hash_for!(enum hir::WherePredicate {
232     BoundPredicate(pred),
233     RegionPredicate(pred),
234     EqPredicate(pred)
235 });
236
237 impl_stable_hash_for!(struct hir::WhereBoundPredicate {
238     span,
239     bound_generic_params,
240     bounded_ty,
241     bounds
242 });
243
244 impl_stable_hash_for!(struct hir::WhereRegionPredicate {
245     span,
246     lifetime,
247     bounds
248 });
249
250 impl_stable_hash_for!(struct hir::WhereEqPredicate {
251     id,
252     span,
253     lhs_ty,
254     rhs_ty
255 });
256
257 impl_stable_hash_for!(struct hir::MutTy {
258     ty,
259     mutbl
260 });
261
262 impl_stable_hash_for!(struct hir::MethodSig {
263     unsafety,
264     constness,
265     abi,
266     decl
267 });
268
269 impl_stable_hash_for!(struct hir::TypeBinding {
270     id,
271     name,
272     ty,
273     span
274 });
275
276 impl<'a> HashStable<StableHashingContext<'a>> for hir::Ty {
277     fn hash_stable<W: StableHasherResult>(&self,
278                                           hcx: &mut StableHashingContext<'a>,
279                                           hasher: &mut StableHasher<W>) {
280         hcx.while_hashing_hir_bodies(true, |hcx| {
281             let hir::Ty {
282                 id: _,
283                 hir_id: _,
284                 ref node,
285                 ref span,
286             } = *self;
287
288             node.hash_stable(hcx, hasher);
289             span.hash_stable(hcx, hasher);
290         })
291     }
292 }
293
294 impl_stable_hash_for!(enum hir::PrimTy {
295     TyInt(int_ty),
296     TyUint(uint_ty),
297     TyFloat(float_ty),
298     TyStr,
299     TyBool,
300     TyChar
301 });
302
303 impl_stable_hash_for!(struct hir::BareFnTy {
304     unsafety,
305     abi,
306     generic_params,
307     decl,
308     arg_names
309 });
310
311 impl_stable_hash_for!(struct hir::ExistTy {
312     generics,
313     bounds
314 });
315
316 impl_stable_hash_for!(enum hir::Ty_ {
317     TySlice(t),
318     TyArray(t, body_id),
319     TyPtr(t),
320     TyRptr(lifetime, t),
321     TyBareFn(t),
322     TyNever,
323     TyTup(ts),
324     TyPath(qpath),
325     TyTraitObject(trait_refs, lifetime),
326     TyImplTraitExistential(existty, lifetimes),
327     TyTypeof(body_id),
328     TyErr,
329     TyInfer
330 });
331
332 impl_stable_hash_for!(struct hir::FnDecl {
333     inputs,
334     output,
335     variadic,
336     has_implicit_self
337 });
338
339 impl_stable_hash_for!(enum hir::FunctionRetTy {
340     DefaultReturn(span),
341     Return(t)
342 });
343
344 impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitRef {
345     fn hash_stable<W: StableHasherResult>(&self,
346                                           hcx: &mut StableHashingContext<'a>,
347                                           hasher: &mut StableHasher<W>) {
348         let hir::TraitRef {
349             ref path,
350             // Don't hash the ref_id. It is tracked via the thing it is used to access
351             ref_id: _,
352         } = *self;
353
354         path.hash_stable(hcx, hasher);
355     }
356 }
357
358
359 impl_stable_hash_for!(struct hir::PolyTraitRef {
360     bound_generic_params,
361     trait_ref,
362     span
363 });
364
365 impl_stable_hash_for!(enum hir::QPath {
366     Resolved(t, path),
367     TypeRelative(t, path_segment)
368 });
369
370 impl_stable_hash_for!(struct hir::MacroDef {
371     name,
372     vis,
373     attrs,
374     id,
375     span,
376     legacy,
377     body
378 });
379
380
381 impl<'a> HashStable<StableHashingContext<'a>> for hir::Block {
382     fn hash_stable<W: StableHasherResult>(&self,
383                                           hcx: &mut StableHashingContext<'a>,
384                                           hasher: &mut StableHasher<W>) {
385         let hir::Block {
386             ref stmts,
387             ref expr,
388             id: _,
389             hir_id: _,
390             rules,
391             span,
392             targeted_by_break,
393             recovered,
394         } = *self;
395
396         stmts.hash_stable(hcx, hasher);
397         expr.hash_stable(hcx, hasher);
398         rules.hash_stable(hcx, hasher);
399         span.hash_stable(hcx, hasher);
400         recovered.hash_stable(hcx, hasher);
401         targeted_by_break.hash_stable(hcx, hasher);
402     }
403 }
404
405 impl<'a> HashStable<StableHashingContext<'a>> for hir::Pat {
406     fn hash_stable<W: StableHasherResult>(&self,
407                                           hcx: &mut StableHashingContext<'a>,
408                                           hasher: &mut StableHasher<W>) {
409         let hir::Pat {
410             id: _,
411             hir_id: _,
412             ref node,
413             ref span
414         } = *self;
415
416
417         node.hash_stable(hcx, hasher);
418         span.hash_stable(hcx, hasher);
419     }
420 }
421
422 impl_stable_hash_for_spanned!(hir::FieldPat);
423
424 impl<'a> HashStable<StableHashingContext<'a>> for hir::FieldPat {
425     fn hash_stable<W: StableHasherResult>(&self,
426                                           hcx: &mut StableHashingContext<'a>,
427                                           hasher: &mut StableHasher<W>) {
428         let hir::FieldPat {
429             id: _,
430             name,
431             ref pat,
432             is_shorthand,
433         } = *self;
434
435         name.hash_stable(hcx, hasher);
436         pat.hash_stable(hcx, hasher);
437         is_shorthand.hash_stable(hcx, hasher);
438     }
439 }
440
441 impl_stable_hash_for!(enum hir::BindingAnnotation {
442     Unannotated,
443     Mutable,
444     Ref,
445     RefMut
446 });
447
448 impl_stable_hash_for!(enum hir::RangeEnd {
449     Included,
450     Excluded
451 });
452
453 impl_stable_hash_for!(enum hir::PatKind {
454     Wild,
455     Binding(binding_mode, var, name, sub),
456     Struct(path, field_pats, dotdot),
457     TupleStruct(path, field_pats, dotdot),
458     Path(path),
459     Tuple(field_pats, dotdot),
460     Box(sub),
461     Ref(sub, mutability),
462     Lit(expr),
463     Range(start, end, end_kind),
464     Slice(one, two, three)
465 });
466
467 impl_stable_hash_for!(enum hir::BinOp_ {
468     BiAdd,
469     BiSub,
470     BiMul,
471     BiDiv,
472     BiRem,
473     BiAnd,
474     BiOr,
475     BiBitXor,
476     BiBitAnd,
477     BiBitOr,
478     BiShl,
479     BiShr,
480     BiEq,
481     BiLt,
482     BiLe,
483     BiNe,
484     BiGe,
485     BiGt
486 });
487
488 impl_stable_hash_for_spanned!(hir::BinOp_);
489
490 impl_stable_hash_for!(enum hir::UnOp {
491     UnDeref,
492     UnNot,
493     UnNeg
494 });
495
496 impl_stable_hash_for_spanned!(hir::Stmt_);
497
498 impl_stable_hash_for!(struct hir::Local {
499     pat,
500     ty,
501     init,
502     id,
503     hir_id,
504     span,
505     attrs,
506     source
507 });
508
509 impl_stable_hash_for_spanned!(hir::Decl_);
510 impl_stable_hash_for!(enum hir::Decl_ {
511     DeclLocal(local),
512     DeclItem(item_id)
513 });
514
515 impl_stable_hash_for!(struct hir::Arm {
516     attrs,
517     pats,
518     guard,
519     body
520 });
521
522 impl<'a> HashStable<StableHashingContext<'a>> for hir::Field {
523     fn hash_stable<W: StableHasherResult>(&self,
524                                           hcx: &mut StableHashingContext<'a>,
525                                           hasher: &mut StableHasher<W>) {
526         let hir::Field {
527             id: _,
528             name,
529             ref expr,
530             span,
531             is_shorthand,
532         } = *self;
533
534         name.hash_stable(hcx, hasher);
535         expr.hash_stable(hcx, hasher);
536         span.hash_stable(hcx, hasher);
537         is_shorthand.hash_stable(hcx, hasher);
538     }
539 }
540
541 impl_stable_hash_for_spanned!(ast::Name);
542
543
544 impl_stable_hash_for!(enum hir::BlockCheckMode {
545     DefaultBlock,
546     UnsafeBlock(src),
547     PushUnsafeBlock(src),
548     PopUnsafeBlock(src)
549 });
550
551 impl_stable_hash_for!(enum hir::UnsafeSource {
552     CompilerGenerated,
553     UserProvided
554 });
555
556 impl<'a> HashStable<StableHashingContext<'a>> for hir::Expr {
557     fn hash_stable<W: StableHasherResult>(&self,
558                                           hcx: &mut StableHashingContext<'a>,
559                                           hasher: &mut StableHasher<W>) {
560         hcx.while_hashing_hir_bodies(true, |hcx| {
561             let hir::Expr {
562                 id: _,
563                 hir_id: _,
564                 ref span,
565                 ref node,
566                 ref attrs
567             } = *self;
568
569             span.hash_stable(hcx, hasher);
570             node.hash_stable(hcx, hasher);
571             attrs.hash_stable(hcx, hasher);
572         })
573     }
574 }
575
576 impl_stable_hash_for!(enum hir::Expr_ {
577     ExprBox(sub),
578     ExprArray(subs),
579     ExprCall(callee, args),
580     ExprMethodCall(segment, span, args),
581     ExprTup(fields),
582     ExprBinary(op, lhs, rhs),
583     ExprUnary(op, operand),
584     ExprLit(value),
585     ExprCast(expr, t),
586     ExprType(expr, t),
587     ExprIf(cond, then, els),
588     ExprWhile(cond, body, label),
589     ExprLoop(body, label, loop_src),
590     ExprMatch(matchee, arms, match_src),
591     ExprClosure(capture_clause, decl, body_id, span, gen),
592     ExprBlock(blk),
593     ExprAssign(lhs, rhs),
594     ExprAssignOp(op, lhs, rhs),
595     ExprField(owner, field_name),
596     ExprIndex(lhs, rhs),
597     ExprPath(path),
598     ExprAddrOf(mutability, sub),
599     ExprBreak(destination, sub),
600     ExprAgain(destination),
601     ExprRet(val),
602     ExprInlineAsm(asm, inputs, outputs),
603     ExprStruct(path, fields, base),
604     ExprRepeat(val, times),
605     ExprYield(val)
606 });
607
608 impl_stable_hash_for!(enum hir::LocalSource {
609     Normal,
610     ForLoopDesugar
611 });
612
613 impl_stable_hash_for!(enum hir::LoopSource {
614     Loop,
615     WhileLet,
616     ForLoop
617 });
618
619 impl<'a> HashStable<StableHashingContext<'a>> for hir::MatchSource {
620     fn hash_stable<W: StableHasherResult>(&self,
621                                           hcx: &mut StableHashingContext<'a>,
622                                           hasher: &mut StableHasher<W>) {
623         use hir::MatchSource;
624
625         mem::discriminant(self).hash_stable(hcx, hasher);
626         match *self {
627             MatchSource::Normal |
628             MatchSource::WhileLetDesugar |
629             MatchSource::ForLoopDesugar |
630             MatchSource::TryDesugar => {
631                 // No fields to hash.
632             }
633             MatchSource::IfLetDesugar { contains_else_clause } => {
634                 contains_else_clause.hash_stable(hcx, hasher);
635             }
636         }
637     }
638 }
639
640 impl_stable_hash_for!(enum hir::GeneratorMovability {
641     Static,
642     Movable
643 });
644
645 impl_stable_hash_for!(enum hir::CaptureClause {
646     CaptureByValue,
647     CaptureByRef
648 });
649
650 impl_stable_hash_for_spanned!(usize);
651
652 impl_stable_hash_for!(struct hir::Destination {
653     label,
654     target_id
655 });
656
657 impl_stable_hash_for_spanned!(ast::Ident);
658
659 impl_stable_hash_for!(enum hir::LoopIdResult {
660     Ok(node_id),
661     Err(loop_id_error)
662 });
663
664 impl_stable_hash_for!(enum hir::LoopIdError {
665     OutsideLoopScope,
666     UnlabeledCfInWhileCondition,
667     UnresolvedLabel
668 });
669
670 impl<'a> HashStable<StableHashingContext<'a>> for ast::Ident {
671     fn hash_stable<W: StableHasherResult>(&self,
672                                           hcx: &mut StableHashingContext<'a>,
673                                           hasher: &mut StableHasher<W>) {
674         let ast::Ident {
675             name,
676             span,
677         } = *self;
678
679         name.hash_stable(hcx, hasher);
680         span.hash_stable(hcx, hasher);
681     }
682 }
683
684 impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitItem {
685     fn hash_stable<W: StableHasherResult>(&self,
686                                           hcx: &mut StableHashingContext<'a>,
687                                           hasher: &mut StableHasher<W>) {
688         let hir::TraitItem {
689             id: _,
690             hir_id: _,
691             name,
692             ref attrs,
693             ref generics,
694             ref node,
695             span
696         } = *self;
697
698         hcx.hash_hir_item_like(|hcx| {
699             name.hash_stable(hcx, hasher);
700             attrs.hash_stable(hcx, hasher);
701             generics.hash_stable(hcx, hasher);
702             node.hash_stable(hcx, hasher);
703             span.hash_stable(hcx, hasher);
704         });
705     }
706 }
707
708 impl_stable_hash_for!(enum hir::TraitMethod {
709     Required(name),
710     Provided(body)
711 });
712
713 impl_stable_hash_for!(enum hir::TraitItemKind {
714     Const(t, body),
715     Method(sig, method),
716     Type(bounds, rhs)
717 });
718
719 impl<'a> HashStable<StableHashingContext<'a>> for hir::ImplItem {
720     fn hash_stable<W: StableHasherResult>(&self,
721                                           hcx: &mut StableHashingContext<'a>,
722                                           hasher: &mut StableHasher<W>) {
723         let hir::ImplItem {
724             id: _,
725             hir_id: _,
726             name,
727             ref vis,
728             defaultness,
729             ref attrs,
730             ref generics,
731             ref node,
732             span
733         } = *self;
734
735         hcx.hash_hir_item_like(|hcx| {
736             name.hash_stable(hcx, hasher);
737             vis.hash_stable(hcx, hasher);
738             defaultness.hash_stable(hcx, hasher);
739             attrs.hash_stable(hcx, hasher);
740             generics.hash_stable(hcx, hasher);
741             node.hash_stable(hcx, hasher);
742             span.hash_stable(hcx, hasher);
743         });
744     }
745 }
746
747 impl_stable_hash_for!(enum hir::ImplItemKind {
748     Const(t, body),
749     Method(sig, body),
750     Type(t)
751 });
752
753 impl<'a> HashStable<StableHashingContext<'a>> for hir::Visibility {
754     fn hash_stable<W: StableHasherResult>(&self,
755                                           hcx: &mut StableHashingContext<'a>,
756                                           hasher: &mut StableHasher<W>) {
757         mem::discriminant(self).hash_stable(hcx, hasher);
758         match *self {
759             hir::Visibility::Public |
760             hir::Visibility::Crate |
761             hir::Visibility::Inherited => {
762                 // No fields to hash.
763             }
764             hir::Visibility::Restricted { ref path, id } => {
765                 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
766                     id.hash_stable(hcx, hasher);
767                 });
768                 path.hash_stable(hcx, hasher);
769             }
770         }
771     }
772 }
773
774 impl<'a> HashStable<StableHashingContext<'a>> for hir::Defaultness {
775     fn hash_stable<W: StableHasherResult>(&self,
776                                           hcx: &mut StableHashingContext<'a>,
777                                           hasher: &mut StableHasher<W>) {
778         mem::discriminant(self).hash_stable(hcx, hasher);
779         match *self {
780             hir::Defaultness::Final => {
781                 // No fields to hash.
782             }
783             hir::Defaultness::Default { has_value } => {
784                 has_value.hash_stable(hcx, hasher);
785             }
786         }
787     }
788 }
789
790 impl_stable_hash_for!(enum hir::ImplPolarity {
791     Positive,
792     Negative
793 });
794
795 impl<'a> HashStable<StableHashingContext<'a>> for hir::Mod {
796     fn hash_stable<W: StableHasherResult>(&self,
797                                           hcx: &mut StableHashingContext<'a>,
798                                           hasher: &mut StableHasher<W>) {
799         let hir::Mod {
800             inner,
801             // We are not hashing the IDs of the items contained in the module.
802             // This is harmless and matches the current behavior but it's not
803             // actually correct. See issue #40876.
804             item_ids: _,
805         } = *self;
806
807         inner.hash_stable(hcx, hasher);
808     }
809 }
810
811 impl_stable_hash_for!(struct hir::ForeignMod {
812     abi,
813     items
814 });
815
816 impl_stable_hash_for!(struct hir::EnumDef {
817     variants
818 });
819
820 impl_stable_hash_for!(struct hir::Variant_ {
821     name,
822     attrs,
823     data,
824     disr_expr
825 });
826
827 impl_stable_hash_for_spanned!(hir::Variant_);
828
829 impl_stable_hash_for!(enum hir::UseKind {
830     Single,
831     Glob,
832     ListStem
833 });
834
835 impl_stable_hash_for!(struct hir::StructField {
836     span,
837     name,
838     vis,
839     id,
840     ty,
841     attrs
842 });
843
844 impl_stable_hash_for!(enum hir::VariantData {
845     Struct(fields, id),
846     Tuple(fields, id),
847     Unit(id)
848 });
849
850 impl<'a> HashStable<StableHashingContext<'a>> for hir::Item {
851     fn hash_stable<W: StableHasherResult>(&self,
852                                           hcx: &mut StableHashingContext<'a>,
853                                           hasher: &mut StableHasher<W>) {
854         let hir::Item {
855             name,
856             ref attrs,
857             id: _,
858             hir_id: _,
859             ref node,
860             ref vis,
861             span
862         } = *self;
863
864         hcx.hash_hir_item_like(|hcx| {
865             name.hash_stable(hcx, hasher);
866             attrs.hash_stable(hcx, hasher);
867             node.hash_stable(hcx, hasher);
868             vis.hash_stable(hcx, hasher);
869             span.hash_stable(hcx, hasher);
870         });
871     }
872 }
873
874 impl_stable_hash_for!(enum hir::Item_ {
875     ItemExternCrate(orig_name),
876     ItemUse(path, use_kind),
877     ItemStatic(ty, mutability, body_id),
878     ItemConst(ty, body_id),
879     ItemFn(fn_decl, unsafety, constness, abi, generics, body_id),
880     ItemMod(module),
881     ItemForeignMod(foreign_mod),
882     ItemGlobalAsm(global_asm),
883     ItemTy(ty, generics),
884     ItemEnum(enum_def, generics),
885     ItemStruct(variant_data, generics),
886     ItemUnion(variant_data, generics),
887     ItemTrait(is_auto, unsafety, generics, bounds, item_refs),
888     ItemTraitAlias(generics, bounds),
889     ItemImpl(unsafety, impl_polarity, impl_defaultness, generics, trait_ref, ty, impl_item_refs)
890 });
891
892 impl_stable_hash_for!(struct hir::TraitItemRef {
893     id,
894     name,
895     kind,
896     span,
897     defaultness
898 });
899
900 impl_stable_hash_for!(struct hir::ImplItemRef {
901     id,
902     name,
903     kind,
904     span,
905     vis,
906     defaultness
907 });
908
909 impl<'a> HashStable<StableHashingContext<'a>>
910 for hir::AssociatedItemKind {
911     fn hash_stable<W: StableHasherResult>(&self,
912                                           hcx: &mut StableHashingContext<'a>,
913                                           hasher: &mut StableHasher<W>) {
914         mem::discriminant(self).hash_stable(hcx, hasher);
915         match *self {
916             hir::AssociatedItemKind::Const |
917             hir::AssociatedItemKind::Type => {
918                 // No fields to hash.
919             }
920             hir::AssociatedItemKind::Method { has_self } => {
921                 has_self.hash_stable(hcx, hasher);
922             }
923         }
924     }
925 }
926
927 impl_stable_hash_for!(struct hir::ForeignItem {
928     name,
929     attrs,
930     node,
931     id,
932     span,
933     vis
934 });
935
936 impl_stable_hash_for!(enum hir::ForeignItem_ {
937     ForeignItemFn(fn_decl, arg_names, generics),
938     ForeignItemStatic(ty, is_mutbl),
939     ForeignItemType
940 });
941
942 impl_stable_hash_for!(enum hir::Stmt_ {
943     StmtDecl(decl, id),
944     StmtExpr(expr, id),
945     StmtSemi(expr, id)
946 });
947
948 impl_stable_hash_for!(struct hir::Arg {
949     pat,
950     id,
951     hir_id
952 });
953
954 impl<'a> HashStable<StableHashingContext<'a>> for hir::Body {
955     fn hash_stable<W: StableHasherResult>(&self,
956                                           hcx: &mut StableHashingContext<'a>,
957                                           hasher: &mut StableHasher<W>) {
958         let hir::Body {
959             ref arguments,
960             ref value,
961             is_generator,
962         } = *self;
963
964         hcx.with_node_id_hashing_mode(NodeIdHashingMode::Ignore, |hcx| {
965             arguments.hash_stable(hcx, hasher);
966             value.hash_stable(hcx, hasher);
967             is_generator.hash_stable(hcx, hasher);
968         });
969     }
970 }
971
972 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::BodyId {
973     type KeyType = (DefPathHash, hir::ItemLocalId);
974
975     #[inline]
976     fn to_stable_hash_key(&self,
977                           hcx: &StableHashingContext<'a>)
978                           -> (DefPathHash, hir::ItemLocalId) {
979         let hir::BodyId { node_id } = *self;
980         node_id.to_stable_hash_key(hcx)
981     }
982 }
983
984 impl_stable_hash_for!(struct hir::InlineAsmOutput {
985     constraint,
986     is_rw,
987     is_indirect
988 });
989
990 impl<'a> HashStable<StableHashingContext<'a>> for hir::GlobalAsm {
991     fn hash_stable<W: StableHasherResult>(&self,
992                                           hcx: &mut StableHashingContext<'a>,
993                                           hasher: &mut StableHasher<W>) {
994         let hir::GlobalAsm {
995             asm,
996             ctxt: _
997         } = *self;
998
999         asm.hash_stable(hcx, hasher);
1000     }
1001 }
1002
1003 impl<'a> HashStable<StableHashingContext<'a>> for hir::InlineAsm {
1004     fn hash_stable<W: StableHasherResult>(&self,
1005                                           hcx: &mut StableHashingContext<'a>,
1006                                           hasher: &mut StableHasher<W>) {
1007         let hir::InlineAsm {
1008             asm,
1009             asm_str_style,
1010             ref outputs,
1011             ref inputs,
1012             ref clobbers,
1013             volatile,
1014             alignstack,
1015             dialect,
1016             ctxt: _, // This is used for error reporting
1017         } = *self;
1018
1019         asm.hash_stable(hcx, hasher);
1020         asm_str_style.hash_stable(hcx, hasher);
1021         outputs.hash_stable(hcx, hasher);
1022         inputs.hash_stable(hcx, hasher);
1023         clobbers.hash_stable(hcx, hasher);
1024         volatile.hash_stable(hcx, hasher);
1025         alignstack.hash_stable(hcx, hasher);
1026         dialect.hash_stable(hcx, hasher);
1027     }
1028 }
1029
1030 impl_stable_hash_for!(enum hir::def::CtorKind {
1031     Fn,
1032     Const,
1033     Fictive
1034 });
1035
1036 impl_stable_hash_for!(enum hir::def::Def {
1037     Mod(def_id),
1038     Struct(def_id),
1039     Union(def_id),
1040     Enum(def_id),
1041     Variant(def_id),
1042     Trait(def_id),
1043     TyAlias(def_id),
1044     TraitAlias(def_id),
1045     AssociatedTy(def_id),
1046     PrimTy(prim_ty),
1047     TyParam(def_id),
1048     SelfTy(trait_def_id, impl_def_id),
1049     TyForeign(def_id),
1050     Fn(def_id),
1051     Const(def_id),
1052     Static(def_id, is_mutbl),
1053     StructCtor(def_id, ctor_kind),
1054     VariantCtor(def_id, ctor_kind),
1055     Method(def_id),
1056     AssociatedConst(def_id),
1057     Local(def_id),
1058     Upvar(def_id, index, expr_id),
1059     Label(node_id),
1060     Macro(def_id, macro_kind),
1061     GlobalAsm(def_id),
1062     Err
1063 });
1064
1065 impl_stable_hash_for!(enum hir::Mutability {
1066     MutMutable,
1067     MutImmutable
1068 });
1069
1070 impl_stable_hash_for!(enum hir::IsAuto {
1071     Yes,
1072     No
1073 });
1074
1075 impl_stable_hash_for!(enum hir::Unsafety {
1076     Unsafe,
1077     Normal
1078 });
1079
1080
1081 impl_stable_hash_for!(enum hir::Constness {
1082     Const,
1083     NotConst
1084 });
1085
1086 impl<'a> HashStable<StableHashingContext<'a>>
1087 for hir::def_id::DefIndex {
1088
1089     fn hash_stable<W: StableHasherResult>(&self,
1090                                           hcx: &mut StableHashingContext<'a>,
1091                                           hasher: &mut StableHasher<W>) {
1092         hcx.local_def_path_hash(*self).hash_stable(hcx, hasher);
1093     }
1094 }
1095
1096 impl<'a> ToStableHashKey<StableHashingContext<'a>>
1097 for hir::def_id::DefIndex {
1098     type KeyType = DefPathHash;
1099
1100     #[inline]
1101     fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
1102          hcx.local_def_path_hash(*self)
1103     }
1104 }
1105
1106 impl_stable_hash_for!(struct hir::def::Export {
1107     ident,
1108     def,
1109     vis,
1110     span,
1111     is_import
1112 });
1113
1114 impl<'a> HashStable<StableHashingContext<'a>>
1115 for ::middle::lang_items::LangItem {
1116     fn hash_stable<W: StableHasherResult>(&self,
1117                                           _: &mut StableHashingContext<'a>,
1118                                           hasher: &mut StableHasher<W>) {
1119         ::std::hash::Hash::hash(self, hasher);
1120     }
1121 }
1122
1123 impl_stable_hash_for!(struct ::middle::lang_items::LanguageItems {
1124     items,
1125     missing
1126 });
1127
1128 impl<'a> HashStable<StableHashingContext<'a>>
1129 for hir::TraitCandidate {
1130     fn hash_stable<W: StableHasherResult>(&self,
1131                                           hcx: &mut StableHashingContext<'a>,
1132                                           hasher: &mut StableHasher<W>) {
1133         hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
1134             let hir::TraitCandidate {
1135                 def_id,
1136                 import_id,
1137             } = *self;
1138
1139             def_id.hash_stable(hcx, hasher);
1140             import_id.hash_stable(hcx, hasher);
1141         });
1142     }
1143 }
1144
1145 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::TraitCandidate {
1146     type KeyType = (DefPathHash, Option<(DefPathHash, hir::ItemLocalId)>);
1147
1148     fn to_stable_hash_key(&self,
1149                           hcx: &StableHashingContext<'a>)
1150                           -> Self::KeyType {
1151         let hir::TraitCandidate {
1152             def_id,
1153             import_id,
1154         } = *self;
1155
1156         let import_id = import_id.map(|node_id| hcx.node_to_hir_id(node_id))
1157                                  .map(|hir_id| (hcx.local_def_path_hash(hir_id.owner),
1158                                                 hir_id.local_id));
1159         (hcx.def_path_hash(def_id), import_id)
1160     }
1161 }
1162
1163 impl<'hir> HashStable<StableHashingContext<'hir>> for hir::TransFnAttrs
1164 {
1165     fn hash_stable<W: StableHasherResult>(&self,
1166                                           hcx: &mut StableHashingContext<'hir>,
1167                                           hasher: &mut StableHasher<W>) {
1168         let hir::TransFnAttrs {
1169             flags,
1170             inline,
1171             export_name,
1172             ref target_features,
1173             linkage,
1174         } = *self;
1175
1176         flags.hash_stable(hcx, hasher);
1177         inline.hash_stable(hcx, hasher);
1178         export_name.hash_stable(hcx, hasher);
1179         target_features.hash_stable(hcx, hasher);
1180         linkage.hash_stable(hcx, hasher);
1181     }
1182 }
1183
1184 impl<'hir> HashStable<StableHashingContext<'hir>> for hir::TransFnAttrFlags
1185 {
1186     fn hash_stable<W: StableHasherResult>(&self,
1187                                           hcx: &mut StableHashingContext<'hir>,
1188                                           hasher: &mut StableHasher<W>) {
1189         self.bits().hash_stable(hcx, hasher);
1190     }
1191 }
1192
1193 impl<'hir> HashStable<StableHashingContext<'hir>> for attr::InlineAttr {
1194     fn hash_stable<W: StableHasherResult>(&self,
1195                                           hcx: &mut StableHashingContext<'hir>,
1196                                           hasher: &mut StableHasher<W>) {
1197         mem::discriminant(self).hash_stable(hcx, hasher);
1198     }
1199 }
1200
1201 impl_stable_hash_for!(struct hir::Freevar {
1202     def,
1203     span
1204 });