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