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
366 impl_stable_hash_for!(struct hir::PolyTraitRef {
367 bound_generic_params,
372 impl_stable_hash_for!(enum hir::QPath {
374 TypeRelative(t, path_segment)
377 impl_stable_hash_for!(struct hir::MacroDef {
387 impl_stable_hash_for!(struct hir::Block {
398 impl_stable_hash_for!(struct hir::Pat {
405 impl_stable_hash_for_spanned!(hir::FieldPat);
407 impl_stable_hash_for!(struct hir::FieldPat {
409 ident -> (ident.name),
414 impl_stable_hash_for!(enum hir::BindingAnnotation {
421 impl_stable_hash_for!(enum hir::RangeEnd {
426 impl_stable_hash_for!(enum hir::PatKind {
428 Binding(binding_mode, var, name, sub),
429 Struct(path, field_pats, dotdot),
430 TupleStruct(path, field_pats, dotdot),
432 Tuple(field_pats, dotdot),
434 Ref(sub, mutability),
436 Range(start, end, end_kind),
437 Slice(one, two, three)
440 impl_stable_hash_for!(enum hir::BinOpKind {
461 impl_stable_hash_for_spanned!(hir::BinOpKind);
463 impl_stable_hash_for!(enum hir::UnOp {
469 impl_stable_hash_for_spanned!(hir::StmtKind);
471 impl_stable_hash_for!(struct hir::Local {
482 impl_stable_hash_for_spanned!(hir::DeclKind);
483 impl_stable_hash_for!(enum hir::DeclKind {
488 impl_stable_hash_for!(struct hir::Arm {
495 impl_stable_hash_for!(struct hir::Field {
503 impl_stable_hash_for_spanned!(ast::Name);
506 impl_stable_hash_for!(enum hir::BlockCheckMode {
509 PushUnsafeBlock(src),
513 impl_stable_hash_for!(enum hir::UnsafeSource {
518 impl_stable_hash_for!(struct hir::AnonConst {
524 impl<'a> HashStable<StableHashingContext<'a>> for hir::Expr {
525 fn hash_stable<W: StableHasherResult>(&self,
526 hcx: &mut StableHashingContext<'a>,
527 hasher: &mut StableHasher<W>) {
528 hcx.while_hashing_hir_bodies(true, |hcx| {
537 span.hash_stable(hcx, hasher);
538 node.hash_stable(hcx, hasher);
539 attrs.hash_stable(hcx, hasher);
544 impl_stable_hash_for!(enum hir::ExprKind {
548 MethodCall(segment, span, args),
550 Binary(op, lhs, rhs),
556 While(cond, body, label),
557 Loop(body, label, loop_src),
558 Match(matchee, arms, match_src),
559 Closure(capture_clause, decl, body_id, span, gen),
562 AssignOp(op, lhs, rhs),
566 AddrOf(mutability, sub),
567 Break(destination, sub),
568 Continue(destination),
570 InlineAsm(asm, inputs, outputs),
571 Struct(path, fields, base),
576 impl_stable_hash_for!(enum hir::LocalSource {
581 impl_stable_hash_for!(enum hir::LoopSource {
587 impl<'a> HashStable<StableHashingContext<'a>> for hir::MatchSource {
588 fn hash_stable<W: StableHasherResult>(&self,
589 hcx: &mut StableHashingContext<'a>,
590 hasher: &mut StableHasher<W>) {
591 use hir::MatchSource;
593 mem::discriminant(self).hash_stable(hcx, hasher);
595 MatchSource::Normal |
596 MatchSource::WhileLetDesugar |
597 MatchSource::ForLoopDesugar |
598 MatchSource::TryDesugar => {
599 // No fields to hash.
601 MatchSource::IfLetDesugar { contains_else_clause } => {
602 contains_else_clause.hash_stable(hcx, hasher);
608 impl_stable_hash_for!(enum hir::GeneratorMovability {
613 impl_stable_hash_for!(enum hir::CaptureClause {
618 impl_stable_hash_for_spanned!(usize);
620 impl_stable_hash_for!(struct hir::Destination {
625 impl_stable_hash_for_spanned!(ast::Ident);
627 impl_stable_hash_for!(enum hir::LoopIdError {
629 UnlabeledCfInWhileCondition,
633 impl_stable_hash_for!(struct ast::Ident {
638 impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitItem {
639 fn hash_stable<W: StableHasherResult>(&self,
640 hcx: &mut StableHashingContext<'a>,
641 hasher: &mut StableHasher<W>) {
652 hcx.hash_hir_item_like(|hcx| {
653 ident.name.hash_stable(hcx, hasher);
654 attrs.hash_stable(hcx, hasher);
655 generics.hash_stable(hcx, hasher);
656 node.hash_stable(hcx, hasher);
657 span.hash_stable(hcx, hasher);
662 impl_stable_hash_for!(enum hir::TraitMethod {
667 impl_stable_hash_for!(enum hir::TraitItemKind {
673 impl<'a> HashStable<StableHashingContext<'a>> for hir::ImplItem {
674 fn hash_stable<W: StableHasherResult>(&self,
675 hcx: &mut StableHashingContext<'a>,
676 hasher: &mut StableHasher<W>) {
689 hcx.hash_hir_item_like(|hcx| {
690 ident.name.hash_stable(hcx, hasher);
691 vis.hash_stable(hcx, hasher);
692 defaultness.hash_stable(hcx, hasher);
693 attrs.hash_stable(hcx, hasher);
694 generics.hash_stable(hcx, hasher);
695 node.hash_stable(hcx, hasher);
696 span.hash_stable(hcx, hasher);
701 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<'a> HashStable<StableHashingContext<'a>> for hir::Mod {
760 fn hash_stable<W: StableHasherResult>(&self,
761 hcx: &mut StableHashingContext<'a>,
762 hasher: &mut StableHasher<W>) {
764 inner: ref inner_span,
768 inner_span.hash_stable(hcx, hasher);
770 // Combining the DefPathHashes directly is faster than feeding them
771 // into the hasher. Because we use a commutative combine, we also don't
772 // have to sort the array.
773 let item_ids_hash = item_ids
776 let (def_path_hash, local_id) = id.id.to_stable_hash_key(hcx);
777 debug_assert_eq!(local_id, hir::ItemLocalId(0));
779 }).fold(Fingerprint::ZERO, |a, b| {
780 a.combine_commutative(b)
783 item_ids.len().hash_stable(hcx, hasher);
784 item_ids_hash.hash_stable(hcx, hasher);
788 impl_stable_hash_for!(struct hir::ForeignMod {
793 impl_stable_hash_for!(struct hir::EnumDef {
797 impl_stable_hash_for!(struct hir::VariantKind {
804 impl_stable_hash_for_spanned!(hir::VariantKind);
806 impl_stable_hash_for!(enum hir::UseKind {
812 impl_stable_hash_for!(struct hir::StructField {
814 ident -> (ident.name),
821 impl_stable_hash_for!(enum hir::VariantData {
827 impl<'a> HashStable<StableHashingContext<'a>> for hir::Item {
828 fn hash_stable<W: StableHasherResult>(&self,
829 hcx: &mut StableHashingContext<'a>,
830 hasher: &mut StableHasher<W>) {
841 hcx.hash_hir_item_like(|hcx| {
842 name.hash_stable(hcx, hasher);
843 attrs.hash_stable(hcx, hasher);
844 node.hash_stable(hcx, hasher);
845 vis.hash_stable(hcx, hasher);
846 span.hash_stable(hcx, hasher);
851 impl_stable_hash_for!(enum hir::ItemKind {
852 ExternCrate(orig_name),
854 Static(ty, mutability, body_id),
856 Fn(fn_decl, header, generics, body_id),
858 ForeignMod(foreign_mod),
859 GlobalAsm(global_asm),
862 Enum(enum_def, generics),
863 Struct(variant_data, generics),
864 Union(variant_data, generics),
865 Trait(is_auto, unsafety, generics, bounds, item_refs),
866 TraitAlias(generics, bounds),
867 Impl(unsafety, impl_polarity, impl_defaultness, generics, trait_ref, ty, impl_item_refs)
870 impl_stable_hash_for!(struct hir::TraitItemRef {
872 ident -> (ident.name),
878 impl_stable_hash_for!(struct hir::ImplItemRef {
880 ident -> (ident.name),
887 impl<'a> HashStable<StableHashingContext<'a>> for hir::AssociatedItemKind {
888 fn hash_stable<W: StableHasherResult>(&self,
889 hcx: &mut StableHashingContext<'a>,
890 hasher: &mut StableHasher<W>) {
891 mem::discriminant(self).hash_stable(hcx, hasher);
893 hir::AssociatedItemKind::Const |
894 hir::AssociatedItemKind::Existential |
895 hir::AssociatedItemKind::Type => {
896 // No fields to hash.
898 hir::AssociatedItemKind::Method { has_self } => {
899 has_self.hash_stable(hcx, hasher);
905 impl_stable_hash_for!(struct hir::ForeignItem {
914 impl_stable_hash_for!(enum hir::ForeignItemKind {
915 Fn(fn_decl, arg_names, generics),
916 Static(ty, is_mutbl),
920 impl_stable_hash_for!(enum hir::StmtKind {
926 impl_stable_hash_for!(struct hir::Arg {
932 impl<'a> HashStable<StableHashingContext<'a>> for hir::Body {
933 fn hash_stable<W: StableHasherResult>(&self,
934 hcx: &mut StableHashingContext<'a>,
935 hasher: &mut StableHasher<W>) {
942 hcx.with_node_id_hashing_mode(NodeIdHashingMode::Ignore, |hcx| {
943 arguments.hash_stable(hcx, hasher);
944 value.hash_stable(hcx, hasher);
945 is_generator.hash_stable(hcx, hasher);
950 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::BodyId {
951 type KeyType = (DefPathHash, hir::ItemLocalId);
954 fn to_stable_hash_key(&self,
955 hcx: &StableHashingContext<'a>)
956 -> (DefPathHash, hir::ItemLocalId) {
957 let hir::BodyId { node_id } = *self;
958 node_id.to_stable_hash_key(hcx)
962 impl_stable_hash_for!(struct hir::InlineAsmOutput {
968 impl_stable_hash_for!(struct hir::GlobalAsm {
970 ctxt -> _, // This is used for error reporting
973 impl_stable_hash_for!(struct hir::InlineAsm {
982 ctxt -> _, // This is used for error reporting
985 impl_stable_hash_for!(enum hir::def::CtorKind {
991 impl_stable_hash_for!(enum hir::def::Def {
1001 AssociatedTy(def_id),
1002 AssociatedExistential(def_id),
1005 SelfTy(trait_def_id, impl_def_id),
1009 Static(def_id, is_mutbl),
1010 StructCtor(def_id, ctor_kind),
1011 VariantCtor(def_id, ctor_kind),
1013 AssociatedConst(def_id),
1015 Upvar(def_id, index, expr_id),
1017 Macro(def_id, macro_kind),
1024 impl_stable_hash_for!(enum hir::Mutability {
1029 impl_stable_hash_for!(enum hir::IsAuto {
1034 impl_stable_hash_for!(enum hir::Unsafety {
1039 impl_stable_hash_for!(enum hir::IsAsync {
1044 impl_stable_hash_for!(enum hir::Constness {
1049 impl<'a> HashStable<StableHashingContext<'a>> for hir::def_id::DefIndex {
1051 fn hash_stable<W: StableHasherResult>(&self,
1052 hcx: &mut StableHashingContext<'a>,
1053 hasher: &mut StableHasher<W>) {
1054 hcx.local_def_path_hash(*self).hash_stable(hcx, hasher);
1058 impl<'a> ToStableHashKey<StableHashingContext<'a>>
1059 for hir::def_id::DefIndex {
1060 type KeyType = DefPathHash;
1063 fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
1064 hcx.local_def_path_hash(*self)
1068 impl_stable_hash_for!(struct hir::def::Export {
1075 impl<'a> HashStable<StableHashingContext<'a>> for ::middle::lang_items::LangItem {
1076 fn hash_stable<W: StableHasherResult>(&self,
1077 _: &mut StableHashingContext<'a>,
1078 hasher: &mut StableHasher<W>) {
1079 ::std::hash::Hash::hash(self, hasher);
1083 impl_stable_hash_for!(struct ::middle::lang_items::LanguageItems {
1088 impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitCandidate {
1089 fn hash_stable<W: StableHasherResult>(&self,
1090 hcx: &mut StableHashingContext<'a>,
1091 hasher: &mut StableHasher<W>) {
1092 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
1093 let hir::TraitCandidate {
1098 def_id.hash_stable(hcx, hasher);
1099 import_id.hash_stable(hcx, hasher);
1104 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::TraitCandidate {
1105 type KeyType = (DefPathHash, Option<(DefPathHash, hir::ItemLocalId)>);
1107 fn to_stable_hash_key(&self,
1108 hcx: &StableHashingContext<'a>)
1110 let hir::TraitCandidate {
1115 let import_id = import_id.map(|node_id| hcx.node_to_hir_id(node_id))
1116 .map(|hir_id| (hcx.local_def_path_hash(hir_id.owner),
1118 (hcx.def_path_hash(def_id), import_id)
1122 impl_stable_hash_for!(struct hir::CodegenFnAttrs {
1131 impl<'hir> HashStable<StableHashingContext<'hir>> for hir::CodegenFnAttrFlags
1133 fn hash_stable<W: StableHasherResult>(&self,
1134 hcx: &mut StableHashingContext<'hir>,
1135 hasher: &mut StableHasher<W>) {
1136 self.bits().hash_stable(hcx, hasher);
1140 impl<'hir> HashStable<StableHashingContext<'hir>> for attr::InlineAttr {
1141 fn hash_stable<W: StableHasherResult>(&self,
1142 hcx: &mut StableHashingContext<'hir>,
1143 hasher: &mut StableHasher<W>) {
1144 mem::discriminant(self).hash_stable(hcx, hasher);
1148 impl_stable_hash_for!(struct hir::Freevar {