]> git.proxmox.com Git - rustc.git/blob - src/librustc/ich/impls_hir.rs
New upstream version 1.43.0+dfsg1
[rustc.git] / src / librustc / ich / impls_hir.rs
1 //! This module contains `HashStable` implementations for various HIR data
2 //! types in no particular order.
3
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};
8 use rustc_hir as hir;
9 use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, CRATE_DEF_INDEX};
10 use smallvec::SmallVec;
11 use std::mem;
12
13 impl<'ctx> rustc_hir::HashStableContext for StableHashingContext<'ctx> {
14 #[inline]
15 fn hash_hir_id(&mut self, hir_id: hir::HirId, hasher: &mut StableHasher) {
16 let hcx = self;
17 match hcx.node_id_hashing_mode {
18 NodeIdHashingMode::Ignore => {
19 // Don't do anything.
20 }
21 NodeIdHashingMode::HashDefPath => {
22 let hir::HirId { owner, local_id } = hir_id;
23
24 hcx.local_def_path_hash(owner).hash_stable(hcx, hasher);
25 local_id.hash_stable(hcx, hasher);
26 }
27 }
28 }
29
30 fn hash_body_id(&mut self, id: hir::BodyId, hasher: &mut StableHasher) {
31 let hcx = self;
32 if hcx.hash_bodies() {
33 hcx.body_resolver.body(id).hash_stable(hcx, hasher);
34 }
35 }
36
37 fn hash_reference_to_item(&mut self, id: hir::HirId, hasher: &mut StableHasher) {
38 let hcx = self;
39
40 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
41 id.hash_stable(hcx, hasher);
42 })
43 }
44
45 fn hash_hir_mod(&mut self, module: &hir::Mod<'_>, hasher: &mut StableHasher) {
46 let hcx = self;
47 let hir::Mod { inner: ref inner_span, ref item_ids } = *module;
48
49 inner_span.hash_stable(hcx, hasher);
50
51 // Combining the `DefPathHash`s directly is faster than feeding them
52 // into the hasher. Because we use a commutative combine, we also don't
53 // have to sort the array.
54 let item_ids_hash = item_ids
55 .iter()
56 .map(|id| {
57 let (def_path_hash, local_id) = id.id.to_stable_hash_key(hcx);
58 debug_assert_eq!(local_id, hir::ItemLocalId::from_u32(0));
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, ref attrs } = *expr;
70
71 span.hash_stable(hcx, hasher);
72 kind.hash_stable(hcx, hasher);
73 attrs.hash_stable(hcx, hasher);
74 })
75 }
76
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;
80
81 kind.hash_stable(hcx, hasher);
82 span.hash_stable(hcx, hasher);
83 })
84 }
85
86 fn hash_hir_visibility_kind(
87 &mut self,
88 vis: &hir::VisibilityKind<'_>,
89 hasher: &mut StableHasher,
90 ) {
91 let hcx = self;
92 mem::discriminant(vis).hash_stable(hcx, hasher);
93 match *vis {
94 hir::VisibilityKind::Public | hir::VisibilityKind::Inherited => {
95 // No fields to hash.
96 }
97 hir::VisibilityKind::Crate(sugar) => {
98 sugar.hash_stable(hcx, hasher);
99 }
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);
103 });
104 path.hash_stable(hcx, hasher);
105 }
106 }
107 }
108 }
109
110 impl<'a> ToStableHashKey<StableHashingContext<'a>> for DefId {
111 type KeyType = DefPathHash;
112
113 #[inline]
114 fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
115 hcx.def_path_hash(*self)
116 }
117 }
118
119 impl<'a> HashStable<StableHashingContext<'a>> for LocalDefId {
120 #[inline]
121 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
122 hcx.def_path_hash(self.to_def_id()).hash_stable(hcx, hasher);
123 }
124 }
125
126 impl<'a> ToStableHashKey<StableHashingContext<'a>> for LocalDefId {
127 type KeyType = DefPathHash;
128
129 #[inline]
130 fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
131 hcx.def_path_hash(self.to_def_id())
132 }
133 }
134
135 impl<'a> HashStable<StableHashingContext<'a>> for CrateNum {
136 #[inline]
137 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
138 hcx.def_path_hash(DefId { krate: *self, index: CRATE_DEF_INDEX }).hash_stable(hcx, hasher);
139 }
140 }
141
142 impl<'a> ToStableHashKey<StableHashingContext<'a>> for CrateNum {
143 type KeyType = DefPathHash;
144
145 #[inline]
146 fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
147 let def_id = DefId { krate: *self, index: CRATE_DEF_INDEX };
148 def_id.to_stable_hash_key(hcx)
149 }
150 }
151
152 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::ItemLocalId {
153 type KeyType = hir::ItemLocalId;
154
155 #[inline]
156 fn to_stable_hash_key(&self, _: &StableHashingContext<'a>) -> hir::ItemLocalId {
157 *self
158 }
159 }
160
161 impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitItem<'_> {
162 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
163 let hir::TraitItem { hir_id: _, ident, ref attrs, ref generics, ref kind, span } = *self;
164
165 hcx.hash_hir_item_like(|hcx| {
166 ident.name.hash_stable(hcx, hasher);
167 attrs.hash_stable(hcx, hasher);
168 generics.hash_stable(hcx, hasher);
169 kind.hash_stable(hcx, hasher);
170 span.hash_stable(hcx, hasher);
171 });
172 }
173 }
174
175 impl<'a> HashStable<StableHashingContext<'a>> for hir::ImplItem<'_> {
176 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
177 let hir::ImplItem {
178 hir_id: _,
179 ident,
180 ref vis,
181 defaultness,
182 ref attrs,
183 ref generics,
184 ref kind,
185 span,
186 } = *self;
187
188 hcx.hash_hir_item_like(|hcx| {
189 ident.name.hash_stable(hcx, hasher);
190 vis.hash_stable(hcx, hasher);
191 defaultness.hash_stable(hcx, hasher);
192 attrs.hash_stable(hcx, hasher);
193 generics.hash_stable(hcx, hasher);
194 kind.hash_stable(hcx, hasher);
195 span.hash_stable(hcx, hasher);
196 });
197 }
198 }
199
200 impl<'a> HashStable<StableHashingContext<'a>> for hir::Item<'_> {
201 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
202 let hir::Item { ident, ref attrs, hir_id: _, ref kind, ref vis, span } = *self;
203
204 hcx.hash_hir_item_like(|hcx| {
205 ident.name.hash_stable(hcx, hasher);
206 attrs.hash_stable(hcx, hasher);
207 kind.hash_stable(hcx, hasher);
208 vis.hash_stable(hcx, hasher);
209 span.hash_stable(hcx, hasher);
210 });
211 }
212 }
213
214 impl<'a> HashStable<StableHashingContext<'a>> for hir::Body<'_> {
215 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
216 let hir::Body { params, value, generator_kind } = self;
217
218 hcx.with_node_id_hashing_mode(NodeIdHashingMode::Ignore, |hcx| {
219 params.hash_stable(hcx, hasher);
220 value.hash_stable(hcx, hasher);
221 generator_kind.hash_stable(hcx, hasher);
222 });
223 }
224 }
225
226 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::BodyId {
227 type KeyType = (DefPathHash, hir::ItemLocalId);
228
229 #[inline]
230 fn to_stable_hash_key(
231 &self,
232 hcx: &StableHashingContext<'a>,
233 ) -> (DefPathHash, hir::ItemLocalId) {
234 let hir::BodyId { hir_id } = *self;
235 hir_id.to_stable_hash_key(hcx)
236 }
237 }
238
239 impl<'a> HashStable<StableHashingContext<'a>> for hir::def_id::DefIndex {
240 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
241 hcx.local_def_path_hash(*self).hash_stable(hcx, hasher);
242 }
243 }
244
245 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::def_id::DefIndex {
246 type KeyType = DefPathHash;
247
248 #[inline]
249 fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
250 hcx.local_def_path_hash(*self)
251 }
252 }
253
254 impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitCandidate {
255 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
256 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
257 let hir::TraitCandidate { def_id, import_ids } = self;
258
259 def_id.hash_stable(hcx, hasher);
260 import_ids.hash_stable(hcx, hasher);
261 });
262 }
263 }
264
265 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::TraitCandidate {
266 type KeyType = (DefPathHash, SmallVec<[(DefPathHash, hir::ItemLocalId); 1]>);
267
268 fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> Self::KeyType {
269 let hir::TraitCandidate { def_id, import_ids } = self;
270
271 let import_keys = import_ids
272 .iter()
273 .map(|hir_id| (hcx.local_def_path_hash(hir_id.owner), hir_id.local_id))
274 .collect();
275 (hcx.def_path_hash(*def_id), import_keys)
276 }
277 }
278
279 impl<'hir> HashStable<StableHashingContext<'hir>> for attr::InlineAttr {
280 fn hash_stable(&self, hcx: &mut StableHashingContext<'hir>, hasher: &mut StableHasher) {
281 mem::discriminant(self).hash_stable(hcx, hasher);
282 }
283 }
284
285 impl<'hir> HashStable<StableHashingContext<'hir>> for attr::OptimizeAttr {
286 fn hash_stable(&self, hcx: &mut StableHashingContext<'hir>, hasher: &mut StableHasher) {
287 mem::discriminant(self).hash_stable(hcx, hasher);
288 }
289 }