1 //! This module contains `HashStable` implementations for various HIR data
2 //! types in no particular order.
4 use crate::ich::{NodeIdHashingMode, StableHashingContext};
5 use rustc_data_structures::fingerprint::Fingerprint;
6 use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
8 use rustc_hir::definitions::DefPathHash;
9 use smallvec::SmallVec;
12 impl<'ctx> rustc_hir::HashStableContext for StableHashingContext<'ctx> {
14 fn hash_hir_id(&mut self, hir_id: hir::HirId, hasher: &mut StableHasher) {
16 match hcx.node_id_hashing_mode {
17 NodeIdHashingMode::Ignore => {
20 NodeIdHashingMode::HashDefPath => {
21 let hir::HirId { owner, local_id } = hir_id;
23 hcx.local_def_path_hash(owner).hash_stable(hcx, hasher);
24 local_id.hash_stable(hcx, hasher);
30 fn hash_body_id(&mut self, id: hir::BodyId, hasher: &mut StableHasher) {
32 if hcx.hash_bodies() {
33 hcx.body_resolver.body(id).hash_stable(hcx, hasher);
38 fn hash_reference_to_item(&mut self, id: hir::HirId, hasher: &mut StableHasher) {
41 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
42 id.hash_stable(hcx, hasher);
47 fn hash_hir_mod(&mut self, module: &hir::Mod<'_>, hasher: &mut StableHasher) {
49 let hir::Mod { inner: ref inner_span, ref item_ids } = *module;
51 inner_span.hash_stable(hcx, hasher);
53 // Combining the `DefPathHash`s directly is faster than feeding them
54 // into the hasher. Because we use a commutative combine, we also don't
55 // have to sort the array.
56 let item_ids_hash = item_ids
59 let def_path_hash = id.to_stable_hash_key(hcx);
62 .fold(Fingerprint::ZERO, |a, b| a.combine_commutative(b));
64 item_ids.len().hash_stable(hcx, hasher);
65 item_ids_hash.hash_stable(hcx, hasher);
68 fn hash_hir_expr(&mut self, expr: &hir::Expr<'_>, hasher: &mut StableHasher) {
69 self.while_hashing_hir_bodies(true, |hcx| {
70 let hir::Expr { hir_id: _, ref span, ref kind } = *expr;
72 span.hash_stable(hcx, hasher);
73 kind.hash_stable(hcx, hasher);
77 fn hash_hir_ty(&mut self, ty: &hir::Ty<'_>, hasher: &mut StableHasher) {
78 self.while_hashing_hir_bodies(true, |hcx| {
79 let hir::Ty { hir_id: _, ref kind, ref span } = *ty;
81 kind.hash_stable(hcx, hasher);
82 span.hash_stable(hcx, hasher);
86 fn hash_hir_visibility_kind(
88 vis: &hir::VisibilityKind<'_>,
89 hasher: &mut StableHasher,
92 mem::discriminant(vis).hash_stable(hcx, hasher);
94 hir::VisibilityKind::Public | hir::VisibilityKind::Inherited => {
97 hir::VisibilityKind::Crate(sugar) => {
98 sugar.hash_stable(hcx, hasher);
100 hir::VisibilityKind::Restricted { ref path, hir_id } => {
101 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
102 hir_id.hash_stable(hcx, hasher);
104 path.hash_stable(hcx, hasher);
110 fn hash_hir_item_like<F: FnOnce(&mut Self)>(&mut self, f: F) {
111 let prev_hash_node_ids = self.node_id_hashing_mode;
112 self.node_id_hashing_mode = NodeIdHashingMode::Ignore;
116 self.node_id_hashing_mode = prev_hash_node_ids;
120 impl<'a> HashStable<StableHashingContext<'a>> for hir::Body<'_> {
122 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
123 let hir::Body { params, value, generator_kind } = self;
125 hcx.with_node_id_hashing_mode(NodeIdHashingMode::Ignore, |hcx| {
126 params.hash_stable(hcx, hasher);
127 value.hash_stable(hcx, hasher);
128 generator_kind.hash_stable(hcx, hasher);
133 impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitCandidate {
134 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
135 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
136 let hir::TraitCandidate { def_id, import_ids } = self;
138 def_id.hash_stable(hcx, hasher);
139 import_ids.hash_stable(hcx, hasher);
144 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::TraitCandidate {
145 type KeyType = (DefPathHash, SmallVec<[DefPathHash; 1]>);
147 fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> Self::KeyType {
148 let hir::TraitCandidate { def_id, import_ids } = self;
151 hcx.def_path_hash(*def_id),
152 import_ids.iter().map(|def_id| hcx.local_def_path_hash(*def_id)).collect(),