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.
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.
11 //! This module contains `HashStable` implementations for various HIR data
12 //! types in no particular order.
15 use hir::def_id::DefId;
16 use ich::{StableHashingContext, NodeIdHashingMode};
21 use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
24 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for DefId {
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);
34 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for hir::HirId {
36 fn hash_stable<W: StableHasherResult>(&self,
37 hcx: &mut StableHashingContext<'a, 'tcx>,
38 hasher: &mut StableHasher<W>) {
44 hcx.def_path_hash(DefId::local(owner)).hash_stable(hcx, hasher);
45 local_id.hash_stable(hcx, hasher);
49 impl_stable_hash_for!(tuple_struct hir::ItemLocalId { index });
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
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>) {
66 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
67 id.hash_stable(hcx, hasher);
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 {
80 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
81 node_id.hash_stable(hcx, hasher);
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>) {
94 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
95 node_id.hash_stable(hcx, hasher);
100 impl_stable_hash_for!(struct hir::Lifetime {
106 impl_stable_hash_for!(struct hir::LifetimeDef {
112 impl_stable_hash_for!(struct hir::Path {
118 impl_stable_hash_for!(struct hir::PathSegment {
123 impl_stable_hash_for!(enum hir::PathParameters {
124 AngleBracketedParameters(data),
125 ParenthesizedParameters(data)
128 impl_stable_hash_for!(struct hir::AngleBracketedParameterData {
135 impl_stable_hash_for!(struct hir::ParenthesizedParameterData {
141 impl_stable_hash_for!(enum hir::TyParamBound {
142 TraitTyParamBound(poly_trait_ref, trait_bound_modifier),
143 RegionTyParamBound(lifetime)
146 impl_stable_hash_for!(enum hir::TraitBoundModifier {
151 impl_stable_hash_for!(struct hir::TyParam {
160 impl_stable_hash_for!(struct hir::Generics {
167 impl_stable_hash_for!(struct hir::WhereClause {
172 impl_stable_hash_for!(enum hir::WherePredicate {
173 BoundPredicate(pred),
174 RegionPredicate(pred),
178 impl_stable_hash_for!(struct hir::WhereBoundPredicate {
185 impl_stable_hash_for!(struct hir::WhereRegionPredicate {
191 impl_stable_hash_for!(struct hir::WhereEqPredicate {
198 impl_stable_hash_for!(struct hir::MutTy {
203 impl_stable_hash_for!(struct hir::MethodSig {
211 impl_stable_hash_for!(struct hir::TypeBinding {
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 {
230 hir::TyTraitObject(..) |
231 hir::TyImplTrait(..) |
235 NodeIdHashingMode::Ignore
238 NodeIdHashingMode::HashTraitsInScope
242 hcx.while_hashing_hir_bodies(true, |hcx| {
249 hcx.with_node_id_hashing_mode(node_id_hashing_mode, |hcx| {
250 id.hash_stable(hcx, hasher);
252 node.hash_stable(hcx, hasher);
253 span.hash_stable(hcx, hasher);
258 impl_stable_hash_for!(enum hir::PrimTy {
267 impl_stable_hash_for!(struct hir::BareFnTy {
274 impl_stable_hash_for!(enum hir::Ty_ {
283 TyTraitObject(trait_refs, lifetime),
290 impl_stable_hash_for!(struct hir::FnDecl {
297 impl_stable_hash_for!(enum hir::FunctionRetTy {
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>) {
311 path.hash_stable(hcx, hasher);
312 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashTraitsInScope, |hcx| {
313 ref_id.hash_stable(hcx, hasher);
319 impl_stable_hash_for!(struct hir::PolyTraitRef {
325 impl_stable_hash_for!(enum hir::QPath {
327 TypeRelative(t, path_segment)
330 impl_stable_hash_for!(struct hir::MacroDef {
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>) {
352 let non_item_stmts = || stmts.iter().filter(|stmt| {
354 hir::StmtDecl(ref decl, _) => {
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
362 hir::DeclItem(_) => false,
363 hir::DeclLocal(_) => true
367 hir::StmtSemi(..) => true
371 let count = non_item_stmts().count();
373 count.hash_stable(hcx, hasher);
375 for stmt in non_item_stmts() {
376 stmt.hash_stable(hcx, hasher);
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);
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 {
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
402 hir::PatKind::Path(..) |
403 hir::PatKind::Struct(..) |
404 hir::PatKind::TupleStruct(..) => {
405 NodeIdHashingMode::HashTraitsInScope
415 hcx.with_node_id_hashing_mode(node_id_hashing_mode, |hcx| {
416 id.hash_stable(hcx, hasher);
418 node.hash_stable(hcx, hasher);
419 span.hash_stable(hcx, hasher);
423 impl_stable_hash_for_spanned!(hir::FieldPat);
424 impl_stable_hash_for!(struct hir::FieldPat {
430 impl_stable_hash_for!(enum hir::BindingMode {
431 BindByRef(mutability),
432 BindByValue(mutability)
435 impl_stable_hash_for!(enum hir::RangeEnd {
440 impl_stable_hash_for!(enum hir::PatKind {
442 Binding(binding_mode, var, name, sub),
443 Struct(path, field_pats, dotdot),
444 TupleStruct(path, field_pats, dotdot),
446 Tuple(field_pats, dotdot),
448 Ref(sub, mutability),
450 Range(start, end, end_kind),
451 Slice(one, two, three)
454 impl_stable_hash_for!(enum hir::BinOp_ {
475 impl_stable_hash_for_spanned!(hir::BinOp_);
477 impl_stable_hash_for!(enum hir::UnOp {
483 impl_stable_hash_for_spanned!(hir::Stmt_);
485 impl_stable_hash_for!(struct hir::Local {
494 impl_stable_hash_for_spanned!(hir::Decl_);
495 impl_stable_hash_for!(enum hir::Decl_ {
500 impl_stable_hash_for!(struct hir::Arm {
507 impl_stable_hash_for!(struct hir::Field {
514 impl_stable_hash_for_spanned!(ast::Name);
517 impl_stable_hash_for!(enum hir::BlockCheckMode {
520 PushUnsafeBlock(src),
524 impl_stable_hash_for!(enum hir::UnsafeSource {
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| {
541 let (spans_always_on, node_id_hashing_mode) = match *node {
552 hir::ExprClosure(..) |
554 hir::ExprAssign(..) |
555 hir::ExprTupField(..) |
556 hir::ExprAddrOf(..) |
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)
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)
571 hir::ExprUnary(op, _) => {
572 (hcx.unop_can_panic_at_runtime(op), NodeIdHashingMode::Ignore)
574 hir::ExprAssignOp(op, ..) => {
575 (hcx.binop_can_panic_at_runtime(op.node), NodeIdHashingMode::Ignore)
577 hir::ExprIndex(..) => {
578 (true, NodeIdHashingMode::Ignore)
580 // For these we don't care about the span, but want to hash the
582 hir::ExprMethodCall(..) |
584 hir::ExprStruct(..) |
585 hir::ExprField(..) => {
586 (false, NodeIdHashingMode::HashTraitsInScope)
590 hcx.with_node_id_hashing_mode(node_id_hashing_mode, |hcx| {
591 id.hash_stable(hcx, hasher);
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);
601 span.hash_stable(hcx, hasher);
602 node.hash_stable(hcx, hasher);
603 attrs.hash_stable(hcx, hasher);
609 impl_stable_hash_for!(enum hir::Expr_ {
612 ExprCall(callee, args),
613 ExprMethodCall(name, ts, args),
615 ExprBinary(op, lhs, rhs),
616 ExprUnary(op, operand),
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),
626 ExprAssign(lhs, rhs),
627 ExprAssignOp(op, lhs, rhs),
628 ExprField(owner, field_name),
629 ExprTupField(owner, idx),
632 ExprAddrOf(mutability, sub),
633 ExprBreak(destination, sub),
634 ExprAgain(destination),
636 ExprInlineAsm(asm, inputs, outputs),
637 ExprStruct(path, fields, base),
638 ExprRepeat(val, times)
641 impl_stable_hash_for!(enum hir::LoopSource {
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;
653 mem::discriminant(self).hash_stable(hcx, hasher);
655 MatchSource::Normal |
656 MatchSource::WhileLetDesugar |
657 MatchSource::ForLoopDesugar |
658 MatchSource::TryDesugar => {
659 // No fields to hash.
661 MatchSource::IfLetDesugar { contains_else_clause } => {
662 contains_else_clause.hash_stable(hcx, hasher);
668 impl_stable_hash_for!(enum hir::CaptureClause {
673 impl_stable_hash_for_spanned!(usize);
675 impl_stable_hash_for!(struct hir::Destination {
680 impl_stable_hash_for_spanned!(ast::Ident);
682 impl_stable_hash_for!(enum hir::LoopIdResult {
687 impl_stable_hash_for!(enum hir::LoopIdError {
689 UnlabeledCfInWhileCondition,
693 impl_stable_hash_for!(enum hir::ScopeTarget {
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>) {
704 ctxt: _ // Ignore this
707 name.hash_stable(hcx, hasher);
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>) {
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);
733 impl_stable_hash_for!(enum hir::TraitMethod {
738 impl_stable_hash_for!(enum hir::TraitItemKind {
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>) {
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);
770 impl_stable_hash_for!(enum hir::ImplItemKind {
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);
782 hir::Visibility::Public |
783 hir::Visibility::Crate |
784 hir::Visibility::Inherited => {
785 // No fields to hash.
787 hir::Visibility::Restricted { ref path, id } => {
788 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashTraitsInScope, |hcx| {
789 id.hash_stable(hcx, hasher);
791 path.hash_stable(hcx, hasher);
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);
803 hir::Defaultness::Final => {
804 // No fields to hash.
806 hir::Defaultness::Default { has_value } => {
807 has_value.hash_stable(hcx, hasher);
813 impl_stable_hash_for!(enum hir::ImplPolarity {
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>) {
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.
830 inner.hash_stable(hcx, hasher);
834 impl_stable_hash_for!(struct hir::ForeignMod {
839 impl_stable_hash_for!(struct hir::EnumDef {
843 impl_stable_hash_for!(struct hir::Variant_ {
850 impl_stable_hash_for_spanned!(hir::Variant_);
852 impl_stable_hash_for!(enum hir::UseKind {
858 impl_stable_hash_for!(struct hir::StructField {
867 impl_stable_hash_for!(enum hir::VariantData {
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(..) |
883 hir::ItemForeignMod(..) |
884 hir::ItemGlobalAsm(..) |
887 hir::ItemStruct(..) |
890 hir::ItemDefaultImpl(..) |
891 hir::ItemImpl(..) => {
892 NodeIdHashingMode::Ignore
894 hir::ItemUse(..) => {
895 NodeIdHashingMode::HashTraitsInScope
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);
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);
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),
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, impl_defaultness, generics, trait_ref, ty, impl_item_refs)
939 impl_stable_hash_for!(struct hir::TraitItemRef {
947 impl_stable_hash_for!(struct hir::ImplItemRef {
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);
962 hir::AssociatedItemKind::Const |
963 hir::AssociatedItemKind::Type => {
964 // No fields to hash.
966 hir::AssociatedItemKind::Method { has_self } => {
967 has_self.hash_stable(hcx, hasher);
973 impl_stable_hash_for!(struct hir::ForeignItem {
982 impl_stable_hash_for!(enum hir::ForeignItem_ {
983 ForeignItemFn(fn_decl, arg_names, generics),
984 ForeignItemStatic(ty, is_mutbl)
987 impl_stable_hash_for!(enum hir::Stmt_ {
993 impl_stable_hash_for!(struct hir::Arg {
998 impl_stable_hash_for!(struct hir::Body {
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);
1013 impl_stable_hash_for!(struct hir::InlineAsmOutput {
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 {
1028 asm.hash_stable(hcx, hasher);
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 {
1045 ctxt: _, // This is used for error reporting
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);
1059 impl_stable_hash_for!(enum hir::def::CtorKind {
1065 impl_stable_hash_for!(enum hir::def::Def {
1073 AssociatedTy(def_id),
1076 SelfTy(trait_def_id, impl_def_id),
1079 Static(def_id, is_mutbl),
1080 StructCtor(def_id, ctor_kind),
1081 VariantCtor(def_id, ctor_kind),
1083 AssociatedConst(def_id),
1085 Upvar(def_id, index, expr_id),
1087 Macro(def_id, macro_kind),
1092 impl_stable_hash_for!(enum hir::Mutability {
1098 impl_stable_hash_for!(enum hir::Unsafety {
1104 impl_stable_hash_for!(enum hir::Constness {
1109 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for hir::def_id::DefIndex {
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);
1118 impl_stable_hash_for!(struct hir::def::Export {