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