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