]> git.proxmox.com Git - rustc.git/blob - compiler/rustc_middle/src/ich/impls_hir.rs
New upstream version 1.52.0~beta.3+dfsg1
[rustc.git] / compiler / rustc_middle / src / ich / impls_hir.rs
1 //! This module contains `HashStable` implementations for various HIR data
2 //! types in no particular order.
3
4 use crate::ich::{NodeIdHashingMode, StableHashingContext};
5 use rustc_attr as attr;
6 use rustc_data_structures::fingerprint::Fingerprint;
7 use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
8 use rustc_hir as hir;
9 use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, CRATE_DEF_INDEX};
10 use rustc_hir::definitions::DefPathHash;
11 use smallvec::SmallVec;
12 use std::mem;
13
14 impl<'ctx> rustc_hir::HashStableContext for StableHashingContext<'ctx> {
15 #[inline]
16 fn hash_hir_id(&mut self, hir_id: hir::HirId, hasher: &mut StableHasher) {
17 let hcx = self;
18 match hcx.node_id_hashing_mode {
19 NodeIdHashingMode::Ignore => {
20 // Don't do anything.
21 }
22 NodeIdHashingMode::HashDefPath => {
23 let hir::HirId { owner, local_id } = hir_id;
24
25 hcx.local_def_path_hash(owner).hash_stable(hcx, hasher);
26 local_id.hash_stable(hcx, hasher);
27 }
28 }
29 }
30
31 fn hash_body_id(&mut self, id: hir::BodyId, hasher: &mut StableHasher) {
32 let hcx = self;
33 if hcx.hash_bodies() {
34 hcx.body_resolver.body(id).hash_stable(hcx, hasher);
35 }
36 }
37
38 fn hash_reference_to_item(&mut self, id: hir::HirId, hasher: &mut StableHasher) {
39 let hcx = self;
40
41 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
42 id.hash_stable(hcx, hasher);
43 })
44 }
45
46 fn hash_hir_mod(&mut self, module: &hir::Mod<'_>, hasher: &mut StableHasher) {
47 let hcx = self;
48 let hir::Mod { inner: ref inner_span, ref item_ids } = *module;
49
50 inner_span.hash_stable(hcx, hasher);
51
52 // Combining the `DefPathHash`s directly is faster than feeding them
53 // into the hasher. Because we use a commutative combine, we also don't
54 // have to sort the array.
55 let item_ids_hash = item_ids
56 .iter()
57 .map(|id| {
58 let def_path_hash = id.to_stable_hash_key(hcx);
59 def_path_hash.0
60 })
61 .fold(Fingerprint::ZERO, |a, b| a.combine_commutative(b));
62
63 item_ids.len().hash_stable(hcx, hasher);
64 item_ids_hash.hash_stable(hcx, hasher);
65 }
66
67 fn hash_hir_expr(&mut self, expr: &hir::Expr<'_>, hasher: &mut StableHasher) {
68 self.while_hashing_hir_bodies(true, |hcx| {
69 let hir::Expr { hir_id: _, ref span, ref kind } = *expr;
70
71 span.hash_stable(hcx, hasher);
72 kind.hash_stable(hcx, hasher);
73 })
74 }
75
76 fn hash_hir_ty(&mut self, ty: &hir::Ty<'_>, hasher: &mut StableHasher) {
77 self.while_hashing_hir_bodies(true, |hcx| {
78 let hir::Ty { hir_id: _, ref kind, ref span } = *ty;
79
80 kind.hash_stable(hcx, hasher);
81 span.hash_stable(hcx, hasher);
82 })
83 }
84
85 fn hash_hir_visibility_kind(
86 &mut self,
87 vis: &hir::VisibilityKind<'_>,
88 hasher: &mut StableHasher,
89 ) {
90 let hcx = self;
91 mem::discriminant(vis).hash_stable(hcx, hasher);
92 match *vis {
93 hir::VisibilityKind::Public | hir::VisibilityKind::Inherited => {
94 // No fields to hash.
95 }
96 hir::VisibilityKind::Crate(sugar) => {
97 sugar.hash_stable(hcx, hasher);
98 }
99 hir::VisibilityKind::Restricted { ref path, hir_id } => {
100 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
101 hir_id.hash_stable(hcx, hasher);
102 });
103 path.hash_stable(hcx, hasher);
104 }
105 }
106 }
107
108 fn hash_hir_item_like<F: FnOnce(&mut Self)>(&mut self, f: F) {
109 let prev_hash_node_ids = self.node_id_hashing_mode;
110 self.node_id_hashing_mode = NodeIdHashingMode::Ignore;
111
112 f(self);
113
114 self.node_id_hashing_mode = prev_hash_node_ids;
115 }
116
117 #[inline]
118 fn local_def_path_hash(&self, def_id: LocalDefId) -> DefPathHash {
119 self.local_def_path_hash(def_id)
120 }
121 }
122
123 impl<'a> ToStableHashKey<StableHashingContext<'a>> for DefId {
124 type KeyType = DefPathHash;
125
126 #[inline]
127 fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
128 hcx.def_path_hash(*self)
129 }
130 }
131
132 impl<'a> HashStable<StableHashingContext<'a>> for LocalDefId {
133 #[inline]
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);
136 }
137 }
138
139 impl<'a> ToStableHashKey<StableHashingContext<'a>> for LocalDefId {
140 type KeyType = DefPathHash;
141
142 #[inline]
143 fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
144 hcx.def_path_hash(self.to_def_id())
145 }
146 }
147
148 impl<'a> ToStableHashKey<StableHashingContext<'a>> for CrateNum {
149 type KeyType = DefPathHash;
150
151 #[inline]
152 fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
153 let def_id = DefId { krate: *self, index: CRATE_DEF_INDEX };
154 def_id.to_stable_hash_key(hcx)
155 }
156 }
157
158 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::ItemLocalId {
159 type KeyType = hir::ItemLocalId;
160
161 #[inline]
162 fn to_stable_hash_key(&self, _: &StableHashingContext<'a>) -> hir::ItemLocalId {
163 *self
164 }
165 }
166
167 impl<'a> HashStable<StableHashingContext<'a>> for hir::Body<'_> {
168 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
169 let hir::Body { params, value, generator_kind } = self;
170
171 hcx.with_node_id_hashing_mode(NodeIdHashingMode::Ignore, |hcx| {
172 params.hash_stable(hcx, hasher);
173 value.hash_stable(hcx, hasher);
174 generator_kind.hash_stable(hcx, hasher);
175 });
176 }
177 }
178
179 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::BodyId {
180 type KeyType = (DefPathHash, hir::ItemLocalId);
181
182 #[inline]
183 fn to_stable_hash_key(
184 &self,
185 hcx: &StableHashingContext<'a>,
186 ) -> (DefPathHash, hir::ItemLocalId) {
187 let hir::BodyId { hir_id } = *self;
188 hir_id.to_stable_hash_key(hcx)
189 }
190 }
191
192 impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitCandidate {
193 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
194 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
195 let hir::TraitCandidate { def_id, import_ids } = self;
196
197 def_id.hash_stable(hcx, hasher);
198 import_ids.hash_stable(hcx, hasher);
199 });
200 }
201 }
202
203 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::TraitCandidate {
204 type KeyType = (DefPathHash, SmallVec<[DefPathHash; 1]>);
205
206 fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> Self::KeyType {
207 let hir::TraitCandidate { def_id, import_ids } = self;
208
209 (
210 hcx.def_path_hash(*def_id),
211 import_ids.iter().map(|def_id| hcx.local_def_path_hash(*def_id)).collect(),
212 )
213 }
214 }
215
216 impl<'hir> HashStable<StableHashingContext<'hir>> for attr::InlineAttr {
217 fn hash_stable(&self, hcx: &mut StableHashingContext<'hir>, hasher: &mut StableHasher) {
218 mem::discriminant(self).hash_stable(hcx, hasher);
219 }
220 }
221
222 impl<'hir> HashStable<StableHashingContext<'hir>> for attr::InstructionSetAttr {
223 fn hash_stable(&self, hcx: &mut StableHashingContext<'hir>, hasher: &mut StableHasher) {
224 mem::discriminant(self).hash_stable(hcx, hasher);
225 }
226 }
227
228 impl<'hir> HashStable<StableHashingContext<'hir>> for attr::OptimizeAttr {
229 fn hash_stable(&self, hcx: &mut StableHashingContext<'hir>, hasher: &mut StableHasher) {
230 mem::discriminant(self).hash_stable(hcx, hasher);
231 }
232 }