]> git.lizzy.rs Git - rust.git/blob - src/librustc/ich/impls_hir.rs
f9758ceea1e8b8ea3aaf92801851e8b5b110c400
[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     attrs,
333     id,
334     span,
335     legacy,
336     body
337 });
338
339
340 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for hir::Block {
341     fn hash_stable<W: StableHasherResult>(&self,
342                                           hcx: &mut StableHashingContext<'a, 'tcx>,
343                                           hasher: &mut StableHasher<W>) {
344         let hir::Block {
345             ref stmts,
346             ref expr,
347             id,
348             rules,
349             span,
350             targeted_by_break,
351         } = *self;
352
353         let non_item_stmts = || stmts.iter().filter(|stmt| {
354             match stmt.node {
355                 hir::StmtDecl(ref decl, _) => {
356                     match decl.node {
357                         // If this is a declaration of a nested item, we don't
358                         // want to leave any trace of it in the hash value, not
359                         // even that it exists. Otherwise changing the position
360                         // of nested items would invalidate the containing item
361                         // even though that does not constitute a semantic
362                         // change.
363                         hir::DeclItem(_) => false,
364                         hir::DeclLocal(_) => true
365                     }
366                 }
367                 hir::StmtExpr(..) |
368                 hir::StmtSemi(..) => true
369             }
370         });
371
372         let count = non_item_stmts().count();
373
374         count.hash_stable(hcx, hasher);
375
376         for stmt in non_item_stmts() {
377             stmt.hash_stable(hcx, hasher);
378         }
379
380         expr.hash_stable(hcx, hasher);
381         id.hash_stable(hcx, hasher);
382         rules.hash_stable(hcx, hasher);
383         span.hash_stable(hcx, hasher);
384         targeted_by_break.hash_stable(hcx, hasher);
385     }
386 }
387
388 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for hir::Pat {
389     fn hash_stable<W: StableHasherResult>(&self,
390                                           hcx: &mut StableHashingContext<'a, 'tcx>,
391                                           hasher: &mut StableHasher<W>) {
392         let node_id_hashing_mode = match self.node {
393             hir::PatKind::Wild        |
394             hir::PatKind::Binding(..) |
395             hir::PatKind::Tuple(..)   |
396             hir::PatKind::Box(..)     |
397             hir::PatKind::Ref(..)     |
398             hir::PatKind::Lit(..)     |
399             hir::PatKind::Range(..)   |
400             hir::PatKind::Slice(..)   => {
401                 NodeIdHashingMode::Ignore
402             }
403             hir::PatKind::Path(..)        |
404             hir::PatKind::Struct(..)      |
405             hir::PatKind::TupleStruct(..) => {
406                 NodeIdHashingMode::HashTraitsInScope
407             }
408         };
409
410         let hir::Pat {
411             id,
412             ref node,
413             ref span
414         } = *self;
415
416         hcx.with_node_id_hashing_mode(node_id_hashing_mode, |hcx| {
417             id.hash_stable(hcx, hasher);
418         });
419         node.hash_stable(hcx, hasher);
420         span.hash_stable(hcx, hasher);
421     }
422 }
423
424 impl_stable_hash_for_spanned!(hir::FieldPat);
425 impl_stable_hash_for!(struct hir::FieldPat {
426     name,
427     pat,
428     is_shorthand
429 });
430
431 impl_stable_hash_for!(enum hir::BindingMode {
432     BindByRef(mutability),
433     BindByValue(mutability)
434 });
435
436 impl_stable_hash_for!(enum hir::RangeEnd {
437     Included,
438     Excluded
439 });
440
441 impl_stable_hash_for!(enum hir::PatKind {
442     Wild,
443     Binding(binding_mode, var, name, sub),
444     Struct(path, field_pats, dotdot),
445     TupleStruct(path, field_pats, dotdot),
446     Path(path),
447     Tuple(field_pats, dotdot),
448     Box(sub),
449     Ref(sub, mutability),
450     Lit(expr),
451     Range(start, end, end_kind),
452     Slice(one, two, three)
453 });
454
455 impl_stable_hash_for!(enum hir::BinOp_ {
456     BiAdd,
457     BiSub,
458     BiMul,
459     BiDiv,
460     BiRem,
461     BiAnd,
462     BiOr,
463     BiBitXor,
464     BiBitAnd,
465     BiBitOr,
466     BiShl,
467     BiShr,
468     BiEq,
469     BiLt,
470     BiLe,
471     BiNe,
472     BiGe,
473     BiGt
474 });
475
476 impl_stable_hash_for_spanned!(hir::BinOp_);
477
478 impl_stable_hash_for!(enum hir::UnOp {
479     UnDeref,
480     UnNot,
481     UnNeg
482 });
483
484 impl_stable_hash_for_spanned!(hir::Stmt_);
485
486 impl_stable_hash_for!(struct hir::Local {
487     pat,
488     ty,
489     init,
490     id,
491     span,
492     attrs
493 });
494
495 impl_stable_hash_for_spanned!(hir::Decl_);
496 impl_stable_hash_for!(enum hir::Decl_ {
497     DeclLocal(local),
498     DeclItem(item_id)
499 });
500
501 impl_stable_hash_for!(struct hir::Arm {
502     attrs,
503     pats,
504     guard,
505     body
506 });
507
508 impl_stable_hash_for!(struct hir::Field {
509     name,
510     expr,
511     span,
512     is_shorthand
513 });
514
515 impl_stable_hash_for_spanned!(ast::Name);
516
517
518 impl_stable_hash_for!(enum hir::BlockCheckMode {
519     DefaultBlock,
520     UnsafeBlock(src),
521     PushUnsafeBlock(src),
522     PopUnsafeBlock(src)
523 });
524
525 impl_stable_hash_for!(enum hir::UnsafeSource {
526     CompilerGenerated,
527     UserProvided
528 });
529
530 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for hir::Expr {
531     fn hash_stable<W: StableHasherResult>(&self,
532                                           hcx: &mut StableHashingContext<'a, 'tcx>,
533                                           hasher: &mut StableHasher<W>) {
534         hcx.while_hashing_hir_bodies(true, |hcx| {
535             let hir::Expr {
536                 id,
537                 ref span,
538                 ref node,
539                 ref attrs
540             } = *self;
541
542             let (spans_always_on, node_id_hashing_mode) = match *node {
543                 hir::ExprBox(..)        |
544                 hir::ExprArray(..)      |
545                 hir::ExprCall(..)       |
546                 hir::ExprLit(..)        |
547                 hir::ExprCast(..)       |
548                 hir::ExprType(..)       |
549                 hir::ExprIf(..)         |
550                 hir::ExprWhile(..)      |
551                 hir::ExprLoop(..)       |
552                 hir::ExprMatch(..)      |
553                 hir::ExprClosure(..)    |
554                 hir::ExprBlock(..)      |
555                 hir::ExprAssign(..)     |
556                 hir::ExprTupField(..)   |
557                 hir::ExprAddrOf(..)     |
558                 hir::ExprBreak(..)      |
559                 hir::ExprAgain(..)      |
560                 hir::ExprRet(..)        |
561                 hir::ExprInlineAsm(..)  |
562                 hir::ExprRepeat(..)     |
563                 hir::ExprTup(..)        => {
564                     // For these we only hash the span when debuginfo is on.
565                     (false, NodeIdHashingMode::Ignore)
566                 }
567                 // For the following, spans might be significant because of
568                 // panic messages indicating the source location.
569                 hir::ExprBinary(op, ..) => {
570                     (hcx.binop_can_panic_at_runtime(op.node), NodeIdHashingMode::Ignore)
571                 }
572                 hir::ExprUnary(op, _) => {
573                     (hcx.unop_can_panic_at_runtime(op), NodeIdHashingMode::Ignore)
574                 }
575                 hir::ExprAssignOp(op, ..) => {
576                     (hcx.binop_can_panic_at_runtime(op.node), NodeIdHashingMode::Ignore)
577                 }
578                 hir::ExprIndex(..) => {
579                     (true, NodeIdHashingMode::Ignore)
580                 }
581                 // For these we don't care about the span, but want to hash the
582                 // trait in scope
583                 hir::ExprMethodCall(..) |
584                 hir::ExprPath(..)       |
585                 hir::ExprStruct(..)     |
586                 hir::ExprField(..)      => {
587                     (false, NodeIdHashingMode::HashTraitsInScope)
588                 }
589             };
590
591             hcx.with_node_id_hashing_mode(node_id_hashing_mode, |hcx| {
592                 id.hash_stable(hcx, hasher);
593             });
594
595             if spans_always_on {
596                 hcx.while_hashing_spans(true, |hcx| {
597                     span.hash_stable(hcx, hasher);
598                     node.hash_stable(hcx, hasher);
599                     attrs.hash_stable(hcx, hasher);
600                 });
601             } else {
602                 span.hash_stable(hcx, hasher);
603                 node.hash_stable(hcx, hasher);
604                 attrs.hash_stable(hcx, hasher);
605             }
606         })
607     }
608 }
609
610 impl_stable_hash_for!(enum hir::Expr_ {
611     ExprBox(sub),
612     ExprArray(subs),
613     ExprCall(callee, args),
614     ExprMethodCall(name, ts, args),
615     ExprTup(fields),
616     ExprBinary(op, lhs, rhs),
617     ExprUnary(op, operand),
618     ExprLit(value),
619     ExprCast(expr, t),
620     ExprType(expr, t),
621     ExprIf(cond, then, els),
622     ExprWhile(cond, body, label),
623     ExprLoop(body, label, loop_src),
624     ExprMatch(matchee, arms, match_src),
625     ExprClosure(capture_clause, decl, body_id, span),
626     ExprBlock(blk),
627     ExprAssign(lhs, rhs),
628     ExprAssignOp(op, lhs, rhs),
629     ExprField(owner, field_name),
630     ExprTupField(owner, idx),
631     ExprIndex(lhs, rhs),
632     ExprPath(path),
633     ExprAddrOf(mutability, sub),
634     ExprBreak(destination, sub),
635     ExprAgain(destination),
636     ExprRet(val),
637     ExprInlineAsm(asm, inputs, outputs),
638     ExprStruct(path, fields, base),
639     ExprRepeat(val, times)
640 });
641
642 impl_stable_hash_for!(enum hir::LoopSource {
643     Loop,
644     WhileLet,
645     ForLoop
646 });
647
648 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for hir::MatchSource {
649     fn hash_stable<W: StableHasherResult>(&self,
650                                           hcx: &mut StableHashingContext<'a, 'tcx>,
651                                           hasher: &mut StableHasher<W>) {
652         use hir::MatchSource;
653
654         mem::discriminant(self).hash_stable(hcx, hasher);
655         match *self {
656             MatchSource::Normal |
657             MatchSource::WhileLetDesugar |
658             MatchSource::ForLoopDesugar |
659             MatchSource::TryDesugar => {
660                 // No fields to hash.
661             }
662             MatchSource::IfLetDesugar { contains_else_clause } => {
663                 contains_else_clause.hash_stable(hcx, hasher);
664             }
665         }
666     }
667 }
668
669 impl_stable_hash_for!(enum hir::CaptureClause {
670     CaptureByValue,
671     CaptureByRef
672 });
673
674 impl_stable_hash_for_spanned!(usize);
675
676 impl_stable_hash_for!(struct hir::Destination {
677     ident,
678     target_id
679 });
680
681 impl_stable_hash_for_spanned!(ast::Ident);
682
683 impl_stable_hash_for!(enum hir::LoopIdResult {
684     Ok(node_id),
685     Err(loop_id_error)
686 });
687
688 impl_stable_hash_for!(enum hir::LoopIdError {
689     OutsideLoopScope,
690     UnlabeledCfInWhileCondition,
691     UnresolvedLabel
692 });
693
694 impl_stable_hash_for!(enum hir::ScopeTarget {
695     Block(node_id),
696     Loop(loop_id_result)
697 });
698
699 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ast::Ident {
700     fn hash_stable<W: StableHasherResult>(&self,
701                                           hcx: &mut StableHashingContext<'a, 'tcx>,
702                                           hasher: &mut StableHasher<W>) {
703         let ast::Ident {
704             ref name,
705             ctxt: _ // Ignore this
706         } = *self;
707
708         name.hash_stable(hcx, hasher);
709     }
710 }
711
712 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for hir::TraitItem {
713     fn hash_stable<W: StableHasherResult>(&self,
714                                           hcx: &mut StableHashingContext<'a, 'tcx>,
715                                           hasher: &mut StableHasher<W>) {
716         let hir::TraitItem {
717             id,
718             name,
719             ref attrs,
720             ref node,
721             span
722         } = *self;
723
724         hcx.hash_hir_item_like(attrs, |hcx| {
725             id.hash_stable(hcx, hasher);
726             name.hash_stable(hcx, hasher);
727             attrs.hash_stable(hcx, hasher);
728             node.hash_stable(hcx, hasher);
729             span.hash_stable(hcx, hasher);
730         });
731     }
732 }
733
734 impl_stable_hash_for!(enum hir::TraitMethod {
735     Required(name),
736     Provided(body)
737 });
738
739 impl_stable_hash_for!(enum hir::TraitItemKind {
740     Const(t, body),
741     Method(sig, method),
742     Type(bounds, rhs)
743 });
744
745 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for hir::ImplItem {
746     fn hash_stable<W: StableHasherResult>(&self,
747                                           hcx: &mut StableHashingContext<'a, 'tcx>,
748                                           hasher: &mut StableHasher<W>) {
749         let hir::ImplItem {
750             id,
751             name,
752             ref vis,
753             defaultness,
754             ref attrs,
755             ref node,
756             span
757         } = *self;
758
759         hcx.hash_hir_item_like(attrs, |hcx| {
760             id.hash_stable(hcx, hasher);
761             name.hash_stable(hcx, hasher);
762             vis.hash_stable(hcx, hasher);
763             defaultness.hash_stable(hcx, hasher);
764             attrs.hash_stable(hcx, hasher);
765             node.hash_stable(hcx, hasher);
766             span.hash_stable(hcx, hasher);
767         });
768     }
769 }
770
771 impl_stable_hash_for!(enum hir::ImplItemKind {
772     Const(t, body),
773     Method(sig, body),
774     Type(t)
775 });
776
777 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for hir::Visibility {
778     fn hash_stable<W: StableHasherResult>(&self,
779                                           hcx: &mut StableHashingContext<'a, 'tcx>,
780                                           hasher: &mut StableHasher<W>) {
781         mem::discriminant(self).hash_stable(hcx, hasher);
782         match *self {
783             hir::Visibility::Public |
784             hir::Visibility::Crate |
785             hir::Visibility::Inherited => {
786                 // No fields to hash.
787             }
788             hir::Visibility::Restricted { ref path, id } => {
789                 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashTraitsInScope, |hcx| {
790                     id.hash_stable(hcx, hasher);
791                 });
792                 path.hash_stable(hcx, hasher);
793             }
794         }
795     }
796 }
797
798 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for hir::Defaultness {
799     fn hash_stable<W: StableHasherResult>(&self,
800                                           hcx: &mut StableHashingContext<'a, 'tcx>,
801                                           hasher: &mut StableHasher<W>) {
802         mem::discriminant(self).hash_stable(hcx, hasher);
803         match *self {
804             hir::Defaultness::Final => {
805                 // No fields to hash.
806             }
807             hir::Defaultness::Default { has_value } => {
808                 has_value.hash_stable(hcx, hasher);
809             }
810         }
811     }
812 }
813
814 impl_stable_hash_for!(enum hir::ImplPolarity {
815     Positive,
816     Negative
817 });
818
819 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for hir::Mod {
820     fn hash_stable<W: StableHasherResult>(&self,
821                                           hcx: &mut StableHashingContext<'a, 'tcx>,
822                                           hasher: &mut StableHasher<W>) {
823         let hir::Mod {
824             inner,
825             // We are not hashing the IDs of the items contained in the module.
826             // This is harmless and matches the current behavior but it's not
827             // actually correct. See issue #40876.
828             item_ids: _,
829         } = *self;
830
831         inner.hash_stable(hcx, hasher);
832     }
833 }
834
835 impl_stable_hash_for!(struct hir::ForeignMod {
836     abi,
837     items
838 });
839
840 impl_stable_hash_for!(struct hir::EnumDef {
841     variants
842 });
843
844 impl_stable_hash_for!(struct hir::Variant_ {
845     name,
846     attrs,
847     data,
848     disr_expr
849 });
850
851 impl_stable_hash_for_spanned!(hir::Variant_);
852
853 impl_stable_hash_for!(enum hir::UseKind {
854     Single,
855     Glob,
856     ListStem
857 });
858
859 impl_stable_hash_for!(struct hir::StructField {
860     span,
861     name,
862     vis,
863     id,
864     ty,
865     attrs
866 });
867
868 impl_stable_hash_for!(enum hir::VariantData {
869     Struct(fields, id),
870     Tuple(fields, id),
871     Unit(id)
872 });
873
874 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for hir::Item {
875     fn hash_stable<W: StableHasherResult>(&self,
876                                           hcx: &mut StableHashingContext<'a, 'tcx>,
877                                           hasher: &mut StableHasher<W>) {
878         let node_id_hashing_mode = match self.node {
879             hir::ItemExternCrate(..) |
880             hir::ItemStatic(..)      |
881             hir::ItemConst(..)       |
882             hir::ItemFn(..)          |
883             hir::ItemMod(..)         |
884             hir::ItemForeignMod(..)  |
885             hir::ItemGlobalAsm(..)   |
886             hir::ItemTy(..)          |
887             hir::ItemEnum(..)        |
888             hir::ItemStruct(..)      |
889             hir::ItemUnion(..)       |
890             hir::ItemTrait(..)       |
891             hir::ItemDefaultImpl(..) |
892             hir::ItemImpl(..)        => {
893                 NodeIdHashingMode::Ignore
894             }
895             hir::ItemUse(..) => {
896                 NodeIdHashingMode::HashTraitsInScope
897             }
898         };
899
900         let hir::Item {
901             name,
902             ref attrs,
903             id,
904             ref node,
905             ref vis,
906             span
907         } = *self;
908
909         hcx.hash_hir_item_like(attrs, |hcx| {
910             hcx.with_node_id_hashing_mode(node_id_hashing_mode, |hcx| {
911                 id.hash_stable(hcx, hasher);
912             });
913             name.hash_stable(hcx, hasher);
914             attrs.hash_stable(hcx, hasher);
915             node.hash_stable(hcx, hasher);
916             vis.hash_stable(hcx, hasher);
917             span.hash_stable(hcx, hasher);
918         });
919     }
920 }
921
922 impl_stable_hash_for!(enum hir::Item_ {
923     ItemExternCrate(name),
924     ItemUse(path, use_kind),
925     ItemStatic(ty, mutability, body_id),
926     ItemConst(ty, body_id),
927     ItemFn(fn_decl, unsafety, constness, abi, generics, body_id),
928     ItemMod(module),
929     ItemForeignMod(foreign_mod),
930     ItemGlobalAsm(global_asm),
931     ItemTy(ty, generics),
932     ItemEnum(enum_def, generics),
933     ItemStruct(variant_data, generics),
934     ItemUnion(variant_data, generics),
935     ItemTrait(unsafety, generics, bounds, item_refs),
936     ItemDefaultImpl(unsafety, trait_ref),
937     ItemImpl(unsafety, impl_polarity, impl_defaultness, generics, trait_ref, ty, impl_item_refs)
938 });
939
940 impl_stable_hash_for!(struct hir::TraitItemRef {
941     id,
942     name,
943     kind,
944     span,
945     defaultness
946 });
947
948 impl_stable_hash_for!(struct hir::ImplItemRef {
949     id,
950     name,
951     kind,
952     span,
953     vis,
954     defaultness
955 });
956
957 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for hir::AssociatedItemKind {
958     fn hash_stable<W: StableHasherResult>(&self,
959                                           hcx: &mut StableHashingContext<'a, 'tcx>,
960                                           hasher: &mut StableHasher<W>) {
961         mem::discriminant(self).hash_stable(hcx, hasher);
962         match *self {
963             hir::AssociatedItemKind::Const |
964             hir::AssociatedItemKind::Type => {
965                 // No fields to hash.
966             }
967             hir::AssociatedItemKind::Method { has_self } => {
968                 has_self.hash_stable(hcx, hasher);
969             }
970         }
971     }
972 }
973
974 impl_stable_hash_for!(struct hir::ForeignItem {
975     name,
976     attrs,
977     node,
978     id,
979     span,
980     vis
981 });
982
983 impl_stable_hash_for!(enum hir::ForeignItem_ {
984     ForeignItemFn(fn_decl, arg_names, generics),
985     ForeignItemStatic(ty, is_mutbl)
986 });
987
988 impl_stable_hash_for!(enum hir::Stmt_ {
989     StmtDecl(decl, id),
990     StmtExpr(expr, id),
991     StmtSemi(expr, id)
992 });
993
994 impl_stable_hash_for!(struct hir::Arg {
995     pat,
996     id
997 });
998
999 impl_stable_hash_for!(struct hir::Body {
1000     arguments,
1001     value
1002 });
1003
1004 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for hir::BodyId {
1005     fn hash_stable<W: StableHasherResult>(&self,
1006                                           hcx: &mut StableHashingContext<'a, 'tcx>,
1007                                           hasher: &mut StableHasher<W>) {
1008         if hcx.hash_bodies() {
1009             hcx.tcx().hir.body(*self).hash_stable(hcx, hasher);
1010         }
1011     }
1012 }
1013
1014 impl_stable_hash_for!(struct hir::InlineAsmOutput {
1015     constraint,
1016     is_rw,
1017     is_indirect
1018 });
1019
1020 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for hir::GlobalAsm {
1021     fn hash_stable<W: StableHasherResult>(&self,
1022                                           hcx: &mut StableHashingContext<'a, 'tcx>,
1023                                           hasher: &mut StableHasher<W>) {
1024         let hir::GlobalAsm {
1025             asm,
1026             ctxt: _
1027         } = *self;
1028
1029         asm.hash_stable(hcx, hasher);
1030     }
1031 }
1032
1033 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for hir::InlineAsm {
1034     fn hash_stable<W: StableHasherResult>(&self,
1035                                           hcx: &mut StableHashingContext<'a, 'tcx>,
1036                                           hasher: &mut StableHasher<W>) {
1037         let hir::InlineAsm {
1038             asm,
1039             asm_str_style,
1040             ref outputs,
1041             ref inputs,
1042             ref clobbers,
1043             volatile,
1044             alignstack,
1045             dialect,
1046             ctxt: _, // This is used for error reporting
1047         } = *self;
1048
1049         asm.hash_stable(hcx, hasher);
1050         asm_str_style.hash_stable(hcx, hasher);
1051         outputs.hash_stable(hcx, hasher);
1052         inputs.hash_stable(hcx, hasher);
1053         clobbers.hash_stable(hcx, hasher);
1054         volatile.hash_stable(hcx, hasher);
1055         alignstack.hash_stable(hcx, hasher);
1056         dialect.hash_stable(hcx, hasher);
1057     }
1058 }
1059
1060 impl_stable_hash_for!(enum hir::def::CtorKind {
1061     Fn,
1062     Const,
1063     Fictive
1064 });
1065
1066 impl_stable_hash_for!(enum hir::def::Def {
1067     Mod(def_id),
1068     Struct(def_id),
1069     Union(def_id),
1070     Enum(def_id),
1071     Variant(def_id),
1072     Trait(def_id),
1073     TyAlias(def_id),
1074     AssociatedTy(def_id),
1075     PrimTy(prim_ty),
1076     TyParam(def_id),
1077     SelfTy(trait_def_id, impl_def_id),
1078     Fn(def_id),
1079     Const(def_id),
1080     Static(def_id, is_mutbl),
1081     StructCtor(def_id, ctor_kind),
1082     VariantCtor(def_id, ctor_kind),
1083     Method(def_id),
1084     AssociatedConst(def_id),
1085     Local(def_id),
1086     Upvar(def_id, index, expr_id),
1087     Label(node_id),
1088     Macro(def_id, macro_kind),
1089     GlobalAsm(def_id),
1090     Err
1091 });
1092
1093 impl_stable_hash_for!(enum hir::Mutability {
1094     MutMutable,
1095     MutImmutable
1096 });
1097
1098
1099 impl_stable_hash_for!(enum hir::Unsafety {
1100     Unsafe,
1101     Normal
1102 });
1103
1104
1105 impl_stable_hash_for!(enum hir::Constness {
1106     Const,
1107     NotConst
1108 });
1109
1110 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for hir::def_id::DefIndex {
1111
1112     fn hash_stable<W: StableHasherResult>(&self,
1113                                           hcx: &mut StableHashingContext<'a, 'tcx>,
1114                                           hasher: &mut StableHasher<W>) {
1115         DefId::local(*self).hash_stable(hcx, hasher);
1116     }
1117 }
1118
1119 impl_stable_hash_for!(struct hir::def::Export {
1120     name,
1121     def,
1122     span
1123 });
1124
1125 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ::middle::lang_items::LangItem {
1126     fn hash_stable<W: StableHasherResult>(&self,
1127                                           _: &mut StableHashingContext<'a, 'tcx>,
1128                                           hasher: &mut StableHasher<W>) {
1129         ::std::hash::Hash::hash(self, hasher);
1130     }
1131 }