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::map::DefPathHash;
16 use hir::def_id::{DefId, LocalDefId, CrateNum, CRATE_DEF_INDEX};
17 use ich::{StableHashingContext, NodeIdHashingMode, Fingerprint};
18 use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey,
19 StableHasher, StableHasherResult};
24 impl<'a> HashStable<StableHashingContext<'a>> for DefId {
26 fn hash_stable<W: StableHasherResult>(&self,
27 hcx: &mut StableHashingContext<'a>,
28 hasher: &mut StableHasher<W>) {
29 hcx.def_path_hash(*self).hash_stable(hcx, hasher);
33 impl<'a> ToStableHashKey<StableHashingContext<'a>> for DefId {
34 type KeyType = DefPathHash;
37 fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
38 hcx.def_path_hash(*self)
42 impl<'a> HashStable<StableHashingContext<'a>> for LocalDefId {
44 fn hash_stable<W: StableHasherResult>(&self,
45 hcx: &mut StableHashingContext<'a>,
46 hasher: &mut StableHasher<W>) {
47 hcx.def_path_hash(self.to_def_id()).hash_stable(hcx, hasher);
51 impl<'a> ToStableHashKey<StableHashingContext<'a>> for LocalDefId {
52 type KeyType = DefPathHash;
55 fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
56 hcx.def_path_hash(self.to_def_id())
60 impl<'a> HashStable<StableHashingContext<'a>> for CrateNum {
62 fn hash_stable<W: StableHasherResult>(&self,
63 hcx: &mut StableHashingContext<'a>,
64 hasher: &mut StableHasher<W>) {
65 hcx.def_path_hash(DefId {
67 index: CRATE_DEF_INDEX
68 }).hash_stable(hcx, hasher);
72 impl<'a> ToStableHashKey<StableHashingContext<'a>> for CrateNum {
73 type KeyType = DefPathHash;
76 fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
77 let def_id = DefId { krate: *self, index: CRATE_DEF_INDEX };
78 def_id.to_stable_hash_key(hcx)
82 impl_stable_hash_for!(tuple_struct hir::ItemLocalId { index });
84 impl<'a> ToStableHashKey<StableHashingContext<'a>>
85 for hir::ItemLocalId {
86 type KeyType = hir::ItemLocalId;
89 fn to_stable_hash_key(&self,
90 _: &StableHashingContext<'a>)
96 // The following implementations of HashStable for ItemId, TraitItemId, and
97 // ImplItemId deserve special attention. Normally we do not hash NodeIds within
98 // the HIR, since they just signify a HIR nodes own path. But ItemId et al
99 // are used when another item in the HIR is *referenced* and we certainly
100 // want to pick up on a reference changing its target, so we hash the NodeIds
101 // in "DefPath Mode".
103 impl<'a> HashStable<StableHashingContext<'a>> for hir::ItemId {
104 fn hash_stable<W: StableHasherResult>(&self,
105 hcx: &mut StableHashingContext<'a>,
106 hasher: &mut StableHasher<W>) {
111 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
112 id.hash_stable(hcx, hasher);
117 impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitItemId {
118 fn hash_stable<W: StableHasherResult>(&self,
119 hcx: &mut StableHashingContext<'a>,
120 hasher: &mut StableHasher<W>) {
121 let hir::TraitItemId {
125 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
126 node_id.hash_stable(hcx, hasher);
131 impl<'a> HashStable<StableHashingContext<'a>> for hir::ImplItemId {
132 fn hash_stable<W: StableHasherResult>(&self,
133 hcx: &mut StableHashingContext<'a>,
134 hasher: &mut StableHasher<W>) {
135 let hir::ImplItemId {
139 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
140 node_id.hash_stable(hcx, hasher);
145 impl_stable_hash_for!(enum hir::ParamName {
150 impl_stable_hash_for!(enum hir::LifetimeName {
157 impl_stable_hash_for!(struct hir::Label {
161 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),
179 impl_stable_hash_for!(enum hir::GenericArg {
184 impl_stable_hash_for!(struct hir::GenericArgs {
190 impl_stable_hash_for!(enum hir::GenericBound {
191 Trait(poly_trait_ref, trait_bound_modifier),
195 impl_stable_hash_for!(enum hir::TraitBoundModifier {
200 impl_stable_hash_for!(struct hir::GenericParam {
210 impl_stable_hash_for!(enum hir::LifetimeParamKind {
216 impl<'a> HashStable<StableHashingContext<'a>> for hir::GenericParamKind {
217 fn hash_stable<W: StableHasherResult>(&self,
218 hcx: &mut StableHashingContext<'a>,
219 hasher: &mut StableHasher<W>) {
220 mem::discriminant(self).hash_stable(hcx, hasher);
222 hir::GenericParamKind::Lifetime { kind } => {
223 kind.hash_stable(hcx, hasher);
225 hir::GenericParamKind::Type { ref default, synthetic } => {
226 default.hash_stable(hcx, hasher);
227 synthetic.hash_stable(hcx, hasher);
233 impl_stable_hash_for!(struct hir::Generics {
239 impl_stable_hash_for!(enum hir::SyntheticTyParamKind {
243 impl_stable_hash_for!(struct hir::WhereClause {
248 impl_stable_hash_for!(enum hir::WherePredicate {
249 BoundPredicate(pred),
250 RegionPredicate(pred),
254 impl_stable_hash_for!(struct hir::WhereBoundPredicate {
256 bound_generic_params,
261 impl_stable_hash_for!(struct hir::WhereRegionPredicate {
267 impl_stable_hash_for!(struct hir::WhereEqPredicate {
274 impl_stable_hash_for!(struct hir::MutTy {
279 impl_stable_hash_for!(struct hir::MethodSig {
284 impl_stable_hash_for!(struct hir::TypeBinding {
286 ident -> (ident.name),
291 impl_stable_hash_for!(struct hir::FnHeader {
298 impl<'a> HashStable<StableHashingContext<'a>> for hir::Ty {
299 fn hash_stable<W: StableHasherResult>(&self,
300 hcx: &mut StableHashingContext<'a>,
301 hasher: &mut StableHasher<W>) {
302 hcx.while_hashing_hir_bodies(true, |hcx| {
310 node.hash_stable(hcx, hasher);
311 span.hash_stable(hcx, hasher);
316 impl_stable_hash_for!(enum hir::PrimTy {
325 impl_stable_hash_for!(struct hir::BareFnTy {
333 impl_stable_hash_for!(struct hir::ExistTy {
339 impl_stable_hash_for!(enum hir::TyKind {
349 TraitObject(trait_refs, lifetime),
355 impl_stable_hash_for!(struct hir::FnDecl {
362 impl_stable_hash_for!(enum hir::FunctionRetTy {
367 impl_stable_hash_for!(enum hir::ImplicitSelfKind {
375 impl_stable_hash_for!(struct hir::TraitRef {
376 // Don't hash the ref_id. It is tracked via the thing it is used to access
382 impl_stable_hash_for!(struct hir::PolyTraitRef {
383 bound_generic_params,
388 impl_stable_hash_for!(enum hir::QPath {
390 TypeRelative(t, path_segment)
393 impl_stable_hash_for!(struct hir::MacroDef {
403 impl_stable_hash_for!(struct hir::Block {
414 impl_stable_hash_for!(struct hir::Pat {
421 impl_stable_hash_for_spanned!(hir::FieldPat);
423 impl_stable_hash_for!(struct hir::FieldPat {
425 ident -> (ident.name),
430 impl_stable_hash_for!(enum hir::BindingAnnotation {
437 impl_stable_hash_for!(enum hir::RangeEnd {
442 impl_stable_hash_for!(enum hir::PatKind {
444 Binding(binding_mode, var, name, sub),
445 Struct(path, field_pats, dotdot),
446 TupleStruct(path, field_pats, dotdot),
448 Tuple(field_pats, dotdot),
450 Ref(sub, mutability),
452 Range(start, end, end_kind),
453 Slice(one, two, three)
456 impl_stable_hash_for!(enum hir::BinOpKind {
477 impl_stable_hash_for_spanned!(hir::BinOpKind);
479 impl_stable_hash_for!(enum hir::UnOp {
485 impl_stable_hash_for_spanned!(hir::StmtKind);
487 impl_stable_hash_for!(struct hir::Local {
498 impl_stable_hash_for_spanned!(hir::DeclKind);
499 impl_stable_hash_for!(enum hir::DeclKind {
504 impl_stable_hash_for!(struct hir::Arm {
511 impl_stable_hash_for!(enum hir::Guard {
515 impl_stable_hash_for!(struct hir::Field {
523 impl_stable_hash_for_spanned!(ast::Name);
526 impl_stable_hash_for!(enum hir::BlockCheckMode {
529 PushUnsafeBlock(src),
533 impl_stable_hash_for!(enum hir::UnsafeSource {
538 impl_stable_hash_for!(struct hir::AnonConst {
544 impl<'a> HashStable<StableHashingContext<'a>> for hir::Expr {
545 fn hash_stable<W: StableHasherResult>(&self,
546 hcx: &mut StableHashingContext<'a>,
547 hasher: &mut StableHasher<W>) {
548 hcx.while_hashing_hir_bodies(true, |hcx| {
557 span.hash_stable(hcx, hasher);
558 node.hash_stable(hcx, hasher);
559 attrs.hash_stable(hcx, hasher);
564 impl_stable_hash_for!(enum hir::ExprKind {
568 MethodCall(segment, span, args),
570 Binary(op, lhs, rhs),
576 While(cond, body, label),
577 Loop(body, label, loop_src),
578 Match(matchee, arms, match_src),
579 Closure(capture_clause, decl, body_id, span, gen),
582 AssignOp(op, lhs, rhs),
586 AddrOf(mutability, sub),
587 Break(destination, sub),
588 Continue(destination),
590 InlineAsm(asm, inputs, outputs),
591 Struct(path, fields, base),
596 impl_stable_hash_for!(enum hir::LocalSource {
601 impl_stable_hash_for!(enum hir::LoopSource {
607 impl<'a> HashStable<StableHashingContext<'a>> for hir::MatchSource {
608 fn hash_stable<W: StableHasherResult>(&self,
609 hcx: &mut StableHashingContext<'a>,
610 hasher: &mut StableHasher<W>) {
611 use hir::MatchSource;
613 mem::discriminant(self).hash_stable(hcx, hasher);
615 MatchSource::Normal |
616 MatchSource::WhileLetDesugar |
617 MatchSource::ForLoopDesugar |
618 MatchSource::TryDesugar => {
619 // No fields to hash.
621 MatchSource::IfLetDesugar { contains_else_clause } => {
622 contains_else_clause.hash_stable(hcx, hasher);
628 impl_stable_hash_for!(enum hir::GeneratorMovability {
633 impl_stable_hash_for!(enum hir::CaptureClause {
638 impl_stable_hash_for_spanned!(usize);
640 impl_stable_hash_for!(struct hir::Destination {
645 impl_stable_hash_for_spanned!(ast::Ident);
647 impl_stable_hash_for!(enum hir::LoopIdError {
649 UnlabeledCfInWhileCondition,
653 impl_stable_hash_for!(struct ast::Ident {
658 impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitItem {
659 fn hash_stable<W: StableHasherResult>(&self,
660 hcx: &mut StableHashingContext<'a>,
661 hasher: &mut StableHasher<W>) {
672 hcx.hash_hir_item_like(|hcx| {
673 ident.name.hash_stable(hcx, hasher);
674 attrs.hash_stable(hcx, hasher);
675 generics.hash_stable(hcx, hasher);
676 node.hash_stable(hcx, hasher);
677 span.hash_stable(hcx, hasher);
682 impl_stable_hash_for!(enum hir::TraitMethod {
687 impl_stable_hash_for!(enum hir::TraitItemKind {
693 impl<'a> HashStable<StableHashingContext<'a>> for hir::ImplItem {
694 fn hash_stable<W: StableHasherResult>(&self,
695 hcx: &mut StableHashingContext<'a>,
696 hasher: &mut StableHasher<W>) {
709 hcx.hash_hir_item_like(|hcx| {
710 ident.name.hash_stable(hcx, hasher);
711 vis.hash_stable(hcx, hasher);
712 defaultness.hash_stable(hcx, hasher);
713 attrs.hash_stable(hcx, hasher);
714 generics.hash_stable(hcx, hasher);
715 node.hash_stable(hcx, hasher);
716 span.hash_stable(hcx, hasher);
721 impl_stable_hash_for!(enum hir::ImplItemKind {
728 impl_stable_hash_for!(enum ::syntax::ast::CrateSugar {
733 impl<'a> HashStable<StableHashingContext<'a>> for hir::VisibilityKind {
734 fn hash_stable<W: StableHasherResult>(&self,
735 hcx: &mut StableHashingContext<'a>,
736 hasher: &mut StableHasher<W>) {
737 mem::discriminant(self).hash_stable(hcx, hasher);
739 hir::VisibilityKind::Public |
740 hir::VisibilityKind::Inherited => {
741 // No fields to hash.
743 hir::VisibilityKind::Crate(sugar) => {
744 sugar.hash_stable(hcx, hasher);
746 hir::VisibilityKind::Restricted { ref path, id, hir_id } => {
747 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
748 id.hash_stable(hcx, hasher);
749 hir_id.hash_stable(hcx, hasher);
751 path.hash_stable(hcx, hasher);
757 impl_stable_hash_for_spanned!(hir::VisibilityKind);
759 impl<'a> HashStable<StableHashingContext<'a>> for hir::Defaultness {
760 fn hash_stable<W: StableHasherResult>(&self,
761 hcx: &mut StableHashingContext<'a>,
762 hasher: &mut StableHasher<W>) {
763 mem::discriminant(self).hash_stable(hcx, hasher);
765 hir::Defaultness::Final => {
766 // No fields to hash.
768 hir::Defaultness::Default { has_value } => {
769 has_value.hash_stable(hcx, hasher);
775 impl_stable_hash_for!(enum hir::ImplPolarity {
780 impl<'a> HashStable<StableHashingContext<'a>> for hir::Mod {
781 fn hash_stable<W: StableHasherResult>(&self,
782 hcx: &mut StableHashingContext<'a>,
783 hasher: &mut StableHasher<W>) {
785 inner: ref inner_span,
789 inner_span.hash_stable(hcx, hasher);
791 // Combining the DefPathHashes directly is faster than feeding them
792 // into the hasher. Because we use a commutative combine, we also don't
793 // have to sort the array.
794 let item_ids_hash = item_ids
797 let (def_path_hash, local_id) = id.id.to_stable_hash_key(hcx);
798 debug_assert_eq!(local_id, hir::ItemLocalId(0));
800 }).fold(Fingerprint::ZERO, |a, b| {
801 a.combine_commutative(b)
804 item_ids.len().hash_stable(hcx, hasher);
805 item_ids_hash.hash_stable(hcx, hasher);
809 impl_stable_hash_for!(struct hir::ForeignMod {
814 impl_stable_hash_for!(struct hir::EnumDef {
818 impl_stable_hash_for!(struct hir::VariantKind {
825 impl_stable_hash_for_spanned!(hir::VariantKind);
827 impl_stable_hash_for!(enum hir::UseKind {
833 impl_stable_hash_for!(struct hir::StructField {
835 ident -> (ident.name),
842 impl_stable_hash_for!(enum hir::VariantData {
848 impl<'a> HashStable<StableHashingContext<'a>> for hir::Item {
849 fn hash_stable<W: StableHasherResult>(&self,
850 hcx: &mut StableHashingContext<'a>,
851 hasher: &mut StableHasher<W>) {
862 hcx.hash_hir_item_like(|hcx| {
863 name.hash_stable(hcx, hasher);
864 attrs.hash_stable(hcx, hasher);
865 node.hash_stable(hcx, hasher);
866 vis.hash_stable(hcx, hasher);
867 span.hash_stable(hcx, hasher);
872 impl_stable_hash_for!(enum hir::ItemKind {
873 ExternCrate(orig_name),
875 Static(ty, mutability, body_id),
877 Fn(fn_decl, header, generics, body_id),
879 ForeignMod(foreign_mod),
880 GlobalAsm(global_asm),
883 Enum(enum_def, generics),
884 Struct(variant_data, generics),
885 Union(variant_data, generics),
886 Trait(is_auto, unsafety, generics, bounds, item_refs),
887 TraitAlias(generics, bounds),
888 Impl(unsafety, impl_polarity, impl_defaultness, generics, trait_ref, ty, impl_item_refs)
891 impl_stable_hash_for!(struct hir::TraitItemRef {
893 ident -> (ident.name),
899 impl_stable_hash_for!(struct hir::ImplItemRef {
901 ident -> (ident.name),
908 impl<'a> HashStable<StableHashingContext<'a>> for hir::AssociatedItemKind {
909 fn hash_stable<W: StableHasherResult>(&self,
910 hcx: &mut StableHashingContext<'a>,
911 hasher: &mut StableHasher<W>) {
912 mem::discriminant(self).hash_stable(hcx, hasher);
914 hir::AssociatedItemKind::Const |
915 hir::AssociatedItemKind::Existential |
916 hir::AssociatedItemKind::Type => {
917 // No fields to hash.
919 hir::AssociatedItemKind::Method { has_self } => {
920 has_self.hash_stable(hcx, hasher);
926 impl_stable_hash_for!(struct hir::ForeignItem {
935 impl_stable_hash_for!(enum hir::ForeignItemKind {
936 Fn(fn_decl, arg_names, generics),
937 Static(ty, is_mutbl),
941 impl_stable_hash_for!(enum hir::StmtKind {
947 impl_stable_hash_for!(struct hir::Arg {
953 impl<'a> HashStable<StableHashingContext<'a>> for hir::Body {
954 fn hash_stable<W: StableHasherResult>(&self,
955 hcx: &mut StableHashingContext<'a>,
956 hasher: &mut StableHasher<W>) {
963 hcx.with_node_id_hashing_mode(NodeIdHashingMode::Ignore, |hcx| {
964 arguments.hash_stable(hcx, hasher);
965 value.hash_stable(hcx, hasher);
966 is_generator.hash_stable(hcx, hasher);
971 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::BodyId {
972 type KeyType = (DefPathHash, hir::ItemLocalId);
975 fn to_stable_hash_key(&self,
976 hcx: &StableHashingContext<'a>)
977 -> (DefPathHash, hir::ItemLocalId) {
978 let hir::BodyId { node_id } = *self;
979 node_id.to_stable_hash_key(hcx)
983 impl_stable_hash_for!(struct hir::InlineAsmOutput {
989 impl_stable_hash_for!(struct hir::GlobalAsm {
991 ctxt -> _, // This is used for error reporting
994 impl_stable_hash_for!(struct hir::InlineAsm {
1003 ctxt -> _, // This is used for error reporting
1006 impl_stable_hash_for!(enum hir::def::CtorKind {
1012 impl_stable_hash_for!(enum hir::def::NonMacroAttrKind {
1020 impl_stable_hash_for!(enum hir::def::Def {
1025 Existential(def_id),
1030 AssociatedTy(def_id),
1031 AssociatedExistential(def_id),
1034 SelfTy(trait_def_id, impl_def_id),
1038 Static(def_id, is_mutbl),
1039 StructCtor(def_id, ctor_kind),
1040 SelfCtor(impl_def_id),
1041 VariantCtor(def_id, ctor_kind),
1043 AssociatedConst(def_id),
1045 Upvar(def_id, index, expr_id),
1047 Macro(def_id, macro_kind),
1049 NonMacroAttr(attr_kind),
1053 impl_stable_hash_for!(enum hir::Mutability {
1058 impl_stable_hash_for!(enum hir::IsAuto {
1063 impl_stable_hash_for!(enum hir::Unsafety {
1068 impl_stable_hash_for!(enum hir::IsAsync {
1073 impl_stable_hash_for!(enum hir::Constness {
1078 impl<'a> HashStable<StableHashingContext<'a>> for hir::def_id::DefIndex {
1080 fn hash_stable<W: StableHasherResult>(&self,
1081 hcx: &mut StableHashingContext<'a>,
1082 hasher: &mut StableHasher<W>) {
1083 hcx.local_def_path_hash(*self).hash_stable(hcx, hasher);
1087 impl<'a> ToStableHashKey<StableHashingContext<'a>>
1088 for hir::def_id::DefIndex {
1089 type KeyType = DefPathHash;
1092 fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
1093 hcx.local_def_path_hash(*self)
1097 impl_stable_hash_for!(struct hir::def::Export {
1104 impl_stable_hash_for!(struct ::middle::lib_features::LibFeatures {
1109 impl<'a> HashStable<StableHashingContext<'a>> for ::middle::lang_items::LangItem {
1110 fn hash_stable<W: StableHasherResult>(&self,
1111 _: &mut StableHashingContext<'a>,
1112 hasher: &mut StableHasher<W>) {
1113 ::std::hash::Hash::hash(self, hasher);
1117 impl_stable_hash_for!(struct ::middle::lang_items::LanguageItems {
1122 impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitCandidate {
1123 fn hash_stable<W: StableHasherResult>(&self,
1124 hcx: &mut StableHashingContext<'a>,
1125 hasher: &mut StableHasher<W>) {
1126 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
1127 let hir::TraitCandidate {
1132 def_id.hash_stable(hcx, hasher);
1133 import_id.hash_stable(hcx, hasher);
1138 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::TraitCandidate {
1139 type KeyType = (DefPathHash, Option<(DefPathHash, hir::ItemLocalId)>);
1141 fn to_stable_hash_key(&self,
1142 hcx: &StableHashingContext<'a>)
1144 let hir::TraitCandidate {
1149 let import_id = import_id.map(|node_id| hcx.node_to_hir_id(node_id))
1150 .map(|hir_id| (hcx.local_def_path_hash(hir_id.owner),
1152 (hcx.def_path_hash(def_id), import_id)
1156 impl_stable_hash_for!(struct hir::CodegenFnAttrs {
1166 impl<'hir> HashStable<StableHashingContext<'hir>> for hir::CodegenFnAttrFlags
1168 fn hash_stable<W: StableHasherResult>(&self,
1169 hcx: &mut StableHashingContext<'hir>,
1170 hasher: &mut StableHasher<W>) {
1171 self.bits().hash_stable(hcx, hasher);
1175 impl<'hir> HashStable<StableHashingContext<'hir>> for attr::InlineAttr {
1176 fn hash_stable<W: StableHasherResult>(&self,
1177 hcx: &mut StableHashingContext<'hir>,
1178 hasher: &mut StableHasher<W>) {
1179 mem::discriminant(self).hash_stable(hcx, hasher);
1183 impl_stable_hash_for!(struct hir::Freevar {