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