1 //! This module contains `HashStable` implementations for various HIR data
2 //! types in no particular order.
4 use crate::hir::map::DefPathHash;
5 use crate::ich::{Fingerprint, NodeIdHashingMode, StableHashingContext};
6 use rustc_attr as attr;
7 use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
9 use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, CRATE_DEF_INDEX};
10 use smallvec::SmallVec;
13 impl<'ctx> rustc_hir::HashStableContext for StableHashingContext<'ctx> {
15 fn hash_def_id(&mut self, def_id: DefId, hasher: &mut StableHasher) {
17 hcx.def_path_hash(def_id).hash_stable(hcx, hasher);
21 fn hash_hir_id(&mut self, hir_id: hir::HirId, hasher: &mut StableHasher) {
23 match hcx.node_id_hashing_mode {
24 NodeIdHashingMode::Ignore => {
27 NodeIdHashingMode::HashDefPath => {
28 let hir::HirId { owner, local_id } = hir_id;
30 hcx.local_def_path_hash(owner).hash_stable(hcx, hasher);
31 local_id.hash_stable(hcx, hasher);
36 fn hash_body_id(&mut self, id: hir::BodyId, hasher: &mut StableHasher) {
38 if hcx.hash_bodies() {
39 hcx.body_resolver.body(id).hash_stable(hcx, hasher);
43 // The following implementations of HashStable for `ItemId`, `TraitItemId`, and
44 // `ImplItemId` deserve special attention. Normally we do not hash `NodeId`s within
45 // the HIR, since they just signify a HIR nodes own path. But `ItemId` et al
46 // are used when another item in the HIR is *referenced* and we certainly
47 // want to pick up on a reference changing its target, so we hash the NodeIds
50 fn hash_reference_to_item(&mut self, id: hir::HirId, hasher: &mut StableHasher) {
53 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
54 id.hash_stable(hcx, hasher);
58 fn hash_hir_mod(&mut self, module: &hir::Mod<'_>, hasher: &mut StableHasher) {
60 let hir::Mod { inner: ref inner_span, ref item_ids } = *module;
62 inner_span.hash_stable(hcx, hasher);
64 // Combining the `DefPathHash`s directly is faster than feeding them
65 // into the hasher. Because we use a commutative combine, we also don't
66 // have to sort the array.
67 let item_ids_hash = item_ids
70 let (def_path_hash, local_id) = id.id.to_stable_hash_key(hcx);
71 debug_assert_eq!(local_id, hir::ItemLocalId::from_u32(0));
74 .fold(Fingerprint::ZERO, |a, b| a.combine_commutative(b));
76 item_ids.len().hash_stable(hcx, hasher);
77 item_ids_hash.hash_stable(hcx, hasher);
80 fn hash_hir_expr(&mut self, expr: &hir::Expr<'_>, hasher: &mut StableHasher) {
81 self.while_hashing_hir_bodies(true, |hcx| {
82 let hir::Expr { hir_id: _, ref span, ref kind, ref attrs } = *expr;
84 span.hash_stable(hcx, hasher);
85 kind.hash_stable(hcx, hasher);
86 attrs.hash_stable(hcx, hasher);
90 fn hash_hir_ty(&mut self, ty: &hir::Ty<'_>, hasher: &mut StableHasher) {
91 self.while_hashing_hir_bodies(true, |hcx| {
92 let hir::Ty { hir_id: _, ref kind, ref span } = *ty;
94 kind.hash_stable(hcx, hasher);
95 span.hash_stable(hcx, hasher);
99 fn hash_hir_visibility_kind(
101 vis: &hir::VisibilityKind<'_>,
102 hasher: &mut StableHasher,
105 mem::discriminant(vis).hash_stable(hcx, hasher);
107 hir::VisibilityKind::Public | hir::VisibilityKind::Inherited => {
108 // No fields to hash.
110 hir::VisibilityKind::Crate(sugar) => {
111 sugar.hash_stable(hcx, hasher);
113 hir::VisibilityKind::Restricted { ref path, hir_id } => {
114 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
115 hir_id.hash_stable(hcx, hasher);
117 path.hash_stable(hcx, hasher);
123 impl<'a> ToStableHashKey<StableHashingContext<'a>> for DefId {
124 type KeyType = DefPathHash;
127 fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
128 hcx.def_path_hash(*self)
132 impl<'a> HashStable<StableHashingContext<'a>> for LocalDefId {
134 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
135 hcx.def_path_hash(self.to_def_id()).hash_stable(hcx, hasher);
139 impl<'a> ToStableHashKey<StableHashingContext<'a>> for LocalDefId {
140 type KeyType = DefPathHash;
143 fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
144 hcx.def_path_hash(self.to_def_id())
148 impl<'a> HashStable<StableHashingContext<'a>> for CrateNum {
150 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
151 hcx.def_path_hash(DefId { krate: *self, index: CRATE_DEF_INDEX }).hash_stable(hcx, hasher);
155 impl<'a> ToStableHashKey<StableHashingContext<'a>> for CrateNum {
156 type KeyType = DefPathHash;
159 fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
160 let def_id = DefId { krate: *self, index: CRATE_DEF_INDEX };
161 def_id.to_stable_hash_key(hcx)
165 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::ItemLocalId {
166 type KeyType = hir::ItemLocalId;
169 fn to_stable_hash_key(&self, _: &StableHashingContext<'a>) -> hir::ItemLocalId {
174 impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitItem<'_> {
175 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
176 let hir::TraitItem { hir_id: _, ident, ref attrs, ref generics, ref kind, span } = *self;
178 hcx.hash_hir_item_like(|hcx| {
179 ident.name.hash_stable(hcx, hasher);
180 attrs.hash_stable(hcx, hasher);
181 generics.hash_stable(hcx, hasher);
182 kind.hash_stable(hcx, hasher);
183 span.hash_stable(hcx, hasher);
188 impl<'a> HashStable<StableHashingContext<'a>> for hir::ImplItem<'_> {
189 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
201 hcx.hash_hir_item_like(|hcx| {
202 ident.name.hash_stable(hcx, hasher);
203 vis.hash_stable(hcx, hasher);
204 defaultness.hash_stable(hcx, hasher);
205 attrs.hash_stable(hcx, hasher);
206 generics.hash_stable(hcx, hasher);
207 kind.hash_stable(hcx, hasher);
208 span.hash_stable(hcx, hasher);
213 impl<'a> HashStable<StableHashingContext<'a>> for hir::Item<'_> {
214 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
215 let hir::Item { ident, ref attrs, hir_id: _, ref kind, ref vis, span } = *self;
217 hcx.hash_hir_item_like(|hcx| {
218 ident.name.hash_stable(hcx, hasher);
219 attrs.hash_stable(hcx, hasher);
220 kind.hash_stable(hcx, hasher);
221 vis.hash_stable(hcx, hasher);
222 span.hash_stable(hcx, hasher);
227 impl<'a> HashStable<StableHashingContext<'a>> for hir::Body<'_> {
228 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
229 let hir::Body { params, value, generator_kind } = self;
231 hcx.with_node_id_hashing_mode(NodeIdHashingMode::Ignore, |hcx| {
232 params.hash_stable(hcx, hasher);
233 value.hash_stable(hcx, hasher);
234 generator_kind.hash_stable(hcx, hasher);
239 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::BodyId {
240 type KeyType = (DefPathHash, hir::ItemLocalId);
243 fn to_stable_hash_key(
245 hcx: &StableHashingContext<'a>,
246 ) -> (DefPathHash, hir::ItemLocalId) {
247 let hir::BodyId { hir_id } = *self;
248 hir_id.to_stable_hash_key(hcx)
252 impl<'a> HashStable<StableHashingContext<'a>> for hir::def_id::DefIndex {
253 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
254 hcx.local_def_path_hash(*self).hash_stable(hcx, hasher);
258 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::def_id::DefIndex {
259 type KeyType = DefPathHash;
262 fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
263 hcx.local_def_path_hash(*self)
267 impl<'a> HashStable<StableHashingContext<'a>> for crate::middle::lang_items::LangItem {
268 fn hash_stable(&self, _: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
269 ::std::hash::Hash::hash(self, hasher);
273 impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitCandidate {
274 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
275 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
276 let hir::TraitCandidate { def_id, import_ids } = self;
278 def_id.hash_stable(hcx, hasher);
279 import_ids.hash_stable(hcx, hasher);
284 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::TraitCandidate {
285 type KeyType = (DefPathHash, SmallVec<[(DefPathHash, hir::ItemLocalId); 1]>);
287 fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> Self::KeyType {
288 let hir::TraitCandidate { def_id, import_ids } = self;
290 let import_keys = import_ids
292 .map(|node_id| hcx.node_to_hir_id(*node_id))
293 .map(|hir_id| (hcx.local_def_path_hash(hir_id.owner), hir_id.local_id))
295 (hcx.def_path_hash(*def_id), import_keys)
299 impl<'hir> HashStable<StableHashingContext<'hir>> for attr::InlineAttr {
300 fn hash_stable(&self, hcx: &mut StableHashingContext<'hir>, hasher: &mut StableHasher) {
301 mem::discriminant(self).hash_stable(hcx, hasher);
305 impl<'hir> HashStable<StableHashingContext<'hir>> for attr::OptimizeAttr {
306 fn hash_stable(&self, hcx: &mut StableHashingContext<'hir>, hasher: &mut StableHasher) {
307 mem::discriminant(self).hash_stable(hcx, hasher);