]> git.lizzy.rs Git - rust.git/blob - src/librustc/ich/impls_hir.rs
Auto merge of #41163 - nagisa:ldflags-llvm-config, r=alexcrichton
[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::ItemTy(..)          |
885             hir::ItemEnum(..)        |
886             hir::ItemStruct(..)      |
887             hir::ItemUnion(..)       |
888             hir::ItemTrait(..)       |
889             hir::ItemDefaultImpl(..) |
890             hir::ItemImpl(..)        => {
891                 NodeIdHashingMode::Ignore
892             }
893             hir::ItemUse(..) => {
894                 NodeIdHashingMode::HashTraitsInScope
895             }
896         };
897
898         let hir::Item {
899             name,
900             ref attrs,
901             id,
902             ref node,
903             ref vis,
904             span
905         } = *self;
906
907         hcx.hash_hir_item_like(attrs, |hcx| {
908             hcx.with_node_id_hashing_mode(node_id_hashing_mode, |hcx| {
909                 id.hash_stable(hcx, hasher);
910             });
911             name.hash_stable(hcx, hasher);
912             attrs.hash_stable(hcx, hasher);
913             node.hash_stable(hcx, hasher);
914             vis.hash_stable(hcx, hasher);
915             span.hash_stable(hcx, hasher);
916         });
917     }
918 }
919
920 impl_stable_hash_for!(enum hir::Item_ {
921     ItemExternCrate(name),
922     ItemUse(path, use_kind),
923     ItemStatic(ty, mutability, body_id),
924     ItemConst(ty, body_id),
925     ItemFn(fn_decl, unsafety, constness, abi, generics, body_id),
926     ItemMod(module),
927     ItemForeignMod(foreign_mod),
928     ItemTy(ty, generics),
929     ItemEnum(enum_def, generics),
930     ItemStruct(variant_data, generics),
931     ItemUnion(variant_data, generics),
932     ItemTrait(unsafety, generics, bounds, item_refs),
933     ItemDefaultImpl(unsafety, trait_ref),
934     ItemImpl(unsafety, impl_polarity, generics, trait_ref, ty, impl_item_refs)
935 });
936
937 impl_stable_hash_for!(struct hir::TraitItemRef {
938     id,
939     name,
940     kind,
941     span,
942     defaultness
943 });
944
945 impl_stable_hash_for!(struct hir::ImplItemRef {
946     id,
947     name,
948     kind,
949     span,
950     vis,
951     defaultness
952 });
953
954 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for hir::AssociatedItemKind {
955     fn hash_stable<W: StableHasherResult>(&self,
956                                           hcx: &mut StableHashingContext<'a, 'tcx>,
957                                           hasher: &mut StableHasher<W>) {
958         mem::discriminant(self).hash_stable(hcx, hasher);
959         match *self {
960             hir::AssociatedItemKind::Const |
961             hir::AssociatedItemKind::Type => {
962                 // No fields to hash.
963             }
964             hir::AssociatedItemKind::Method { has_self } => {
965                 has_self.hash_stable(hcx, hasher);
966             }
967         }
968     }
969 }
970
971 impl_stable_hash_for!(struct hir::ForeignItem {
972     name,
973     attrs,
974     node,
975     id,
976     span,
977     vis
978 });
979
980 impl_stable_hash_for!(enum hir::ForeignItem_ {
981     ForeignItemFn(fn_decl, arg_names, generics),
982     ForeignItemStatic(ty, is_mutbl)
983 });
984
985 impl_stable_hash_for!(enum hir::Stmt_ {
986     StmtDecl(decl, id),
987     StmtExpr(expr, id),
988     StmtSemi(expr, id)
989 });
990
991 impl_stable_hash_for!(struct hir::Arg {
992     pat,
993     id
994 });
995
996 impl_stable_hash_for!(struct hir::Body {
997     arguments,
998     value
999 });
1000
1001 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for hir::BodyId {
1002     fn hash_stable<W: StableHasherResult>(&self,
1003                                           hcx: &mut StableHashingContext<'a, 'tcx>,
1004                                           hasher: &mut StableHasher<W>) {
1005         if hcx.hash_bodies() {
1006             hcx.tcx().hir.body(*self).hash_stable(hcx, hasher);
1007         }
1008     }
1009 }
1010
1011 impl_stable_hash_for!(struct hir::InlineAsmOutput {
1012     constraint,
1013     is_rw,
1014     is_indirect
1015 });
1016
1017 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for hir::InlineAsm {
1018     fn hash_stable<W: StableHasherResult>(&self,
1019                                           hcx: &mut StableHashingContext<'a, 'tcx>,
1020                                           hasher: &mut StableHasher<W>) {
1021         let hir::InlineAsm {
1022             asm,
1023             asm_str_style,
1024             ref outputs,
1025             ref inputs,
1026             ref clobbers,
1027             volatile,
1028             alignstack,
1029             dialect,
1030             ctxt: _, // This is used for error reporting
1031         } = *self;
1032
1033         asm.hash_stable(hcx, hasher);
1034         asm_str_style.hash_stable(hcx, hasher);
1035         outputs.hash_stable(hcx, hasher);
1036         inputs.hash_stable(hcx, hasher);
1037         clobbers.hash_stable(hcx, hasher);
1038         volatile.hash_stable(hcx, hasher);
1039         alignstack.hash_stable(hcx, hasher);
1040         dialect.hash_stable(hcx, hasher);
1041     }
1042 }
1043
1044 impl_stable_hash_for!(enum hir::def::CtorKind {
1045     Fn,
1046     Const,
1047     Fictive
1048 });
1049
1050 impl_stable_hash_for!(enum hir::def::Def {
1051     Mod(def_id),
1052     Struct(def_id),
1053     Union(def_id),
1054     Enum(def_id),
1055     Variant(def_id),
1056     Trait(def_id),
1057     TyAlias(def_id),
1058     AssociatedTy(def_id),
1059     PrimTy(prim_ty),
1060     TyParam(def_id),
1061     SelfTy(trait_def_id, impl_def_id),
1062     Fn(def_id),
1063     Const(def_id),
1064     Static(def_id, is_mutbl),
1065     StructCtor(def_id, ctor_kind),
1066     VariantCtor(def_id, ctor_kind),
1067     Method(def_id),
1068     AssociatedConst(def_id),
1069     Local(def_id),
1070     Upvar(def_id, index, expr_id),
1071     Label(node_id),
1072     Macro(def_id, macro_kind),
1073     Err
1074 });
1075
1076 impl_stable_hash_for!(enum hir::Mutability {
1077     MutMutable,
1078     MutImmutable
1079 });
1080
1081
1082 impl_stable_hash_for!(enum hir::Unsafety {
1083     Unsafe,
1084     Normal
1085 });
1086
1087
1088 impl_stable_hash_for!(enum hir::Constness {
1089     Const,
1090     NotConst
1091 });
1092
1093 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for hir::def_id::DefIndex {
1094
1095     fn hash_stable<W: StableHasherResult>(&self,
1096                                           hcx: &mut StableHashingContext<'a, 'tcx>,
1097                                           hasher: &mut StableHasher<W>) {
1098         DefId::local(*self).hash_stable(hcx, hasher);
1099     }
1100 }
1101
1102 impl_stable_hash_for!(struct hir::def::Export {
1103     name,
1104     def,
1105     span
1106 });