]>
Commit | Line | Data |
---|---|---|
cc61c64b XL |
1 | //! This module contains `HashStable` implementations for various data types |
2 | //! from libsyntax in no particular order. | |
3 | ||
9fa01778 | 4 | use crate::ich::StableHashingContext; |
cc61c64b XL |
5 | |
6 | use std::hash as std_hash; | |
7 | use std::mem; | |
8 | ||
9 | use syntax::ast; | |
0531ce1d | 10 | use syntax::feature_gate; |
cc61c64b | 11 | use syntax::parse::token; |
e1599b0c | 12 | use syntax::symbol::InternedString; |
cc61c64b | 13 | use syntax::tokenstream; |
b7449926 | 14 | use syntax_pos::SourceFile; |
7cac9316 | 15 | |
9fa01778 | 16 | use crate::hir::def_id::{DefId, CrateNum, CRATE_DEF_INDEX}; |
cc61c64b | 17 | |
b7449926 | 18 | use smallvec::SmallVec; |
ea8adc8c XL |
19 | use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey, |
20 | StableHasher, StableHasherResult}; | |
cc61c64b | 21 | |
0531ce1d | 22 | impl<'a> HashStable<StableHashingContext<'a>> for InternedString { |
cc61c64b XL |
23 | #[inline] |
24 | fn hash_stable<W: StableHasherResult>(&self, | |
0531ce1d | 25 | hcx: &mut StableHashingContext<'a>, |
cc61c64b | 26 | hasher: &mut StableHasher<W>) { |
83c7162d | 27 | self.with(|s| s.hash_stable(hcx, hasher)) |
cc61c64b XL |
28 | } |
29 | } | |
30 | ||
0531ce1d | 31 | impl<'a> ToStableHashKey<StableHashingContext<'a>> for InternedString { |
ea8adc8c XL |
32 | type KeyType = InternedString; |
33 | ||
34 | #[inline] | |
35 | fn to_stable_hash_key(&self, | |
0531ce1d | 36 | _: &StableHashingContext<'a>) |
ea8adc8c XL |
37 | -> InternedString { |
38 | self.clone() | |
39 | } | |
40 | } | |
41 | ||
0531ce1d | 42 | impl<'a> HashStable<StableHashingContext<'a>> for ast::Name { |
cc61c64b XL |
43 | #[inline] |
44 | fn hash_stable<W: StableHasherResult>(&self, | |
0531ce1d | 45 | hcx: &mut StableHashingContext<'a>, |
cc61c64b XL |
46 | hasher: &mut StableHasher<W>) { |
47 | self.as_str().hash_stable(hcx, hasher); | |
48 | } | |
49 | } | |
50 | ||
0531ce1d | 51 | impl<'a> ToStableHashKey<StableHashingContext<'a>> for ast::Name { |
ea8adc8c XL |
52 | type KeyType = InternedString; |
53 | ||
54 | #[inline] | |
55 | fn to_stable_hash_key(&self, | |
0531ce1d | 56 | _: &StableHashingContext<'a>) |
ea8adc8c | 57 | -> InternedString { |
83c7162d | 58 | self.as_interned_str() |
ea8adc8c XL |
59 | } |
60 | } | |
61 | ||
cc61c64b XL |
62 | impl_stable_hash_for!(enum ::syntax::ast::AsmDialect { |
63 | Att, | |
64 | Intel | |
65 | }); | |
66 | ||
67 | impl_stable_hash_for!(enum ::syntax::ext::base::MacroKind { | |
68 | Bang, | |
69 | Attr, | |
8faf50e0 | 70 | Derive, |
cc61c64b XL |
71 | }); |
72 | ||
73 | ||
83c7162d | 74 | impl_stable_hash_for!(enum ::rustc_target::spec::abi::Abi { |
cc61c64b XL |
75 | Cdecl, |
76 | Stdcall, | |
77 | Fastcall, | |
78 | Vectorcall, | |
7cac9316 | 79 | Thiscall, |
cc61c64b XL |
80 | Aapcs, |
81 | Win64, | |
82 | SysV64, | |
83 | PtxKernel, | |
84 | Msp430Interrupt, | |
85 | X86Interrupt, | |
8faf50e0 | 86 | AmdGpuKernel, |
cc61c64b XL |
87 | Rust, |
88 | C, | |
89 | System, | |
90 | RustIntrinsic, | |
91 | RustCall, | |
92 | PlatformIntrinsic, | |
93 | Unadjusted | |
94 | }); | |
95 | ||
96 | impl_stable_hash_for!(struct ::syntax::attr::Deprecation { since, note }); | |
ea8adc8c XL |
97 | impl_stable_hash_for!(struct ::syntax::attr::Stability { |
98 | level, | |
99 | feature, | |
100 | rustc_depr, | |
0bf4aa26 | 101 | promotable, |
48663c56 | 102 | allow_const_fn_ptr, |
b7449926 | 103 | const_stability |
ea8adc8c | 104 | }); |
cc61c64b | 105 | |
0731742a XL |
106 | impl_stable_hash_for!(enum ::syntax::edition::Edition { |
107 | Edition2015, | |
108 | Edition2018, | |
109 | }); | |
94b46f34 | 110 | |
0531ce1d | 111 | impl<'a> HashStable<StableHashingContext<'a>> |
041b39d2 | 112 | for ::syntax::attr::StabilityLevel { |
cc61c64b | 113 | fn hash_stable<W: StableHasherResult>(&self, |
0531ce1d | 114 | hcx: &mut StableHashingContext<'a>, |
cc61c64b XL |
115 | hasher: &mut StableHasher<W>) { |
116 | mem::discriminant(self).hash_stable(hcx, hasher); | |
117 | match *self { | |
416331ca | 118 | ::syntax::attr::StabilityLevel::Unstable { ref reason, ref issue, ref is_soft } => { |
cc61c64b XL |
119 | reason.hash_stable(hcx, hasher); |
120 | issue.hash_stable(hcx, hasher); | |
416331ca | 121 | is_soft.hash_stable(hcx, hasher); |
cc61c64b XL |
122 | } |
123 | ::syntax::attr::StabilityLevel::Stable { ref since } => { | |
124 | since.hash_stable(hcx, hasher); | |
125 | } | |
126 | } | |
127 | } | |
128 | } | |
129 | ||
9fa01778 | 130 | impl_stable_hash_for!(struct ::syntax::attr::RustcDeprecation { since, reason, suggestion }); |
cc61c64b XL |
131 | |
132 | ||
133 | impl_stable_hash_for!(enum ::syntax::attr::IntType { | |
134 | SignedInt(int_ty), | |
135 | UnsignedInt(uint_ty) | |
136 | }); | |
137 | ||
138 | impl_stable_hash_for!(enum ::syntax::ast::LitIntType { | |
139 | Signed(int_ty), | |
140 | Unsigned(int_ty), | |
141 | Unsuffixed | |
142 | }); | |
143 | ||
48663c56 XL |
144 | impl_stable_hash_for!(struct ::syntax::ast::Lit { |
145 | node, | |
146 | token, | |
48663c56 XL |
147 | span |
148 | }); | |
149 | ||
cc61c64b XL |
150 | impl_stable_hash_for!(enum ::syntax::ast::LitKind { |
151 | Str(value, style), | |
152 | ByteStr(value), | |
153 | Byte(value), | |
154 | Char(value), | |
155 | Int(value, lit_int_type), | |
156 | Float(value, float_ty), | |
157 | FloatUnsuffixed(value), | |
dc9dc135 XL |
158 | Bool(value), |
159 | Err(value) | |
cc61c64b XL |
160 | }); |
161 | ||
48663c56 XL |
162 | impl_stable_hash_for_spanned!(::syntax::ast::LitKind); |
163 | ||
2c00a5a8 XL |
164 | impl_stable_hash_for!(enum ::syntax::ast::IntTy { Isize, I8, I16, I32, I64, I128 }); |
165 | impl_stable_hash_for!(enum ::syntax::ast::UintTy { Usize, U8, U16, U32, U64, U128 }); | |
cc61c64b XL |
166 | impl_stable_hash_for!(enum ::syntax::ast::FloatTy { F32, F64 }); |
167 | impl_stable_hash_for!(enum ::syntax::ast::Unsafety { Unsafe, Normal }); | |
168 | impl_stable_hash_for!(enum ::syntax::ast::Constness { Const, NotConst }); | |
169 | impl_stable_hash_for!(enum ::syntax::ast::Defaultness { Default, Final }); | |
83c7162d | 170 | impl_stable_hash_for!(struct ::syntax::ast::Lifetime { id, ident }); |
cc61c64b XL |
171 | impl_stable_hash_for!(enum ::syntax::ast::StrStyle { Cooked, Raw(pounds) }); |
172 | impl_stable_hash_for!(enum ::syntax::ast::AttrStyle { Outer, Inner }); | |
173 | ||
0531ce1d | 174 | impl<'a> HashStable<StableHashingContext<'a>> for [ast::Attribute] { |
cc61c64b | 175 | fn hash_stable<W: StableHasherResult>(&self, |
0531ce1d | 176 | hcx: &mut StableHashingContext<'a>, |
cc61c64b | 177 | hasher: &mut StableHasher<W>) { |
ea8adc8c XL |
178 | if self.len() == 0 { |
179 | self.len().hash_stable(hcx, hasher); | |
180 | return | |
181 | } | |
182 | ||
cc61c64b | 183 | // Some attributes are always ignored during hashing. |
b7449926 | 184 | let filtered: SmallVec<[&ast::Attribute; 8]> = self |
cc61c64b XL |
185 | .iter() |
186 | .filter(|attr| { | |
9fa01778 XL |
187 | !attr.is_sugared_doc && |
188 | !attr.ident().map_or(false, |ident| hcx.is_ignored_attr(ident.name)) | |
cc61c64b XL |
189 | }) |
190 | .collect(); | |
191 | ||
192 | filtered.len().hash_stable(hcx, hasher); | |
193 | for attr in filtered { | |
194 | attr.hash_stable(hcx, hasher); | |
195 | } | |
196 | } | |
197 | } | |
198 | ||
83c7162d XL |
199 | impl<'a> HashStable<StableHashingContext<'a>> for ast::Path { |
200 | fn hash_stable<W: StableHasherResult>(&self, | |
201 | hcx: &mut StableHashingContext<'a>, | |
202 | hasher: &mut StableHasher<W>) { | |
203 | self.segments.len().hash_stable(hcx, hasher); | |
204 | for segment in &self.segments { | |
205 | segment.ident.name.hash_stable(hcx, hasher); | |
206 | } | |
207 | } | |
208 | } | |
209 | ||
0531ce1d | 210 | impl<'a> HashStable<StableHashingContext<'a>> for ast::Attribute { |
cc61c64b | 211 | fn hash_stable<W: StableHasherResult>(&self, |
0531ce1d | 212 | hcx: &mut StableHashingContext<'a>, |
cc61c64b XL |
213 | hasher: &mut StableHasher<W>) { |
214 | // Make sure that these have been filtered out. | |
9fa01778 | 215 | debug_assert!(!self.ident().map_or(false, |ident| hcx.is_ignored_attr(ident.name))); |
cc61c64b XL |
216 | debug_assert!(!self.is_sugared_doc); |
217 | ||
218 | let ast::Attribute { | |
219 | id: _, | |
220 | style, | |
221 | ref path, | |
222 | ref tokens, | |
223 | is_sugared_doc: _, | |
224 | span, | |
225 | } = *self; | |
226 | ||
227 | style.hash_stable(hcx, hasher); | |
83c7162d | 228 | path.hash_stable(hcx, hasher); |
cc61c64b XL |
229 | for tt in tokens.trees() { |
230 | tt.hash_stable(hcx, hasher); | |
231 | } | |
232 | span.hash_stable(hcx, hasher); | |
233 | } | |
234 | } | |
235 | ||
0531ce1d | 236 | impl<'a> HashStable<StableHashingContext<'a>> |
041b39d2 | 237 | for tokenstream::TokenTree { |
cc61c64b | 238 | fn hash_stable<W: StableHasherResult>(&self, |
0531ce1d | 239 | hcx: &mut StableHashingContext<'a>, |
cc61c64b XL |
240 | hasher: &mut StableHasher<W>) { |
241 | mem::discriminant(self).hash_stable(hcx, hasher); | |
242 | match *self { | |
dc9dc135 XL |
243 | tokenstream::TokenTree::Token(ref token) => { |
244 | token.hash_stable(hcx, hasher); | |
cc61c64b | 245 | } |
0731742a | 246 | tokenstream::TokenTree::Delimited(span, delim, ref tts) => { |
cc61c64b | 247 | span.hash_stable(hcx, hasher); |
0731742a | 248 | std_hash::Hash::hash(&delim, hasher); |
9fa01778 | 249 | for sub_tt in tts.trees() { |
cc61c64b XL |
250 | sub_tt.hash_stable(hcx, hasher); |
251 | } | |
252 | } | |
253 | } | |
254 | } | |
255 | } | |
256 | ||
0531ce1d | 257 | impl<'a> HashStable<StableHashingContext<'a>> |
041b39d2 | 258 | for tokenstream::TokenStream { |
cc61c64b | 259 | fn hash_stable<W: StableHasherResult>(&self, |
0531ce1d | 260 | hcx: &mut StableHashingContext<'a>, |
cc61c64b XL |
261 | hasher: &mut StableHasher<W>) { |
262 | for sub_tt in self.trees() { | |
263 | sub_tt.hash_stable(hcx, hasher); | |
264 | } | |
265 | } | |
266 | } | |
267 | ||
dc9dc135 XL |
268 | impl_stable_hash_for!(enum token::LitKind { |
269 | Bool, | |
270 | Byte, | |
271 | Char, | |
272 | Integer, | |
273 | Float, | |
274 | Str, | |
275 | ByteStr, | |
276 | StrRaw(n), | |
277 | ByteStrRaw(n), | |
278 | Err | |
48663c56 XL |
279 | }); |
280 | ||
dc9dc135 XL |
281 | impl_stable_hash_for!(struct token::Lit { |
282 | kind, | |
283 | symbol, | |
284 | suffix | |
285 | }); | |
cc61c64b | 286 | |
dc9dc135 XL |
287 | impl<'a> HashStable<StableHashingContext<'a>> for token::TokenKind { |
288 | fn hash_stable<W: StableHasherResult>(&self, | |
289 | hcx: &mut StableHashingContext<'a>, | |
290 | hasher: &mut StableHasher<W>) { | |
291 | mem::discriminant(self).hash_stable(hcx, hasher); | |
292 | match *self { | |
293 | token::Eq | | |
294 | token::Lt | | |
295 | token::Le | | |
296 | token::EqEq | | |
297 | token::Ne | | |
298 | token::Ge | | |
299 | token::Gt | | |
300 | token::AndAnd | | |
301 | token::OrOr | | |
302 | token::Not | | |
303 | token::Tilde | | |
304 | token::At | | |
305 | token::Dot | | |
306 | token::DotDot | | |
307 | token::DotDotDot | | |
308 | token::DotDotEq | | |
309 | token::Comma | | |
310 | token::Semi | | |
311 | token::Colon | | |
312 | token::ModSep | | |
313 | token::RArrow | | |
314 | token::LArrow | | |
315 | token::FatArrow | | |
316 | token::Pound | | |
317 | token::Dollar | | |
318 | token::Question | | |
319 | token::SingleQuote | | |
320 | token::Whitespace | | |
321 | token::Comment | | |
322 | token::Eof => {} | |
323 | ||
324 | token::BinOp(bin_op_token) | | |
325 | token::BinOpEq(bin_op_token) => { | |
326 | std_hash::Hash::hash(&bin_op_token, hasher); | |
327 | } | |
cc61c64b | 328 | |
dc9dc135 XL |
329 | token::OpenDelim(delim_token) | |
330 | token::CloseDelim(delim_token) => { | |
331 | std_hash::Hash::hash(&delim_token, hasher); | |
332 | } | |
333 | token::Literal(lit) => lit.hash_stable(hcx, hasher), | |
cc61c64b | 334 | |
dc9dc135 XL |
335 | token::Ident(name, is_raw) => { |
336 | name.hash_stable(hcx, hasher); | |
337 | is_raw.hash_stable(hcx, hasher); | |
338 | } | |
339 | token::Lifetime(name) => name.hash_stable(hcx, hasher), | |
cc61c64b | 340 | |
dc9dc135 XL |
341 | token::Interpolated(_) => { |
342 | bug!("interpolated tokens should not be present in the HIR") | |
343 | } | |
344 | ||
345 | token::DocComment(val) | | |
416331ca XL |
346 | token::Shebang(val) | |
347 | token::Unknown(val) => val.hash_stable(hcx, hasher), | |
dc9dc135 | 348 | } |
cc61c64b XL |
349 | } |
350 | } | |
7cac9316 | 351 | |
dc9dc135 XL |
352 | impl_stable_hash_for!(struct token::Token { |
353 | kind, | |
354 | span | |
355 | }); | |
356 | ||
532ac7d7 | 357 | impl_stable_hash_for!(enum ::syntax::ast::NestedMetaItem { |
7cac9316 XL |
358 | MetaItem(meta_item), |
359 | Literal(lit) | |
360 | }); | |
361 | ||
362 | impl_stable_hash_for!(struct ::syntax::ast::MetaItem { | |
532ac7d7 | 363 | path, |
7cac9316 XL |
364 | node, |
365 | span | |
366 | }); | |
367 | ||
368 | impl_stable_hash_for!(enum ::syntax::ast::MetaItemKind { | |
369 | Word, | |
370 | List(nested_items), | |
371 | NameValue(lit) | |
372 | }); | |
373 | ||
dc9dc135 XL |
374 | impl_stable_hash_for!(enum ::syntax_pos::hygiene::Transparency { |
375 | Transparent, | |
376 | SemiTransparent, | |
377 | Opaque, | |
378 | }); | |
379 | ||
e1599b0c | 380 | impl_stable_hash_for!(struct ::syntax_pos::hygiene::ExpnData { |
416331ca | 381 | kind, |
e1599b0c XL |
382 | parent -> _, |
383 | call_site, | |
dc9dc135 | 384 | def_site, |
ff7c6d11 XL |
385 | allow_internal_unstable, |
386 | allow_internal_unsafe, | |
8faf50e0 XL |
387 | local_inner_macros, |
388 | edition | |
ff7c6d11 XL |
389 | }); |
390 | ||
416331ca XL |
391 | impl_stable_hash_for!(enum ::syntax_pos::hygiene::ExpnKind { |
392 | Root, | |
393 | Macro(kind, descr), | |
e1599b0c | 394 | AstPass(kind), |
416331ca | 395 | Desugaring(kind) |
ff7c6d11 XL |
396 | }); |
397 | ||
e1599b0c XL |
398 | impl_stable_hash_for!(enum ::syntax_pos::hygiene::AstPass { |
399 | StdImports, | |
400 | TestHarness, | |
401 | ProcMacroHarness, | |
402 | PluginMacroDefs, | |
403 | }); | |
404 | ||
416331ca XL |
405 | impl_stable_hash_for!(enum ::syntax_pos::hygiene::DesugaringKind { |
406 | CondTemporary, | |
8faf50e0 | 407 | Async, |
48663c56 | 408 | Await, |
83c7162d | 409 | QuestionMark, |
416331ca | 410 | OpaqueTy, |
8faf50e0 | 411 | ForLoop, |
b7449926 | 412 | TryBlock |
ff7c6d11 XL |
413 | }); |
414 | ||
415 | impl_stable_hash_for!(enum ::syntax_pos::FileName { | |
416 | Real(pb), | |
417 | Macros(s), | |
0731742a XL |
418 | QuoteExpansion(s), |
419 | Anon(s), | |
420 | MacroExpansion(s), | |
421 | ProcMacroSourceCode(s), | |
422 | CliCrateAttr(s), | |
423 | CfgSpec(s), | |
424 | Custom(s), | |
425 | DocTest(pb, line), | |
ff7c6d11 XL |
426 | }); |
427 | ||
b7449926 | 428 | impl<'a> HashStable<StableHashingContext<'a>> for SourceFile { |
7cac9316 | 429 | fn hash_stable<W: StableHasherResult>(&self, |
0531ce1d | 430 | hcx: &mut StableHashingContext<'a>, |
7cac9316 | 431 | hasher: &mut StableHasher<W>) { |
b7449926 | 432 | let SourceFile { |
ff7c6d11 XL |
433 | name: _, // We hash the smaller name_hash instead of this |
434 | name_hash, | |
7cac9316 | 435 | name_was_remapped, |
ea8adc8c | 436 | unmapped_path: _, |
7cac9316 XL |
437 | crate_of_origin, |
438 | // Do not hash the source as it is not encoded | |
439 | src: _, | |
041b39d2 XL |
440 | src_hash, |
441 | external_src: _, | |
7cac9316 XL |
442 | start_pos, |
443 | end_pos: _, | |
444 | ref lines, | |
445 | ref multibyte_chars, | |
abe05a73 | 446 | ref non_narrow_chars, |
7cac9316 XL |
447 | } = *self; |
448 | ||
ff7c6d11 | 449 | (name_hash as u64).hash_stable(hcx, hasher); |
7cac9316 XL |
450 | name_was_remapped.hash_stable(hcx, hasher); |
451 | ||
452 | DefId { | |
453 | krate: CrateNum::from_u32(crate_of_origin), | |
454 | index: CRATE_DEF_INDEX, | |
455 | }.hash_stable(hcx, hasher); | |
456 | ||
041b39d2 XL |
457 | src_hash.hash_stable(hcx, hasher); |
458 | ||
b7449926 | 459 | // We only hash the relative position within this source_file |
8faf50e0 XL |
460 | lines.len().hash_stable(hcx, hasher); |
461 | for &line in lines.iter() { | |
462 | stable_byte_pos(line, start_pos).hash_stable(hcx, hasher); | |
463 | } | |
7cac9316 | 464 | |
b7449926 | 465 | // We only hash the relative position within this source_file |
8faf50e0 XL |
466 | multibyte_chars.len().hash_stable(hcx, hasher); |
467 | for &char_pos in multibyte_chars.iter() { | |
468 | stable_multibyte_char(char_pos, start_pos).hash_stable(hcx, hasher); | |
469 | } | |
abe05a73 | 470 | |
8faf50e0 XL |
471 | non_narrow_chars.len().hash_stable(hcx, hasher); |
472 | for &char_pos in non_narrow_chars.iter() { | |
473 | stable_non_narrow_char(char_pos, start_pos).hash_stable(hcx, hasher); | |
474 | } | |
7cac9316 XL |
475 | } |
476 | } | |
477 | ||
478 | fn stable_byte_pos(pos: ::syntax_pos::BytePos, | |
b7449926 | 479 | source_file_start: ::syntax_pos::BytePos) |
7cac9316 | 480 | -> u32 { |
b7449926 | 481 | pos.0 - source_file_start.0 |
7cac9316 XL |
482 | } |
483 | ||
484 | fn stable_multibyte_char(mbc: ::syntax_pos::MultiByteChar, | |
b7449926 | 485 | source_file_start: ::syntax_pos::BytePos) |
7cac9316 XL |
486 | -> (u32, u32) { |
487 | let ::syntax_pos::MultiByteChar { | |
488 | pos, | |
489 | bytes, | |
490 | } = mbc; | |
491 | ||
b7449926 | 492 | (pos.0 - source_file_start.0, bytes as u32) |
7cac9316 | 493 | } |
abe05a73 XL |
494 | |
495 | fn stable_non_narrow_char(swc: ::syntax_pos::NonNarrowChar, | |
b7449926 | 496 | source_file_start: ::syntax_pos::BytePos) |
abe05a73 XL |
497 | -> (u32, u32) { |
498 | let pos = swc.pos(); | |
499 | let width = swc.width(); | |
500 | ||
b7449926 | 501 | (pos.0 - source_file_start.0, width as u32) |
abe05a73 | 502 | } |
0531ce1d | 503 | |
dc9dc135 XL |
504 | impl<'tcx> HashStable<StableHashingContext<'tcx>> for feature_gate::Features { |
505 | fn hash_stable<W: StableHasherResult>( | |
506 | &self, | |
507 | hcx: &mut StableHashingContext<'tcx>, | |
508 | hasher: &mut StableHasher<W>, | |
509 | ) { | |
0531ce1d XL |
510 | // Unfortunately we cannot exhaustively list fields here, since the |
511 | // struct is macro generated. | |
b7449926 | 512 | self.declared_lang_features.hash_stable(hcx, hasher); |
0531ce1d XL |
513 | self.declared_lib_features.hash_stable(hcx, hasher); |
514 | ||
515 | self.walk_feature_fields(|feature_name, value| { | |
516 | feature_name.hash_stable(hcx, hasher); | |
517 | value.hash_stable(hcx, hasher); | |
518 | }); | |
519 | } | |
520 | } |