1 //! This module contains `HashStable` implementations for various HIR data
2 //! types in no particular order.
5 use crate::hir::map::DefPathHash;
6 use crate::hir::def_id::{DefId, LocalDefId, CrateNum, CRATE_DEF_INDEX};
7 use crate::ich::{StableHashingContext, NodeIdHashingMode, Fingerprint};
8 use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey,
9 StableHasher, StableHasherResult};
14 impl<'a> HashStable<StableHashingContext<'a>> for DefId {
16 fn hash_stable<W: StableHasherResult>(&self,
17 hcx: &mut StableHashingContext<'a>,
18 hasher: &mut StableHasher<W>) {
19 hcx.def_path_hash(*self).hash_stable(hcx, hasher);
23 impl<'a> ToStableHashKey<StableHashingContext<'a>> for DefId {
24 type KeyType = DefPathHash;
27 fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
28 hcx.def_path_hash(*self)
32 impl<'a> HashStable<StableHashingContext<'a>> for LocalDefId {
34 fn hash_stable<W: StableHasherResult>(&self,
35 hcx: &mut StableHashingContext<'a>,
36 hasher: &mut StableHasher<W>) {
37 hcx.def_path_hash(self.to_def_id()).hash_stable(hcx, hasher);
41 impl<'a> ToStableHashKey<StableHashingContext<'a>> for LocalDefId {
42 type KeyType = DefPathHash;
45 fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
46 hcx.def_path_hash(self.to_def_id())
50 impl<'a> HashStable<StableHashingContext<'a>> for CrateNum {
52 fn hash_stable<W: StableHasherResult>(&self,
53 hcx: &mut StableHashingContext<'a>,
54 hasher: &mut StableHasher<W>) {
55 hcx.def_path_hash(DefId {
57 index: CRATE_DEF_INDEX
58 }).hash_stable(hcx, hasher);
62 impl<'a> ToStableHashKey<StableHashingContext<'a>> for CrateNum {
63 type KeyType = DefPathHash;
66 fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
67 let def_id = DefId { krate: *self, index: CRATE_DEF_INDEX };
68 def_id.to_stable_hash_key(hcx)
72 impl<'a> HashStable<StableHashingContext<'a>> for hir::ItemLocalId {
74 fn hash_stable<W: StableHasherResult>(&self,
75 hcx: &mut StableHashingContext<'a>,
76 hasher: &mut StableHasher<W>) {
77 self.as_u32().hash_stable(hcx, hasher);
81 impl<'a> ToStableHashKey<StableHashingContext<'a>>
82 for hir::ItemLocalId {
83 type KeyType = hir::ItemLocalId;
86 fn to_stable_hash_key(&self,
87 _: &StableHashingContext<'a>)
93 // The following implementations of HashStable for ItemId, TraitItemId, and
94 // ImplItemId deserve special attention. Normally we do not hash NodeIds within
95 // the HIR, since they just signify a HIR nodes own path. But ItemId et al
96 // are used when another item in the HIR is *referenced* and we certainly
97 // want to pick up on a reference changing its target, so we hash the NodeIds
100 impl<'a> HashStable<StableHashingContext<'a>> for hir::ItemId {
101 fn hash_stable<W: StableHasherResult>(&self,
102 hcx: &mut StableHashingContext<'a>,
103 hasher: &mut StableHasher<W>) {
108 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
109 id.hash_stable(hcx, hasher);
114 impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitItemId {
115 fn hash_stable<W: StableHasherResult>(&self,
116 hcx: &mut StableHashingContext<'a>,
117 hasher: &mut StableHasher<W>) {
118 let hir::TraitItemId {
122 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
123 node_id.hash_stable(hcx, hasher);
128 impl<'a> HashStable<StableHashingContext<'a>> for hir::ImplItemId {
129 fn hash_stable<W: StableHasherResult>(&self,
130 hcx: &mut StableHashingContext<'a>,
131 hasher: &mut StableHasher<W>) {
132 let hir::ImplItemId {
136 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
137 node_id.hash_stable(hcx, hasher);
142 impl_stable_hash_for!(enum hir::ParamName {
148 impl_stable_hash_for!(enum hir::LifetimeName {
156 impl_stable_hash_for!(struct ast::Label {
160 impl_stable_hash_for!(struct hir::Lifetime {
167 impl_stable_hash_for!(struct hir::Path {
173 impl_stable_hash_for!(struct hir::PathSegment {
174 ident -> (ident.name),
182 impl_stable_hash_for!(enum hir::GenericArg {
187 impl_stable_hash_for!(struct hir::GenericArgs {
193 impl_stable_hash_for!(enum hir::GenericBound {
194 Trait(poly_trait_ref, trait_bound_modifier),
198 impl_stable_hash_for!(enum hir::TraitBoundModifier {
203 impl_stable_hash_for!(struct hir::GenericParam {
214 impl_stable_hash_for!(enum hir::LifetimeParamKind {
221 impl<'a> HashStable<StableHashingContext<'a>> for hir::GenericParamKind {
222 fn hash_stable<W: StableHasherResult>(&self,
223 hcx: &mut StableHashingContext<'a>,
224 hasher: &mut StableHasher<W>) {
225 mem::discriminant(self).hash_stable(hcx, hasher);
227 hir::GenericParamKind::Lifetime { kind } => {
228 kind.hash_stable(hcx, hasher);
230 hir::GenericParamKind::Type { ref default, synthetic } => {
231 default.hash_stable(hcx, hasher);
232 synthetic.hash_stable(hcx, hasher);
238 impl_stable_hash_for!(struct hir::Generics {
244 impl_stable_hash_for!(enum hir::SyntheticTyParamKind {
248 impl_stable_hash_for!(struct hir::WhereClause {
254 impl_stable_hash_for!(enum hir::WherePredicate {
255 BoundPredicate(pred),
256 RegionPredicate(pred),
260 impl_stable_hash_for!(struct hir::WhereBoundPredicate {
262 bound_generic_params,
267 impl_stable_hash_for!(struct hir::WhereRegionPredicate {
273 impl_stable_hash_for!(struct hir::WhereEqPredicate {
281 impl_stable_hash_for!(struct hir::MutTy {
286 impl_stable_hash_for!(struct hir::MethodSig {
291 impl_stable_hash_for!(struct hir::TypeBinding {
294 ident -> (ident.name),
299 impl_stable_hash_for!(struct hir::FnHeader {
306 impl<'a> HashStable<StableHashingContext<'a>> for hir::Ty {
307 fn hash_stable<W: StableHasherResult>(&self,
308 hcx: &mut StableHashingContext<'a>,
309 hasher: &mut StableHasher<W>) {
310 hcx.while_hashing_hir_bodies(true, |hcx| {
318 node.hash_stable(hcx, hasher);
319 span.hash_stable(hcx, hasher);
324 impl_stable_hash_for!(enum hir::PrimTy {
333 impl_stable_hash_for!(struct hir::BareFnTy {
341 impl_stable_hash_for!(struct hir::ExistTy {
347 impl_stable_hash_for!(enum hir::TyKind {
357 TraitObject(trait_refs, lifetime),
363 impl_stable_hash_for!(struct hir::FnDecl {
370 impl_stable_hash_for!(enum hir::FunctionRetTy {
375 impl_stable_hash_for!(enum hir::ImplicitSelfKind {
383 impl_stable_hash_for!(struct hir::TraitRef {
384 // Don't hash the ref_id. It is tracked via the thing it is used to access
390 impl_stable_hash_for!(struct hir::PolyTraitRef {
391 bound_generic_params,
396 impl_stable_hash_for!(enum hir::QPath {
398 TypeRelative(t, path_segment)
401 impl_stable_hash_for!(struct hir::MacroDef {
412 impl_stable_hash_for!(struct hir::Block {
422 impl_stable_hash_for!(struct hir::Pat {
429 impl_stable_hash_for_spanned!(hir::FieldPat);
431 impl_stable_hash_for!(struct hir::FieldPat {
434 ident -> (ident.name),
439 impl_stable_hash_for!(enum hir::BindingAnnotation {
446 impl_stable_hash_for!(enum hir::RangeEnd {
451 impl_stable_hash_for!(enum hir::PatKind {
453 Binding(binding_mode, var, hir_id, name, sub),
454 Struct(path, field_pats, dotdot),
455 TupleStruct(path, field_pats, dotdot),
457 Tuple(field_pats, dotdot),
459 Ref(sub, mutability),
461 Range(start, end, end_kind),
462 Slice(one, two, three)
465 impl_stable_hash_for!(enum hir::BinOpKind {
486 impl_stable_hash_for_spanned!(hir::BinOpKind);
488 impl_stable_hash_for!(enum hir::UnOp {
494 impl_stable_hash_for!(struct hir::Stmt {
502 impl_stable_hash_for!(struct hir::Local {
513 impl_stable_hash_for!(struct hir::Arm {
520 impl_stable_hash_for!(enum hir::Guard {
524 impl_stable_hash_for!(struct hir::Field {
533 impl_stable_hash_for_spanned!(ast::Name);
536 impl_stable_hash_for!(enum hir::BlockCheckMode {
539 PushUnsafeBlock(src),
543 impl_stable_hash_for!(enum hir::UnsafeSource {
548 impl_stable_hash_for!(struct hir::AnonConst {
554 impl<'a> HashStable<StableHashingContext<'a>> for hir::Expr {
555 fn hash_stable<W: StableHasherResult>(&self,
556 hcx: &mut StableHashingContext<'a>,
557 hasher: &mut StableHasher<W>) {
558 hcx.while_hashing_hir_bodies(true, |hcx| {
567 span.hash_stable(hcx, hasher);
568 node.hash_stable(hcx, hasher);
569 attrs.hash_stable(hcx, hasher);
574 impl_stable_hash_for!(enum hir::ExprKind {
578 MethodCall(segment, span, args),
580 Binary(op, lhs, rhs),
586 While(cond, body, label),
587 Loop(body, label, loop_src),
588 Match(matchee, arms, match_src),
589 Closure(capture_clause, decl, body_id, span, gen),
592 AssignOp(op, lhs, rhs),
596 AddrOf(mutability, sub),
597 Break(destination, sub),
598 Continue(destination),
600 InlineAsm(asm, inputs, outputs),
601 Struct(path, fields, base),
607 impl_stable_hash_for!(enum hir::LocalSource {
612 impl_stable_hash_for!(enum hir::LoopSource {
618 impl<'a> HashStable<StableHashingContext<'a>> for hir::MatchSource {
619 fn hash_stable<W: StableHasherResult>(&self,
620 hcx: &mut StableHashingContext<'a>,
621 hasher: &mut StableHasher<W>) {
622 use crate::hir::MatchSource;
624 mem::discriminant(self).hash_stable(hcx, hasher);
626 MatchSource::Normal |
627 MatchSource::WhileLetDesugar |
628 MatchSource::ForLoopDesugar |
629 MatchSource::TryDesugar => {
630 // No fields to hash.
632 MatchSource::IfLetDesugar { contains_else_clause } => {
633 contains_else_clause.hash_stable(hcx, hasher);
639 impl_stable_hash_for!(enum hir::GeneratorMovability {
644 impl_stable_hash_for!(enum hir::CaptureClause {
649 impl_stable_hash_for_spanned!(usize);
651 impl_stable_hash_for!(struct hir::Destination {
656 impl_stable_hash_for_spanned!(ast::Ident);
658 impl_stable_hash_for!(enum hir::LoopIdError {
660 UnlabeledCfInWhileCondition,
664 impl_stable_hash_for!(struct ast::Ident {
669 impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitItem {
670 fn hash_stable<W: StableHasherResult>(&self,
671 hcx: &mut StableHashingContext<'a>,
672 hasher: &mut StableHasher<W>) {
683 hcx.hash_hir_item_like(|hcx| {
684 ident.name.hash_stable(hcx, hasher);
685 attrs.hash_stable(hcx, hasher);
686 generics.hash_stable(hcx, hasher);
687 node.hash_stable(hcx, hasher);
688 span.hash_stable(hcx, hasher);
693 impl_stable_hash_for!(enum hir::TraitMethod {
698 impl_stable_hash_for!(enum hir::TraitItemKind {
704 impl<'a> HashStable<StableHashingContext<'a>> for hir::ImplItem {
705 fn hash_stable<W: StableHasherResult>(&self,
706 hcx: &mut StableHashingContext<'a>,
707 hasher: &mut StableHasher<W>) {
720 hcx.hash_hir_item_like(|hcx| {
721 ident.name.hash_stable(hcx, hasher);
722 vis.hash_stable(hcx, hasher);
723 defaultness.hash_stable(hcx, hasher);
724 attrs.hash_stable(hcx, hasher);
725 generics.hash_stable(hcx, hasher);
726 node.hash_stable(hcx, hasher);
727 span.hash_stable(hcx, hasher);
732 impl_stable_hash_for!(enum hir::ImplItemKind {
739 impl_stable_hash_for!(enum ::syntax::ast::CrateSugar {
744 impl<'a> HashStable<StableHashingContext<'a>> for hir::VisibilityKind {
745 fn hash_stable<W: StableHasherResult>(&self,
746 hcx: &mut StableHashingContext<'a>,
747 hasher: &mut StableHasher<W>) {
748 mem::discriminant(self).hash_stable(hcx, hasher);
750 hir::VisibilityKind::Public |
751 hir::VisibilityKind::Inherited => {
752 // No fields to hash.
754 hir::VisibilityKind::Crate(sugar) => {
755 sugar.hash_stable(hcx, hasher);
757 hir::VisibilityKind::Restricted { ref path, id, hir_id } => {
758 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
759 id.hash_stable(hcx, hasher);
760 hir_id.hash_stable(hcx, hasher);
762 path.hash_stable(hcx, hasher);
768 impl_stable_hash_for_spanned!(hir::VisibilityKind);
770 impl<'a> HashStable<StableHashingContext<'a>> for hir::Defaultness {
771 fn hash_stable<W: StableHasherResult>(&self,
772 hcx: &mut StableHashingContext<'a>,
773 hasher: &mut StableHasher<W>) {
774 mem::discriminant(self).hash_stable(hcx, hasher);
776 hir::Defaultness::Final => {
777 // No fields to hash.
779 hir::Defaultness::Default { has_value } => {
780 has_value.hash_stable(hcx, hasher);
786 impl_stable_hash_for!(enum hir::ImplPolarity {
791 impl<'a> HashStable<StableHashingContext<'a>> for hir::Mod {
792 fn hash_stable<W: StableHasherResult>(&self,
793 hcx: &mut StableHashingContext<'a>,
794 hasher: &mut StableHasher<W>) {
796 inner: ref inner_span,
800 inner_span.hash_stable(hcx, hasher);
802 // Combining the DefPathHashes directly is faster than feeding them
803 // into the hasher. Because we use a commutative combine, we also don't
804 // have to sort the array.
805 let item_ids_hash = item_ids
808 let (def_path_hash, local_id) = id.id.to_stable_hash_key(hcx);
809 debug_assert_eq!(local_id, hir::ItemLocalId::from_u32(0));
811 }).fold(Fingerprint::ZERO, |a, b| {
812 a.combine_commutative(b)
815 item_ids.len().hash_stable(hcx, hasher);
816 item_ids_hash.hash_stable(hcx, hasher);
820 impl_stable_hash_for!(struct hir::ForeignMod {
825 impl_stable_hash_for!(struct hir::EnumDef {
829 impl_stable_hash_for!(struct hir::VariantKind {
830 ident -> (ident.name),
836 impl_stable_hash_for_spanned!(hir::VariantKind);
838 impl_stable_hash_for!(enum hir::UseKind {
844 impl_stable_hash_for!(struct hir::StructField {
846 ident -> (ident.name),
854 impl_stable_hash_for!(enum hir::VariantData {
855 Struct(fields, id, hir_id),
856 Tuple(fields, id, hir_id),
860 impl<'a> HashStable<StableHashingContext<'a>> for hir::Item {
861 fn hash_stable<W: StableHasherResult>(&self,
862 hcx: &mut StableHashingContext<'a>,
863 hasher: &mut StableHasher<W>) {
874 hcx.hash_hir_item_like(|hcx| {
875 ident.name.hash_stable(hcx, hasher);
876 attrs.hash_stable(hcx, hasher);
877 node.hash_stable(hcx, hasher);
878 vis.hash_stable(hcx, hasher);
879 span.hash_stable(hcx, hasher);
884 impl_stable_hash_for!(enum hir::ItemKind {
885 ExternCrate(orig_name),
887 Static(ty, mutability, body_id),
889 Fn(fn_decl, header, generics, body_id),
891 ForeignMod(foreign_mod),
892 GlobalAsm(global_asm),
895 Enum(enum_def, generics),
896 Struct(variant_data, generics),
897 Union(variant_data, generics),
898 Trait(is_auto, unsafety, generics, bounds, item_refs),
899 TraitAlias(generics, bounds),
900 Impl(unsafety, impl_polarity, impl_defaultness, generics, trait_ref, ty, impl_item_refs)
903 impl_stable_hash_for!(struct hir::TraitItemRef {
905 ident -> (ident.name),
911 impl_stable_hash_for!(struct hir::ImplItemRef {
913 ident -> (ident.name),
920 impl<'a> HashStable<StableHashingContext<'a>> for hir::AssociatedItemKind {
921 fn hash_stable<W: StableHasherResult>(&self,
922 hcx: &mut StableHashingContext<'a>,
923 hasher: &mut StableHasher<W>) {
924 mem::discriminant(self).hash_stable(hcx, hasher);
926 hir::AssociatedItemKind::Const |
927 hir::AssociatedItemKind::Existential |
928 hir::AssociatedItemKind::Type => {
929 // No fields to hash.
931 hir::AssociatedItemKind::Method { has_self } => {
932 has_self.hash_stable(hcx, hasher);
938 impl_stable_hash_for!(struct hir::ForeignItem {
939 ident -> (ident.name),
948 impl_stable_hash_for!(enum hir::ForeignItemKind {
949 Fn(fn_decl, arg_names, generics),
950 Static(ty, is_mutbl),
954 impl_stable_hash_for!(enum hir::StmtKind {
961 impl_stable_hash_for!(struct hir::Arg {
967 impl<'a> HashStable<StableHashingContext<'a>> for hir::Body {
968 fn hash_stable<W: StableHasherResult>(&self,
969 hcx: &mut StableHashingContext<'a>,
970 hasher: &mut StableHasher<W>) {
977 hcx.with_node_id_hashing_mode(NodeIdHashingMode::Ignore, |hcx| {
978 arguments.hash_stable(hcx, hasher);
979 value.hash_stable(hcx, hasher);
980 is_generator.hash_stable(hcx, hasher);
985 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::BodyId {
986 type KeyType = (DefPathHash, hir::ItemLocalId);
989 fn to_stable_hash_key(&self,
990 hcx: &StableHashingContext<'a>)
991 -> (DefPathHash, hir::ItemLocalId) {
992 let hir::BodyId { hir_id } = *self;
993 hir_id.to_stable_hash_key(hcx)
997 impl_stable_hash_for!(struct hir::InlineAsmOutput {
1004 impl_stable_hash_for!(struct hir::GlobalAsm {
1006 ctxt -> _, // This is used for error reporting
1009 impl_stable_hash_for!(struct hir::InlineAsm {
1018 ctxt -> _, // This is used for error reporting
1021 impl_stable_hash_for!(enum hir::def::CtorKind {
1027 impl_stable_hash_for!(enum hir::def::NonMacroAttrKind {
1035 impl_stable_hash_for!(enum hir::def::Def {
1040 Existential(def_id),
1045 AssociatedTy(def_id),
1046 AssociatedExistential(def_id),
1050 SelfTy(trait_def_id, impl_def_id),
1054 Static(def_id, is_mutbl),
1055 StructCtor(def_id, ctor_kind),
1056 SelfCtor(impl_def_id),
1057 VariantCtor(def_id, ctor_kind),
1059 AssociatedConst(def_id),
1061 Upvar(def_id, index, expr_id),
1063 Macro(def_id, macro_kind),
1065 NonMacroAttr(attr_kind),
1069 impl_stable_hash_for!(enum hir::Mutability {
1074 impl_stable_hash_for!(enum hir::IsAuto {
1079 impl_stable_hash_for!(enum hir::Unsafety {
1084 impl_stable_hash_for!(enum hir::IsAsync {
1089 impl_stable_hash_for!(enum hir::Constness {
1094 impl<'a> HashStable<StableHashingContext<'a>> for hir::def_id::DefIndex {
1096 fn hash_stable<W: StableHasherResult>(&self,
1097 hcx: &mut StableHashingContext<'a>,
1098 hasher: &mut StableHasher<W>) {
1099 hcx.local_def_path_hash(*self).hash_stable(hcx, hasher);
1103 impl<'a> ToStableHashKey<StableHashingContext<'a>>
1104 for hir::def_id::DefIndex {
1105 type KeyType = DefPathHash;
1108 fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
1109 hcx.local_def_path_hash(*self)
1113 impl_stable_hash_for!(struct hir::def::Export {
1120 impl_stable_hash_for!(struct crate::middle::lib_features::LibFeatures {
1125 impl<'a> HashStable<StableHashingContext<'a>> for crate::middle::lang_items::LangItem {
1126 fn hash_stable<W: StableHasherResult>(&self,
1127 _: &mut StableHashingContext<'a>,
1128 hasher: &mut StableHasher<W>) {
1129 ::std::hash::Hash::hash(self, hasher);
1133 impl_stable_hash_for!(struct crate::middle::lang_items::LanguageItems {
1138 impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitCandidate {
1139 fn hash_stable<W: StableHasherResult>(&self,
1140 hcx: &mut StableHashingContext<'a>,
1141 hasher: &mut StableHasher<W>) {
1142 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
1143 let hir::TraitCandidate {
1148 def_id.hash_stable(hcx, hasher);
1149 import_id.hash_stable(hcx, hasher);
1154 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::TraitCandidate {
1155 type KeyType = (DefPathHash, Option<(DefPathHash, hir::ItemLocalId)>);
1157 fn to_stable_hash_key(&self,
1158 hcx: &StableHashingContext<'a>)
1160 let hir::TraitCandidate {
1165 let import_id = import_id.map(|node_id| hcx.node_to_hir_id(node_id))
1166 .map(|hir_id| (hcx.local_def_path_hash(hir_id.owner),
1168 (hcx.def_path_hash(def_id), import_id)
1172 impl_stable_hash_for!(struct hir::CodegenFnAttrs {
1183 impl<'hir> HashStable<StableHashingContext<'hir>> for hir::CodegenFnAttrFlags
1185 fn hash_stable<W: StableHasherResult>(&self,
1186 hcx: &mut StableHashingContext<'hir>,
1187 hasher: &mut StableHasher<W>) {
1188 self.bits().hash_stable(hcx, hasher);
1192 impl<'hir> HashStable<StableHashingContext<'hir>> for attr::InlineAttr {
1193 fn hash_stable<W: StableHasherResult>(&self,
1194 hcx: &mut StableHashingContext<'hir>,
1195 hasher: &mut StableHasher<W>) {
1196 mem::discriminant(self).hash_stable(hcx, hasher);
1200 impl<'hir> HashStable<StableHashingContext<'hir>> for attr::OptimizeAttr {
1201 fn hash_stable<W: StableHasherResult>(&self,
1202 hcx: &mut StableHashingContext<'hir>,
1203 hasher: &mut StableHasher<W>) {
1204 mem::discriminant(self).hash_stable(hcx, hasher);
1208 impl_stable_hash_for!(struct hir::Freevar {