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