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!(struct hir::Field {
504 impl_stable_hash_for_spanned!(ast::Name);
507 impl_stable_hash_for!(enum hir::BlockCheckMode {
510 PushUnsafeBlock(src),
514 impl_stable_hash_for!(enum hir::UnsafeSource {
519 impl_stable_hash_for!(struct hir::AnonConst {
525 impl<'a> HashStable<StableHashingContext<'a>> for hir::Expr {
526 fn hash_stable<W: StableHasherResult>(&self,
527 hcx: &mut StableHashingContext<'a>,
528 hasher: &mut StableHasher<W>) {
529 hcx.while_hashing_hir_bodies(true, |hcx| {
538 span.hash_stable(hcx, hasher);
539 node.hash_stable(hcx, hasher);
540 attrs.hash_stable(hcx, hasher);
545 impl_stable_hash_for!(enum hir::ExprKind {
549 MethodCall(segment, span, args),
551 Binary(op, lhs, rhs),
557 While(cond, body, label),
558 Loop(body, label, loop_src),
559 Match(matchee, arms, match_src),
560 Closure(capture_clause, decl, body_id, span, gen),
563 AssignOp(op, lhs, rhs),
567 AddrOf(mutability, sub),
568 Break(destination, sub),
569 Continue(destination),
571 InlineAsm(asm, inputs, outputs),
572 Struct(path, fields, base),
577 impl_stable_hash_for!(enum hir::LocalSource {
582 impl_stable_hash_for!(enum hir::LoopSource {
588 impl<'a> HashStable<StableHashingContext<'a>> for hir::MatchSource {
589 fn hash_stable<W: StableHasherResult>(&self,
590 hcx: &mut StableHashingContext<'a>,
591 hasher: &mut StableHasher<W>) {
592 use hir::MatchSource;
594 mem::discriminant(self).hash_stable(hcx, hasher);
596 MatchSource::Normal |
597 MatchSource::WhileLetDesugar |
598 MatchSource::ForLoopDesugar |
599 MatchSource::TryDesugar => {
600 // No fields to hash.
602 MatchSource::IfLetDesugar { contains_else_clause } => {
603 contains_else_clause.hash_stable(hcx, hasher);
609 impl_stable_hash_for!(enum hir::GeneratorMovability {
614 impl_stable_hash_for!(enum hir::CaptureClause {
619 impl_stable_hash_for_spanned!(usize);
621 impl_stable_hash_for!(struct hir::Destination {
626 impl_stable_hash_for_spanned!(ast::Ident);
628 impl_stable_hash_for!(enum hir::LoopIdError {
630 UnlabeledCfInWhileCondition,
634 impl_stable_hash_for!(struct ast::Ident {
639 impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitItem {
640 fn hash_stable<W: StableHasherResult>(&self,
641 hcx: &mut StableHashingContext<'a>,
642 hasher: &mut StableHasher<W>) {
653 hcx.hash_hir_item_like(|hcx| {
654 ident.name.hash_stable(hcx, hasher);
655 attrs.hash_stable(hcx, hasher);
656 generics.hash_stable(hcx, hasher);
657 node.hash_stable(hcx, hasher);
658 span.hash_stable(hcx, hasher);
663 impl_stable_hash_for!(enum hir::TraitMethod {
668 impl_stable_hash_for!(enum hir::TraitItemKind {
674 impl<'a> HashStable<StableHashingContext<'a>> for hir::ImplItem {
675 fn hash_stable<W: StableHasherResult>(&self,
676 hcx: &mut StableHashingContext<'a>,
677 hasher: &mut StableHasher<W>) {
690 hcx.hash_hir_item_like(|hcx| {
691 ident.name.hash_stable(hcx, hasher);
692 vis.hash_stable(hcx, hasher);
693 defaultness.hash_stable(hcx, hasher);
694 attrs.hash_stable(hcx, hasher);
695 generics.hash_stable(hcx, hasher);
696 node.hash_stable(hcx, hasher);
697 span.hash_stable(hcx, hasher);
702 impl_stable_hash_for!(enum hir::ImplItemKind {
709 impl_stable_hash_for!(enum ::syntax::ast::CrateSugar {
714 impl<'a> HashStable<StableHashingContext<'a>> for hir::VisibilityKind {
715 fn hash_stable<W: StableHasherResult>(&self,
716 hcx: &mut StableHashingContext<'a>,
717 hasher: &mut StableHasher<W>) {
718 mem::discriminant(self).hash_stable(hcx, hasher);
720 hir::VisibilityKind::Public |
721 hir::VisibilityKind::Inherited => {
722 // No fields to hash.
724 hir::VisibilityKind::Crate(sugar) => {
725 sugar.hash_stable(hcx, hasher);
727 hir::VisibilityKind::Restricted { ref path, id, hir_id } => {
728 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
729 id.hash_stable(hcx, hasher);
730 hir_id.hash_stable(hcx, hasher);
732 path.hash_stable(hcx, hasher);
738 impl_stable_hash_for_spanned!(hir::VisibilityKind);
740 impl<'a> HashStable<StableHashingContext<'a>> for hir::Defaultness {
741 fn hash_stable<W: StableHasherResult>(&self,
742 hcx: &mut StableHashingContext<'a>,
743 hasher: &mut StableHasher<W>) {
744 mem::discriminant(self).hash_stable(hcx, hasher);
746 hir::Defaultness::Final => {
747 // No fields to hash.
749 hir::Defaultness::Default { has_value } => {
750 has_value.hash_stable(hcx, hasher);
756 impl_stable_hash_for!(enum hir::ImplPolarity {
761 impl<'a> HashStable<StableHashingContext<'a>> for hir::Mod {
762 fn hash_stable<W: StableHasherResult>(&self,
763 hcx: &mut StableHashingContext<'a>,
764 hasher: &mut StableHasher<W>) {
766 inner: ref inner_span,
770 inner_span.hash_stable(hcx, hasher);
772 // Combining the DefPathHashes directly is faster than feeding them
773 // into the hasher. Because we use a commutative combine, we also don't
774 // have to sort the array.
775 let item_ids_hash = item_ids
778 let (def_path_hash, local_id) = id.id.to_stable_hash_key(hcx);
779 debug_assert_eq!(local_id, hir::ItemLocalId(0));
781 }).fold(Fingerprint::ZERO, |a, b| {
782 a.combine_commutative(b)
785 item_ids.len().hash_stable(hcx, hasher);
786 item_ids_hash.hash_stable(hcx, hasher);
790 impl_stable_hash_for!(struct hir::ForeignMod {
795 impl_stable_hash_for!(struct hir::EnumDef {
799 impl_stable_hash_for!(struct hir::VariantKind {
806 impl_stable_hash_for_spanned!(hir::VariantKind);
808 impl_stable_hash_for!(enum hir::UseKind {
814 impl_stable_hash_for!(struct hir::StructField {
816 ident -> (ident.name),
823 impl_stable_hash_for!(enum hir::VariantData {
829 impl<'a> HashStable<StableHashingContext<'a>> for hir::Item {
830 fn hash_stable<W: StableHasherResult>(&self,
831 hcx: &mut StableHashingContext<'a>,
832 hasher: &mut StableHasher<W>) {
843 hcx.hash_hir_item_like(|hcx| {
844 name.hash_stable(hcx, hasher);
845 attrs.hash_stable(hcx, hasher);
846 node.hash_stable(hcx, hasher);
847 vis.hash_stable(hcx, hasher);
848 span.hash_stable(hcx, hasher);
853 impl_stable_hash_for!(enum hir::ItemKind {
854 ExternCrate(orig_name),
856 Static(ty, mutability, body_id),
858 Fn(fn_decl, header, generics, body_id),
860 ForeignMod(foreign_mod),
861 GlobalAsm(global_asm),
864 Enum(enum_def, generics),
865 Struct(variant_data, generics),
866 Union(variant_data, generics),
867 Trait(is_auto, unsafety, generics, bounds, item_refs),
868 TraitAlias(generics, bounds),
869 Impl(unsafety, impl_polarity, impl_defaultness, generics, trait_ref, ty, impl_item_refs)
872 impl_stable_hash_for!(struct hir::TraitItemRef {
874 ident -> (ident.name),
880 impl_stable_hash_for!(struct hir::ImplItemRef {
882 ident -> (ident.name),
889 impl<'a> HashStable<StableHashingContext<'a>> for hir::AssociatedItemKind {
890 fn hash_stable<W: StableHasherResult>(&self,
891 hcx: &mut StableHashingContext<'a>,
892 hasher: &mut StableHasher<W>) {
893 mem::discriminant(self).hash_stable(hcx, hasher);
895 hir::AssociatedItemKind::Const |
896 hir::AssociatedItemKind::Existential |
897 hir::AssociatedItemKind::Type => {
898 // No fields to hash.
900 hir::AssociatedItemKind::Method { has_self } => {
901 has_self.hash_stable(hcx, hasher);
907 impl_stable_hash_for!(struct hir::ForeignItem {
916 impl_stable_hash_for!(enum hir::ForeignItemKind {
917 Fn(fn_decl, arg_names, generics),
918 Static(ty, is_mutbl),
922 impl_stable_hash_for!(enum hir::StmtKind {
928 impl_stable_hash_for!(struct hir::Arg {
934 impl<'a> HashStable<StableHashingContext<'a>> for hir::Body {
935 fn hash_stable<W: StableHasherResult>(&self,
936 hcx: &mut StableHashingContext<'a>,
937 hasher: &mut StableHasher<W>) {
944 hcx.with_node_id_hashing_mode(NodeIdHashingMode::Ignore, |hcx| {
945 arguments.hash_stable(hcx, hasher);
946 value.hash_stable(hcx, hasher);
947 is_generator.hash_stable(hcx, hasher);
952 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::BodyId {
953 type KeyType = (DefPathHash, hir::ItemLocalId);
956 fn to_stable_hash_key(&self,
957 hcx: &StableHashingContext<'a>)
958 -> (DefPathHash, hir::ItemLocalId) {
959 let hir::BodyId { node_id } = *self;
960 node_id.to_stable_hash_key(hcx)
964 impl_stable_hash_for!(struct hir::InlineAsmOutput {
970 impl_stable_hash_for!(struct hir::GlobalAsm {
972 ctxt -> _, // This is used for error reporting
975 impl_stable_hash_for!(struct hir::InlineAsm {
984 ctxt -> _, // This is used for error reporting
987 impl_stable_hash_for!(enum hir::def::CtorKind {
993 impl_stable_hash_for!(enum hir::def::NonMacroAttrKind {
1000 impl_stable_hash_for!(enum hir::def::Def {
1005 Existential(def_id),
1010 AssociatedTy(def_id),
1011 AssociatedExistential(def_id),
1014 SelfTy(trait_def_id, impl_def_id),
1018 Static(def_id, is_mutbl),
1019 StructCtor(def_id, ctor_kind),
1020 VariantCtor(def_id, ctor_kind),
1022 AssociatedConst(def_id),
1024 Upvar(def_id, index, expr_id),
1026 Macro(def_id, macro_kind),
1028 NonMacroAttr(attr_kind),
1032 impl_stable_hash_for!(enum hir::Mutability {
1037 impl_stable_hash_for!(enum hir::IsAuto {
1042 impl_stable_hash_for!(enum hir::Unsafety {
1047 impl_stable_hash_for!(enum hir::IsAsync {
1052 impl_stable_hash_for!(enum hir::Constness {
1057 impl<'a> HashStable<StableHashingContext<'a>> for hir::def_id::DefIndex {
1059 fn hash_stable<W: StableHasherResult>(&self,
1060 hcx: &mut StableHashingContext<'a>,
1061 hasher: &mut StableHasher<W>) {
1062 hcx.local_def_path_hash(*self).hash_stable(hcx, hasher);
1066 impl<'a> ToStableHashKey<StableHashingContext<'a>>
1067 for hir::def_id::DefIndex {
1068 type KeyType = DefPathHash;
1071 fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
1072 hcx.local_def_path_hash(*self)
1076 impl_stable_hash_for!(struct hir::def::Export {
1083 impl_stable_hash_for!(struct ::middle::lib_features::LibFeatures {
1088 impl<'a> HashStable<StableHashingContext<'a>> for ::middle::lang_items::LangItem {
1089 fn hash_stable<W: StableHasherResult>(&self,
1090 _: &mut StableHashingContext<'a>,
1091 hasher: &mut StableHasher<W>) {
1092 ::std::hash::Hash::hash(self, hasher);
1096 impl_stable_hash_for!(struct ::middle::lang_items::LanguageItems {
1101 impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitCandidate {
1102 fn hash_stable<W: StableHasherResult>(&self,
1103 hcx: &mut StableHashingContext<'a>,
1104 hasher: &mut StableHasher<W>) {
1105 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
1106 let hir::TraitCandidate {
1111 def_id.hash_stable(hcx, hasher);
1112 import_id.hash_stable(hcx, hasher);
1117 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::TraitCandidate {
1118 type KeyType = (DefPathHash, Option<(DefPathHash, hir::ItemLocalId)>);
1120 fn to_stable_hash_key(&self,
1121 hcx: &StableHashingContext<'a>)
1123 let hir::TraitCandidate {
1128 let import_id = import_id.map(|node_id| hcx.node_to_hir_id(node_id))
1129 .map(|hir_id| (hcx.local_def_path_hash(hir_id.owner),
1131 (hcx.def_path_hash(def_id), import_id)
1135 impl_stable_hash_for!(struct hir::CodegenFnAttrs {
1145 impl<'hir> HashStable<StableHashingContext<'hir>> for hir::CodegenFnAttrFlags
1147 fn hash_stable<W: StableHasherResult>(&self,
1148 hcx: &mut StableHashingContext<'hir>,
1149 hasher: &mut StableHasher<W>) {
1150 self.bits().hash_stable(hcx, hasher);
1154 impl<'hir> HashStable<StableHashingContext<'hir>> for attr::InlineAttr {
1155 fn hash_stable<W: StableHasherResult>(&self,
1156 hcx: &mut StableHashingContext<'hir>,
1157 hasher: &mut StableHasher<W>) {
1158 mem::discriminant(self).hash_stable(hcx, hasher);
1162 impl_stable_hash_for!(struct hir::Freevar {