]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_hir/src/stable_hash_impls.rs
Rollup merge of #95885 - gimbles:patch-1, r=Mark-Simulacrum
[rust.git] / compiler / rustc_hir / src / stable_hash_impls.rs
1 use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
2
3 use crate::hir::{
4     AttributeMap, BodyId, Crate, Expr, ForeignItemId, ImplItemId, ItemId, OwnerNodes, TraitItemId,
5     Ty,
6 };
7 use crate::hir_id::{HirId, ItemLocalId};
8 use rustc_span::def_id::DefPathHash;
9
10 /// Requirements for a `StableHashingContext` to be used in this crate.
11 /// This is a hack to allow using the `HashStable_Generic` derive macro
12 /// instead of implementing everything in `rustc_middle`.
13 pub trait HashStableContext:
14     rustc_ast::HashStableContext + rustc_target::HashStableContext
15 {
16     fn hash_body_id(&mut self, _: BodyId, hasher: &mut StableHasher);
17     fn hash_hir_expr(&mut self, _: &Expr<'_>, hasher: &mut StableHasher);
18     fn hash_hir_ty(&mut self, _: &Ty<'_>, hasher: &mut StableHasher);
19 }
20
21 impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for HirId {
22     type KeyType = (DefPathHash, ItemLocalId);
23
24     #[inline]
25     fn to_stable_hash_key(&self, hcx: &HirCtx) -> (DefPathHash, ItemLocalId) {
26         let def_path_hash = self.owner.to_stable_hash_key(hcx);
27         (def_path_hash, self.local_id)
28     }
29 }
30
31 impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for ItemLocalId {
32     type KeyType = ItemLocalId;
33
34     #[inline]
35     fn to_stable_hash_key(&self, _: &HirCtx) -> ItemLocalId {
36         *self
37     }
38 }
39
40 impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for BodyId {
41     type KeyType = (DefPathHash, ItemLocalId);
42
43     #[inline]
44     fn to_stable_hash_key(&self, hcx: &HirCtx) -> (DefPathHash, ItemLocalId) {
45         let BodyId { hir_id } = *self;
46         hir_id.to_stable_hash_key(hcx)
47     }
48 }
49
50 impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for ItemId {
51     type KeyType = DefPathHash;
52
53     #[inline]
54     fn to_stable_hash_key(&self, hcx: &HirCtx) -> DefPathHash {
55         self.def_id.to_stable_hash_key(hcx)
56     }
57 }
58
59 impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for TraitItemId {
60     type KeyType = DefPathHash;
61
62     #[inline]
63     fn to_stable_hash_key(&self, hcx: &HirCtx) -> DefPathHash {
64         self.def_id.to_stable_hash_key(hcx)
65     }
66 }
67
68 impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for ImplItemId {
69     type KeyType = DefPathHash;
70
71     #[inline]
72     fn to_stable_hash_key(&self, hcx: &HirCtx) -> DefPathHash {
73         self.def_id.to_stable_hash_key(hcx)
74     }
75 }
76
77 impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for ForeignItemId {
78     type KeyType = DefPathHash;
79
80     #[inline]
81     fn to_stable_hash_key(&self, hcx: &HirCtx) -> DefPathHash {
82         self.def_id.to_stable_hash_key(hcx)
83     }
84 }
85
86 impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for BodyId {
87     fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
88         hcx.hash_body_id(*self, hasher)
89     }
90 }
91
92 // The following implementations of HashStable for `ItemId`, `TraitItemId`, and
93 // `ImplItemId` deserve special attention. Normally we do not hash `NodeId`s within
94 // the HIR, since they just signify a HIR nodes own path. But `ItemId` et al
95 // are used when another item in the HIR is *referenced* and we certainly
96 // want to pick up on a reference changing its target, so we hash the NodeIds
97 // in "DefPath Mode".
98
99 impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for Expr<'_> {
100     fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
101         hcx.hash_hir_expr(self, hasher)
102     }
103 }
104
105 impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for Ty<'_> {
106     fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
107         hcx.hash_hir_ty(self, hasher)
108     }
109 }
110
111 impl<'tcx, HirCtx: crate::HashStableContext> HashStable<HirCtx> for OwnerNodes<'tcx> {
112     fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
113         // We ignore the `nodes` and `bodies` fields since these refer to information included in
114         // `hash` which is hashed in the collector and used for the crate hash.
115         // `local_id_to_def_id` is also ignored because is dependent on the body, then just hashing
116         // the body satisfies the condition of two nodes being different have different
117         // `hash_stable` results.
118         let OwnerNodes {
119             hash_including_bodies,
120             hash_without_bodies: _,
121             nodes: _,
122             bodies: _,
123             local_id_to_def_id: _,
124         } = *self;
125         hash_including_bodies.hash_stable(hcx, hasher);
126     }
127 }
128
129 impl<'tcx, HirCtx: crate::HashStableContext> HashStable<HirCtx> for AttributeMap<'tcx> {
130     fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
131         // We ignore the `map` since it refers to information included in `hash` which is hashed in
132         // the collector and used for the crate hash.
133         let AttributeMap { hash, map: _ } = *self;
134         hash.hash_stable(hcx, hasher);
135     }
136 }
137
138 impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for Crate<'_> {
139     fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
140         let Crate { owners: _, hir_hash } = self;
141         hir_hash.hash_stable(hcx, hasher)
142     }
143 }