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};
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::Ty_ {
342 TyTraitObject(trait_refs, lifetime),
343 TyImplTraitExistential(existty, def_id, lifetimes),
349 impl_stable_hash_for!(struct hir::FnDecl {
356 impl_stable_hash_for!(enum hir::FunctionRetTy {
361 impl_stable_hash_for!(struct hir::TraitRef {
362 // 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::BinOp_ {
462 impl_stable_hash_for_spanned!(hir::BinOp_);
464 impl_stable_hash_for!(enum hir::UnOp {
470 impl_stable_hash_for_spanned!(hir::Stmt_);
472 impl_stable_hash_for!(struct hir::Local {
483 impl_stable_hash_for_spanned!(hir::Decl_);
484 impl_stable_hash_for!(enum hir::Decl_ {
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::Expr_ {
548 ExprCall(callee, args),
549 ExprMethodCall(segment, span, args),
551 ExprBinary(op, lhs, rhs),
552 ExprUnary(op, operand),
556 ExprIf(cond, then, els),
557 ExprWhile(cond, body, label),
558 ExprLoop(body, label, loop_src),
559 ExprMatch(matchee, arms, match_src),
560 ExprClosure(capture_clause, decl, body_id, span, gen),
561 ExprBlock(blk, label),
562 ExprAssign(lhs, rhs),
563 ExprAssignOp(op, lhs, rhs),
564 ExprField(owner, ident),
567 ExprAddrOf(mutability, sub),
568 ExprBreak(destination, sub),
569 ExprContinue(destination),
571 ExprInlineAsm(asm, inputs, outputs),
572 ExprStruct(path, fields, base),
573 ExprRepeat(val, times),
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 {
708 impl_stable_hash_for!(enum ::syntax::ast::CrateSugar {
713 impl<'a> HashStable<StableHashingContext<'a>> for hir::VisibilityKind {
714 fn hash_stable<W: StableHasherResult>(&self,
715 hcx: &mut StableHashingContext<'a>,
716 hasher: &mut StableHasher<W>) {
717 mem::discriminant(self).hash_stable(hcx, hasher);
719 hir::VisibilityKind::Public |
720 hir::VisibilityKind::Inherited => {
721 // No fields to hash.
723 hir::VisibilityKind::Crate(sugar) => {
724 sugar.hash_stable(hcx, hasher);
726 hir::VisibilityKind::Restricted { ref path, id } => {
727 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
728 id.hash_stable(hcx, hasher);
730 path.hash_stable(hcx, hasher);
736 impl_stable_hash_for_spanned!(hir::VisibilityKind);
738 impl<'a> HashStable<StableHashingContext<'a>> for hir::Defaultness {
739 fn hash_stable<W: StableHasherResult>(&self,
740 hcx: &mut StableHashingContext<'a>,
741 hasher: &mut StableHasher<W>) {
742 mem::discriminant(self).hash_stable(hcx, hasher);
744 hir::Defaultness::Final => {
745 // No fields to hash.
747 hir::Defaultness::Default { has_value } => {
748 has_value.hash_stable(hcx, hasher);
754 impl_stable_hash_for!(enum hir::ImplPolarity {
759 impl_stable_hash_for!(struct hir::Mod {
761 // We are not hashing the IDs of the items contained in the module.
762 // This is harmless and matches the current behavior but it's not
763 // actually correct. See issue #40876.
767 impl_stable_hash_for!(struct hir::ForeignMod {
772 impl_stable_hash_for!(struct hir::EnumDef {
776 impl_stable_hash_for!(struct hir::Variant_ {
783 impl_stable_hash_for_spanned!(hir::Variant_);
785 impl_stable_hash_for!(enum hir::UseKind {
791 impl_stable_hash_for!(struct hir::StructField {
793 ident -> (ident.name),
800 impl_stable_hash_for!(enum hir::VariantData {
806 impl<'a> HashStable<StableHashingContext<'a>> for hir::Item {
807 fn hash_stable<W: StableHasherResult>(&self,
808 hcx: &mut StableHashingContext<'a>,
809 hasher: &mut StableHasher<W>) {
820 hcx.hash_hir_item_like(|hcx| {
821 name.hash_stable(hcx, hasher);
822 attrs.hash_stable(hcx, hasher);
823 node.hash_stable(hcx, hasher);
824 vis.hash_stable(hcx, hasher);
825 span.hash_stable(hcx, hasher);
830 impl_stable_hash_for!(enum hir::Item_ {
831 ItemExternCrate(orig_name),
832 ItemUse(path, use_kind),
833 ItemStatic(ty, mutability, body_id),
834 ItemConst(ty, body_id),
835 ItemFn(fn_decl, header, generics, body_id),
837 ItemForeignMod(foreign_mod),
838 ItemGlobalAsm(global_asm),
839 ItemTy(ty, generics),
840 ItemExistential(exist),
841 ItemEnum(enum_def, generics),
842 ItemStruct(variant_data, generics),
843 ItemUnion(variant_data, generics),
844 ItemTrait(is_auto, unsafety, generics, bounds, item_refs),
845 ItemTraitAlias(generics, bounds),
846 ItemImpl(unsafety, impl_polarity, impl_defaultness, generics, trait_ref, ty, impl_item_refs)
849 impl_stable_hash_for!(struct hir::TraitItemRef {
851 ident -> (ident.name),
857 impl_stable_hash_for!(struct hir::ImplItemRef {
859 ident -> (ident.name),
866 impl<'a> HashStable<StableHashingContext<'a>> for hir::AssociatedItemKind {
867 fn hash_stable<W: StableHasherResult>(&self,
868 hcx: &mut StableHashingContext<'a>,
869 hasher: &mut StableHasher<W>) {
870 mem::discriminant(self).hash_stable(hcx, hasher);
872 hir::AssociatedItemKind::Const |
873 hir::AssociatedItemKind::Type => {
874 // No fields to hash.
876 hir::AssociatedItemKind::Method { has_self } => {
877 has_self.hash_stable(hcx, hasher);
883 impl_stable_hash_for!(struct hir::ForeignItem {
892 impl_stable_hash_for!(enum hir::ForeignItem_ {
893 ForeignItemFn(fn_decl, arg_names, generics),
894 ForeignItemStatic(ty, is_mutbl),
898 impl_stable_hash_for!(enum hir::Stmt_ {
904 impl_stable_hash_for!(struct hir::Arg {
910 impl<'a> HashStable<StableHashingContext<'a>> for hir::Body {
911 fn hash_stable<W: StableHasherResult>(&self,
912 hcx: &mut StableHashingContext<'a>,
913 hasher: &mut StableHasher<W>) {
920 hcx.with_node_id_hashing_mode(NodeIdHashingMode::Ignore, |hcx| {
921 arguments.hash_stable(hcx, hasher);
922 value.hash_stable(hcx, hasher);
923 is_generator.hash_stable(hcx, hasher);
928 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::BodyId {
929 type KeyType = (DefPathHash, hir::ItemLocalId);
932 fn to_stable_hash_key(&self,
933 hcx: &StableHashingContext<'a>)
934 -> (DefPathHash, hir::ItemLocalId) {
935 let hir::BodyId { node_id } = *self;
936 node_id.to_stable_hash_key(hcx)
940 impl_stable_hash_for!(struct hir::InlineAsmOutput {
946 impl_stable_hash_for!(struct hir::GlobalAsm {
948 ctxt -> _, // This is used for error reporting
951 impl_stable_hash_for!(struct hir::InlineAsm {
960 ctxt -> _, // This is used for error reporting
963 impl_stable_hash_for!(enum hir::def::CtorKind {
969 impl_stable_hash_for!(enum hir::def::Def {
979 AssociatedTy(def_id),
982 SelfTy(trait_def_id, impl_def_id),
986 Static(def_id, is_mutbl),
987 StructCtor(def_id, ctor_kind),
988 VariantCtor(def_id, ctor_kind),
990 AssociatedConst(def_id),
992 Upvar(def_id, index, expr_id),
994 Macro(def_id, macro_kind),
999 impl_stable_hash_for!(enum hir::Mutability {
1004 impl_stable_hash_for!(enum hir::IsAuto {
1009 impl_stable_hash_for!(enum hir::Unsafety {
1014 impl_stable_hash_for!(enum hir::IsAsync {
1019 impl_stable_hash_for!(enum hir::Constness {
1024 impl<'a> HashStable<StableHashingContext<'a>> for hir::def_id::DefIndex {
1026 fn hash_stable<W: StableHasherResult>(&self,
1027 hcx: &mut StableHashingContext<'a>,
1028 hasher: &mut StableHasher<W>) {
1029 hcx.local_def_path_hash(*self).hash_stable(hcx, hasher);
1033 impl<'a> ToStableHashKey<StableHashingContext<'a>>
1034 for hir::def_id::DefIndex {
1035 type KeyType = DefPathHash;
1038 fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
1039 hcx.local_def_path_hash(*self)
1043 impl_stable_hash_for!(struct hir::def::Export {
1050 impl<'a> HashStable<StableHashingContext<'a>> for ::middle::lang_items::LangItem {
1051 fn hash_stable<W: StableHasherResult>(&self,
1052 _: &mut StableHashingContext<'a>,
1053 hasher: &mut StableHasher<W>) {
1054 ::std::hash::Hash::hash(self, hasher);
1058 impl_stable_hash_for!(struct ::middle::lang_items::LanguageItems {
1063 impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitCandidate {
1064 fn hash_stable<W: StableHasherResult>(&self,
1065 hcx: &mut StableHashingContext<'a>,
1066 hasher: &mut StableHasher<W>) {
1067 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
1068 let hir::TraitCandidate {
1073 def_id.hash_stable(hcx, hasher);
1074 import_id.hash_stable(hcx, hasher);
1079 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::TraitCandidate {
1080 type KeyType = (DefPathHash, Option<(DefPathHash, hir::ItemLocalId)>);
1082 fn to_stable_hash_key(&self,
1083 hcx: &StableHashingContext<'a>)
1085 let hir::TraitCandidate {
1090 let import_id = import_id.map(|node_id| hcx.node_to_hir_id(node_id))
1091 .map(|hir_id| (hcx.local_def_path_hash(hir_id.owner),
1093 (hcx.def_path_hash(def_id), import_id)
1097 impl_stable_hash_for!(struct hir::CodegenFnAttrs {
1105 impl<'hir> HashStable<StableHashingContext<'hir>> for hir::CodegenFnAttrFlags
1107 fn hash_stable<W: StableHasherResult>(&self,
1108 hcx: &mut StableHashingContext<'hir>,
1109 hasher: &mut StableHasher<W>) {
1110 self.bits().hash_stable(hcx, hasher);
1114 impl<'hir> HashStable<StableHashingContext<'hir>> for attr::InlineAttr {
1115 fn hash_stable<W: StableHasherResult>(&self,
1116 hcx: &mut StableHashingContext<'hir>,
1117 hasher: &mut StableHasher<W>) {
1118 mem::discriminant(self).hash_stable(hcx, hasher);
1122 impl_stable_hash_for!(struct hir::Freevar {