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<'a> HashStable<StableHashingContext<'a>> for hir::GenericParamKind {
211 fn hash_stable<W: StableHasherResult>(&self,
212 hcx: &mut StableHashingContext<'a>,
213 hasher: &mut StableHasher<W>) {
214 mem::discriminant(self).hash_stable(hcx, hasher);
216 hir::GenericParamKind::Lifetime { in_band } => {
217 in_band.hash_stable(hcx, hasher);
219 hir::GenericParamKind::Type { ref default, synthetic } => {
220 default.hash_stable(hcx, hasher);
221 synthetic.hash_stable(hcx, hasher);
227 impl_stable_hash_for!(struct hir::Generics {
233 impl_stable_hash_for!(enum hir::SyntheticTyParamKind {
237 impl_stable_hash_for!(struct hir::WhereClause {
242 impl_stable_hash_for!(enum hir::WherePredicate {
243 BoundPredicate(pred),
244 RegionPredicate(pred),
248 impl_stable_hash_for!(struct hir::WhereBoundPredicate {
250 bound_generic_params,
255 impl_stable_hash_for!(struct hir::WhereRegionPredicate {
261 impl_stable_hash_for!(struct hir::WhereEqPredicate {
268 impl_stable_hash_for!(struct hir::MutTy {
273 impl_stable_hash_for!(struct hir::MethodSig {
278 impl_stable_hash_for!(struct hir::TypeBinding {
280 ident -> (ident.name),
285 impl_stable_hash_for!(struct hir::FnHeader {
292 impl<'a> HashStable<StableHashingContext<'a>> for hir::Ty {
293 fn hash_stable<W: StableHasherResult>(&self,
294 hcx: &mut StableHashingContext<'a>,
295 hasher: &mut StableHasher<W>) {
296 hcx.while_hashing_hir_bodies(true, |hcx| {
304 node.hash_stable(hcx, hasher);
305 span.hash_stable(hcx, hasher);
310 impl_stable_hash_for!(enum hir::PrimTy {
319 impl_stable_hash_for!(struct hir::BareFnTy {
327 impl_stable_hash_for!(struct hir::ExistTy {
333 impl_stable_hash_for!(enum hir::TyKind {
342 TraitObject(trait_refs, lifetime),
348 impl_stable_hash_for!(struct hir::FnDecl {
355 impl_stable_hash_for!(enum hir::FunctionRetTy {
360 impl_stable_hash_for!(struct hir::TraitRef {
361 // Don't hash the ref_id. It is tracked via the thing it is used to access
367 impl_stable_hash_for!(struct hir::PolyTraitRef {
368 bound_generic_params,
373 impl_stable_hash_for!(enum hir::QPath {
375 TypeRelative(t, path_segment)
378 impl_stable_hash_for!(struct hir::MacroDef {
388 impl_stable_hash_for!(struct hir::Block {
399 impl_stable_hash_for!(struct hir::Pat {
406 impl_stable_hash_for_spanned!(hir::FieldPat);
408 impl_stable_hash_for!(struct hir::FieldPat {
410 ident -> (ident.name),
415 impl_stable_hash_for!(enum hir::BindingAnnotation {
422 impl_stable_hash_for!(enum hir::RangeEnd {
427 impl_stable_hash_for!(enum hir::PatKind {
429 Binding(binding_mode, var, name, sub),
430 Struct(path, field_pats, dotdot),
431 TupleStruct(path, field_pats, dotdot),
433 Tuple(field_pats, dotdot),
435 Ref(sub, mutability),
437 Range(start, end, end_kind),
438 Slice(one, two, three)
441 impl_stable_hash_for!(enum hir::BinOpKind {
462 impl_stable_hash_for_spanned!(hir::BinOpKind);
464 impl_stable_hash_for!(enum hir::UnOp {
470 impl_stable_hash_for_spanned!(hir::StmtKind);
472 impl_stable_hash_for!(struct hir::Local {
483 impl_stable_hash_for_spanned!(hir::DeclKind);
484 impl_stable_hash_for!(enum hir::DeclKind {
489 impl_stable_hash_for!(struct hir::Arm {
496 impl_stable_hash_for!(enum hir::Guard {
500 impl_stable_hash_for!(struct hir::Field {
508 impl_stable_hash_for_spanned!(ast::Name);
511 impl_stable_hash_for!(enum hir::BlockCheckMode {
514 PushUnsafeBlock(src),
518 impl_stable_hash_for!(enum hir::UnsafeSource {
523 impl_stable_hash_for!(struct hir::AnonConst {
529 impl<'a> HashStable<StableHashingContext<'a>> for hir::Expr {
530 fn hash_stable<W: StableHasherResult>(&self,
531 hcx: &mut StableHashingContext<'a>,
532 hasher: &mut StableHasher<W>) {
533 hcx.while_hashing_hir_bodies(true, |hcx| {
542 span.hash_stable(hcx, hasher);
543 node.hash_stable(hcx, hasher);
544 attrs.hash_stable(hcx, hasher);
549 impl_stable_hash_for!(enum hir::ExprKind {
553 MethodCall(segment, span, args),
555 Binary(op, lhs, rhs),
561 While(cond, body, label),
562 Loop(body, label, loop_src),
563 Match(matchee, arms, match_src),
564 Closure(capture_clause, decl, body_id, span, gen),
567 AssignOp(op, lhs, rhs),
571 AddrOf(mutability, sub),
572 Break(destination, sub),
573 Continue(destination),
575 InlineAsm(asm, inputs, outputs),
576 Struct(path, fields, base),
581 impl_stable_hash_for!(enum hir::LocalSource {
586 impl_stable_hash_for!(enum hir::LoopSource {
592 impl<'a> HashStable<StableHashingContext<'a>> for hir::MatchSource {
593 fn hash_stable<W: StableHasherResult>(&self,
594 hcx: &mut StableHashingContext<'a>,
595 hasher: &mut StableHasher<W>) {
596 use hir::MatchSource;
598 mem::discriminant(self).hash_stable(hcx, hasher);
600 MatchSource::Normal |
601 MatchSource::WhileLetDesugar |
602 MatchSource::ForLoopDesugar |
603 MatchSource::TryDesugar => {
604 // No fields to hash.
606 MatchSource::IfLetDesugar { contains_else_clause } => {
607 contains_else_clause.hash_stable(hcx, hasher);
613 impl_stable_hash_for!(enum hir::GeneratorMovability {
618 impl_stable_hash_for!(enum hir::CaptureClause {
623 impl_stable_hash_for_spanned!(usize);
625 impl_stable_hash_for!(struct hir::Destination {
630 impl_stable_hash_for_spanned!(ast::Ident);
632 impl_stable_hash_for!(enum hir::LoopIdError {
634 UnlabeledCfInWhileCondition,
638 impl_stable_hash_for!(struct ast::Ident {
643 impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitItem {
644 fn hash_stable<W: StableHasherResult>(&self,
645 hcx: &mut StableHashingContext<'a>,
646 hasher: &mut StableHasher<W>) {
657 hcx.hash_hir_item_like(|hcx| {
658 ident.name.hash_stable(hcx, hasher);
659 attrs.hash_stable(hcx, hasher);
660 generics.hash_stable(hcx, hasher);
661 node.hash_stable(hcx, hasher);
662 span.hash_stable(hcx, hasher);
667 impl_stable_hash_for!(enum hir::TraitMethod {
672 impl_stable_hash_for!(enum hir::TraitItemKind {
678 impl<'a> HashStable<StableHashingContext<'a>> for hir::ImplItem {
679 fn hash_stable<W: StableHasherResult>(&self,
680 hcx: &mut StableHashingContext<'a>,
681 hasher: &mut StableHasher<W>) {
694 hcx.hash_hir_item_like(|hcx| {
695 ident.name.hash_stable(hcx, hasher);
696 vis.hash_stable(hcx, hasher);
697 defaultness.hash_stable(hcx, hasher);
698 attrs.hash_stable(hcx, hasher);
699 generics.hash_stable(hcx, hasher);
700 node.hash_stable(hcx, hasher);
701 span.hash_stable(hcx, hasher);
706 impl_stable_hash_for!(enum hir::ImplItemKind {
713 impl_stable_hash_for!(enum ::syntax::ast::CrateSugar {
718 impl<'a> HashStable<StableHashingContext<'a>> for hir::VisibilityKind {
719 fn hash_stable<W: StableHasherResult>(&self,
720 hcx: &mut StableHashingContext<'a>,
721 hasher: &mut StableHasher<W>) {
722 mem::discriminant(self).hash_stable(hcx, hasher);
724 hir::VisibilityKind::Public |
725 hir::VisibilityKind::Inherited => {
726 // No fields to hash.
728 hir::VisibilityKind::Crate(sugar) => {
729 sugar.hash_stable(hcx, hasher);
731 hir::VisibilityKind::Restricted { ref path, id, hir_id } => {
732 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
733 id.hash_stable(hcx, hasher);
734 hir_id.hash_stable(hcx, hasher);
736 path.hash_stable(hcx, hasher);
742 impl_stable_hash_for_spanned!(hir::VisibilityKind);
744 impl<'a> HashStable<StableHashingContext<'a>> for hir::Defaultness {
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::Defaultness::Final => {
751 // No fields to hash.
753 hir::Defaultness::Default { has_value } => {
754 has_value.hash_stable(hcx, hasher);
760 impl_stable_hash_for!(enum hir::ImplPolarity {
765 impl<'a> HashStable<StableHashingContext<'a>> for hir::Mod {
766 fn hash_stable<W: StableHasherResult>(&self,
767 hcx: &mut StableHashingContext<'a>,
768 hasher: &mut StableHasher<W>) {
770 inner: ref inner_span,
774 inner_span.hash_stable(hcx, hasher);
776 // Combining the DefPathHashes directly is faster than feeding them
777 // into the hasher. Because we use a commutative combine, we also don't
778 // have to sort the array.
779 let item_ids_hash = item_ids
782 let (def_path_hash, local_id) = id.id.to_stable_hash_key(hcx);
783 debug_assert_eq!(local_id, hir::ItemLocalId(0));
785 }).fold(Fingerprint::ZERO, |a, b| {
786 a.combine_commutative(b)
789 item_ids.len().hash_stable(hcx, hasher);
790 item_ids_hash.hash_stable(hcx, hasher);
794 impl_stable_hash_for!(struct hir::ForeignMod {
799 impl_stable_hash_for!(struct hir::EnumDef {
803 impl_stable_hash_for!(struct hir::VariantKind {
810 impl_stable_hash_for_spanned!(hir::VariantKind);
812 impl_stable_hash_for!(enum hir::UseKind {
818 impl_stable_hash_for!(struct hir::StructField {
820 ident -> (ident.name),
827 impl_stable_hash_for!(enum hir::VariantData {
833 impl<'a> HashStable<StableHashingContext<'a>> for hir::Item {
834 fn hash_stable<W: StableHasherResult>(&self,
835 hcx: &mut StableHashingContext<'a>,
836 hasher: &mut StableHasher<W>) {
847 hcx.hash_hir_item_like(|hcx| {
848 name.hash_stable(hcx, hasher);
849 attrs.hash_stable(hcx, hasher);
850 node.hash_stable(hcx, hasher);
851 vis.hash_stable(hcx, hasher);
852 span.hash_stable(hcx, hasher);
857 impl_stable_hash_for!(enum hir::ItemKind {
858 ExternCrate(orig_name),
860 Static(ty, mutability, body_id),
862 Fn(fn_decl, header, generics, body_id),
864 ForeignMod(foreign_mod),
865 GlobalAsm(global_asm),
868 Enum(enum_def, generics),
869 Struct(variant_data, generics),
870 Union(variant_data, generics),
871 Trait(is_auto, unsafety, generics, bounds, item_refs),
872 TraitAlias(generics, bounds),
873 Impl(unsafety, impl_polarity, impl_defaultness, generics, trait_ref, ty, impl_item_refs)
876 impl_stable_hash_for!(struct hir::TraitItemRef {
878 ident -> (ident.name),
884 impl_stable_hash_for!(struct hir::ImplItemRef {
886 ident -> (ident.name),
893 impl<'a> HashStable<StableHashingContext<'a>> for hir::AssociatedItemKind {
894 fn hash_stable<W: StableHasherResult>(&self,
895 hcx: &mut StableHashingContext<'a>,
896 hasher: &mut StableHasher<W>) {
897 mem::discriminant(self).hash_stable(hcx, hasher);
899 hir::AssociatedItemKind::Const |
900 hir::AssociatedItemKind::Existential |
901 hir::AssociatedItemKind::Type => {
902 // No fields to hash.
904 hir::AssociatedItemKind::Method { has_self } => {
905 has_self.hash_stable(hcx, hasher);
911 impl_stable_hash_for!(struct hir::ForeignItem {
920 impl_stable_hash_for!(enum hir::ForeignItemKind {
921 Fn(fn_decl, arg_names, generics),
922 Static(ty, is_mutbl),
926 impl_stable_hash_for!(enum hir::StmtKind {
932 impl_stable_hash_for!(struct hir::Arg {
938 impl<'a> HashStable<StableHashingContext<'a>> for hir::Body {
939 fn hash_stable<W: StableHasherResult>(&self,
940 hcx: &mut StableHashingContext<'a>,
941 hasher: &mut StableHasher<W>) {
948 hcx.with_node_id_hashing_mode(NodeIdHashingMode::Ignore, |hcx| {
949 arguments.hash_stable(hcx, hasher);
950 value.hash_stable(hcx, hasher);
951 is_generator.hash_stable(hcx, hasher);
956 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::BodyId {
957 type KeyType = (DefPathHash, hir::ItemLocalId);
960 fn to_stable_hash_key(&self,
961 hcx: &StableHashingContext<'a>)
962 -> (DefPathHash, hir::ItemLocalId) {
963 let hir::BodyId { node_id } = *self;
964 node_id.to_stable_hash_key(hcx)
968 impl_stable_hash_for!(struct hir::InlineAsmOutput {
974 impl_stable_hash_for!(struct hir::GlobalAsm {
976 ctxt -> _, // This is used for error reporting
979 impl_stable_hash_for!(struct hir::InlineAsm {
988 ctxt -> _, // This is used for error reporting
991 impl_stable_hash_for!(enum hir::def::CtorKind {
997 impl_stable_hash_for!(enum hir::def::NonMacroAttrKind {
1004 impl_stable_hash_for!(enum hir::def::Def {
1009 Existential(def_id),
1014 AssociatedTy(def_id),
1015 AssociatedExistential(def_id),
1018 SelfTy(trait_def_id, impl_def_id),
1022 Static(def_id, is_mutbl),
1023 StructCtor(def_id, ctor_kind),
1024 VariantCtor(def_id, ctor_kind),
1026 AssociatedConst(def_id),
1028 Upvar(def_id, index, expr_id),
1030 Macro(def_id, macro_kind),
1032 NonMacroAttr(attr_kind),
1036 impl_stable_hash_for!(enum hir::Mutability {
1041 impl_stable_hash_for!(enum hir::IsAuto {
1046 impl_stable_hash_for!(enum hir::Unsafety {
1051 impl_stable_hash_for!(enum hir::IsAsync {
1056 impl_stable_hash_for!(enum hir::Constness {
1061 impl<'a> HashStable<StableHashingContext<'a>> for hir::def_id::DefIndex {
1063 fn hash_stable<W: StableHasherResult>(&self,
1064 hcx: &mut StableHashingContext<'a>,
1065 hasher: &mut StableHasher<W>) {
1066 hcx.local_def_path_hash(*self).hash_stable(hcx, hasher);
1070 impl<'a> ToStableHashKey<StableHashingContext<'a>>
1071 for hir::def_id::DefIndex {
1072 type KeyType = DefPathHash;
1075 fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
1076 hcx.local_def_path_hash(*self)
1080 impl_stable_hash_for!(struct hir::def::Export {
1087 impl_stable_hash_for!(struct ::middle::lib_features::LibFeatures {
1092 impl<'a> HashStable<StableHashingContext<'a>> for ::middle::lang_items::LangItem {
1093 fn hash_stable<W: StableHasherResult>(&self,
1094 _: &mut StableHashingContext<'a>,
1095 hasher: &mut StableHasher<W>) {
1096 ::std::hash::Hash::hash(self, hasher);
1100 impl_stable_hash_for!(struct ::middle::lang_items::LanguageItems {
1105 impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitCandidate {
1106 fn hash_stable<W: StableHasherResult>(&self,
1107 hcx: &mut StableHashingContext<'a>,
1108 hasher: &mut StableHasher<W>) {
1109 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
1110 let hir::TraitCandidate {
1115 def_id.hash_stable(hcx, hasher);
1116 import_id.hash_stable(hcx, hasher);
1121 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::TraitCandidate {
1122 type KeyType = (DefPathHash, Option<(DefPathHash, hir::ItemLocalId)>);
1124 fn to_stable_hash_key(&self,
1125 hcx: &StableHashingContext<'a>)
1127 let hir::TraitCandidate {
1132 let import_id = import_id.map(|node_id| hcx.node_to_hir_id(node_id))
1133 .map(|hir_id| (hcx.local_def_path_hash(hir_id.owner),
1135 (hcx.def_path_hash(def_id), import_id)
1139 impl_stable_hash_for!(struct hir::CodegenFnAttrs {
1149 impl<'hir> HashStable<StableHashingContext<'hir>> for hir::CodegenFnAttrFlags
1151 fn hash_stable<W: StableHasherResult>(&self,
1152 hcx: &mut StableHashingContext<'hir>,
1153 hasher: &mut StableHasher<W>) {
1154 self.bits().hash_stable(hcx, hasher);
1158 impl<'hir> HashStable<StableHashingContext<'hir>> for attr::InlineAttr {
1159 fn hash_stable<W: StableHasherResult>(&self,
1160 hcx: &mut StableHashingContext<'hir>,
1161 hasher: &mut StableHasher<W>) {
1162 mem::discriminant(self).hash_stable(hcx, hasher);
1166 impl_stable_hash_for!(struct hir::Freevar {