]> git.proxmox.com Git - rustc.git/blob - src/librustc/ich/impls_syntax.rs
New upstream version 1.34.2+dfsg1
[rustc.git] / src / librustc / ich / impls_syntax.rs
1 //! This module contains `HashStable` implementations for various data types
2 //! from libsyntax in no particular order.
3
4 use crate::ich::StableHashingContext;
5
6 use std::hash as std_hash;
7 use std::mem;
8
9 use syntax::ast;
10 use syntax::feature_gate;
11 use syntax::parse::token;
12 use syntax::symbol::{InternedString, LocalInternedString};
13 use syntax::tokenstream;
14 use syntax_pos::SourceFile;
15
16 use crate::hir::def_id::{DefId, CrateNum, CRATE_DEF_INDEX};
17
18 use smallvec::SmallVec;
19 use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey,
20 StableHasher, StableHasherResult};
21
22 impl<'a> HashStable<StableHashingContext<'a>> for InternedString {
23 #[inline]
24 fn hash_stable<W: StableHasherResult>(&self,
25 hcx: &mut StableHashingContext<'a>,
26 hasher: &mut StableHasher<W>) {
27 self.with(|s| s.hash_stable(hcx, hasher))
28 }
29 }
30
31 impl<'a> ToStableHashKey<StableHashingContext<'a>> for InternedString {
32 type KeyType = InternedString;
33
34 #[inline]
35 fn to_stable_hash_key(&self,
36 _: &StableHashingContext<'a>)
37 -> InternedString {
38 self.clone()
39 }
40 }
41
42 impl<'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
52 impl<'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
63 impl<'a> HashStable<StableHashingContext<'a>> for ast::Name {
64 #[inline]
65 fn hash_stable<W: StableHasherResult>(&self,
66 hcx: &mut StableHashingContext<'a>,
67 hasher: &mut StableHasher<W>) {
68 self.as_str().hash_stable(hcx, hasher);
69 }
70 }
71
72 impl<'a> ToStableHashKey<StableHashingContext<'a>> for ast::Name {
73 type KeyType = InternedString;
74
75 #[inline]
76 fn to_stable_hash_key(&self,
77 _: &StableHashingContext<'a>)
78 -> InternedString {
79 self.as_interned_str()
80 }
81 }
82
83 impl_stable_hash_for!(enum ::syntax::ast::AsmDialect {
84 Att,
85 Intel
86 });
87
88 impl_stable_hash_for!(enum ::syntax::ext::base::MacroKind {
89 Bang,
90 Attr,
91 Derive,
92 ProcMacroStub,
93 });
94
95
96 impl_stable_hash_for!(enum ::rustc_target::spec::abi::Abi {
97 Cdecl,
98 Stdcall,
99 Fastcall,
100 Vectorcall,
101 Thiscall,
102 Aapcs,
103 Win64,
104 SysV64,
105 PtxKernel,
106 Msp430Interrupt,
107 X86Interrupt,
108 AmdGpuKernel,
109 Rust,
110 C,
111 System,
112 RustIntrinsic,
113 RustCall,
114 PlatformIntrinsic,
115 Unadjusted
116 });
117
118 impl_stable_hash_for!(struct ::syntax::attr::Deprecation { since, note });
119 impl_stable_hash_for!(struct ::syntax::attr::Stability {
120 level,
121 feature,
122 rustc_depr,
123 promotable,
124 const_stability
125 });
126
127 impl_stable_hash_for!(enum ::syntax::edition::Edition {
128 Edition2015,
129 Edition2018,
130 });
131
132 impl<'a> HashStable<StableHashingContext<'a>>
133 for ::syntax::attr::StabilityLevel {
134 fn hash_stable<W: StableHasherResult>(&self,
135 hcx: &mut StableHashingContext<'a>,
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
150 impl_stable_hash_for!(struct ::syntax::attr::RustcDeprecation { since, reason, suggestion });
151
152
153 impl_stable_hash_for!(enum ::syntax::attr::IntType {
154 SignedInt(int_ty),
155 UnsignedInt(uint_ty)
156 });
157
158 impl_stable_hash_for!(enum ::syntax::ast::LitIntType {
159 Signed(int_ty),
160 Unsigned(int_ty),
161 Unsuffixed
162 });
163
164 impl_stable_hash_for_spanned!(::syntax::ast::LitKind);
165 impl_stable_hash_for!(enum ::syntax::ast::LitKind {
166 Str(value, style),
167 Err(value),
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
177 impl_stable_hash_for!(enum ::syntax::ast::IntTy { Isize, I8, I16, I32, I64, I128 });
178 impl_stable_hash_for!(enum ::syntax::ast::UintTy { Usize, U8, U16, U32, U64, U128 });
179 impl_stable_hash_for!(enum ::syntax::ast::FloatTy { F32, F64 });
180 impl_stable_hash_for!(enum ::syntax::ast::Unsafety { Unsafe, Normal });
181 impl_stable_hash_for!(enum ::syntax::ast::Constness { Const, NotConst });
182 impl_stable_hash_for!(enum ::syntax::ast::Defaultness { Default, Final });
183 impl_stable_hash_for!(struct ::syntax::ast::Lifetime { id, ident });
184 impl_stable_hash_for!(enum ::syntax::ast::StrStyle { Cooked, Raw(pounds) });
185 impl_stable_hash_for!(enum ::syntax::ast::AttrStyle { Outer, Inner });
186
187 impl<'a> HashStable<StableHashingContext<'a>> for [ast::Attribute] {
188 fn hash_stable<W: StableHasherResult>(&self,
189 hcx: &mut StableHashingContext<'a>,
190 hasher: &mut StableHasher<W>) {
191 if self.len() == 0 {
192 self.len().hash_stable(hcx, hasher);
193 return
194 }
195
196 // Some attributes are always ignored during hashing.
197 let filtered: SmallVec<[&ast::Attribute; 8]> = self
198 .iter()
199 .filter(|attr| {
200 !attr.is_sugared_doc &&
201 !attr.ident().map_or(false, |ident| hcx.is_ignored_attr(ident.name))
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
212 impl<'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
223 impl<'a> HashStable<StableHashingContext<'a>> for ast::Attribute {
224 fn hash_stable<W: StableHasherResult>(&self,
225 hcx: &mut StableHashingContext<'a>,
226 hasher: &mut StableHasher<W>) {
227 // Make sure that these have been filtered out.
228 debug_assert!(!self.ident().map_or(false, |ident| hcx.is_ignored_attr(ident.name)));
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);
241 path.hash_stable(hcx, hasher);
242 for tt in tokens.trees() {
243 tt.hash_stable(hcx, hasher);
244 }
245 span.hash_stable(hcx, hasher);
246 }
247 }
248
249 impl<'a> HashStable<StableHashingContext<'a>>
250 for tokenstream::TokenTree {
251 fn hash_stable<W: StableHasherResult>(&self,
252 hcx: &mut StableHashingContext<'a>,
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);
258 hash_token(token, hcx, hasher);
259 }
260 tokenstream::TokenTree::Delimited(span, delim, ref tts) => {
261 span.hash_stable(hcx, hasher);
262 std_hash::Hash::hash(&delim, hasher);
263 for sub_tt in tts.trees() {
264 sub_tt.hash_stable(hcx, hasher);
265 }
266 }
267 }
268 }
269 }
270
271 impl<'a> HashStable<StableHashingContext<'a>>
272 for tokenstream::TokenStream {
273 fn hash_stable<W: StableHasherResult>(&self,
274 hcx: &mut StableHashingContext<'a>,
275 hasher: &mut StableHasher<W>) {
276 for sub_tt in self.trees() {
277 sub_tt.hash_stable(hcx, hasher);
278 }
279 }
280 }
281
282 fn hash_token<'a, 'gcx, W: StableHasherResult>(
283 token: &token::Token,
284 hcx: &mut StableHashingContext<'a>,
285 hasher: &mut StableHasher<W>,
286 ) {
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 |
304 token::Token::DotDotEq |
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 |
315 token::Token::SingleQuote |
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) |
334 token::Lit::Err(val) |
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
348 token::Token::Ident(ident, is_raw) => {
349 ident.name.hash_stable(hcx, hasher);
350 is_raw.hash_stable(hcx, hasher);
351 }
352 token::Token::Lifetime(ident) => ident.name.hash_stable(hcx, hasher),
353
354 token::Token::Interpolated(_) => {
355 bug!("interpolated tokens should not be present in the HIR")
356 }
357
358 token::Token::DocComment(val) |
359 token::Token::Shebang(val) => val.hash_stable(hcx, hasher),
360 }
361 }
362
363 impl_stable_hash_for_spanned!(::syntax::ast::NestedMetaItemKind);
364
365 impl_stable_hash_for!(enum ::syntax::ast::NestedMetaItemKind {
366 MetaItem(meta_item),
367 Literal(lit)
368 });
369
370 impl_stable_hash_for!(struct ::syntax::ast::MetaItem {
371 ident,
372 node,
373 span
374 });
375
376 impl_stable_hash_for!(enum ::syntax::ast::MetaItemKind {
377 Word,
378 List(nested_items),
379 NameValue(lit)
380 });
381
382 impl_stable_hash_for!(struct ::syntax_pos::hygiene::ExpnInfo {
383 call_site,
384 def_site,
385 format,
386 allow_internal_unstable,
387 allow_internal_unsafe,
388 local_inner_macros,
389 edition
390 });
391
392 impl_stable_hash_for!(enum ::syntax_pos::hygiene::ExpnFormat {
393 MacroAttribute(sym),
394 MacroBang(sym),
395 CompilerDesugaring(kind)
396 });
397
398 impl_stable_hash_for!(enum ::syntax_pos::hygiene::CompilerDesugaringKind {
399 Async,
400 QuestionMark,
401 ExistentialReturnType,
402 ForLoop,
403 TryBlock
404 });
405
406 impl_stable_hash_for!(enum ::syntax_pos::FileName {
407 Real(pb),
408 Macros(s),
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),
417 });
418
419 impl<'a> HashStable<StableHashingContext<'a>> for SourceFile {
420 fn hash_stable<W: StableHasherResult>(&self,
421 hcx: &mut StableHashingContext<'a>,
422 hasher: &mut StableHasher<W>) {
423 let SourceFile {
424 name: _, // We hash the smaller name_hash instead of this
425 name_hash,
426 name_was_remapped,
427 unmapped_path: _,
428 crate_of_origin,
429 // Do not hash the source as it is not encoded
430 src: _,
431 src_hash,
432 external_src: _,
433 start_pos,
434 end_pos: _,
435 ref lines,
436 ref multibyte_chars,
437 ref non_narrow_chars,
438 } = *self;
439
440 (name_hash as u64).hash_stable(hcx, hasher);
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
448 src_hash.hash_stable(hcx, hasher);
449
450 // We only hash the relative position within this source_file
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 }
455
456 // We only hash the relative position within this source_file
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 }
461
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 }
466 }
467 }
468
469 fn stable_byte_pos(pos: ::syntax_pos::BytePos,
470 source_file_start: ::syntax_pos::BytePos)
471 -> u32 {
472 pos.0 - source_file_start.0
473 }
474
475 fn stable_multibyte_char(mbc: ::syntax_pos::MultiByteChar,
476 source_file_start: ::syntax_pos::BytePos)
477 -> (u32, u32) {
478 let ::syntax_pos::MultiByteChar {
479 pos,
480 bytes,
481 } = mbc;
482
483 (pos.0 - source_file_start.0, bytes as u32)
484 }
485
486 fn stable_non_narrow_char(swc: ::syntax_pos::NonNarrowChar,
487 source_file_start: ::syntax_pos::BytePos)
488 -> (u32, u32) {
489 let pos = swc.pos();
490 let width = swc.width();
491
492 (pos.0 - source_file_start.0, width as u32)
493 }
494
495
496
497 impl<'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.
503 self.declared_lang_features.hash_stable(hcx, hasher);
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 }