]> git.lizzy.rs Git - rust.git/blob - src/librustc/ich/impls_syntax.rs
Rollup merge of #63285 - Mark-Simulacrum:rm-await-origin, r=Centril
[rust.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 });
93
94
95 impl_stable_hash_for!(enum ::rustc_target::spec::abi::Abi {
96     Cdecl,
97     Stdcall,
98     Fastcall,
99     Vectorcall,
100     Thiscall,
101     Aapcs,
102     Win64,
103     SysV64,
104     PtxKernel,
105     Msp430Interrupt,
106     X86Interrupt,
107     AmdGpuKernel,
108     Rust,
109     C,
110     System,
111     RustIntrinsic,
112     RustCall,
113     PlatformIntrinsic,
114     Unadjusted
115 });
116
117 impl_stable_hash_for!(struct ::syntax::attr::Deprecation { since, note });
118 impl_stable_hash_for!(struct ::syntax::attr::Stability {
119     level,
120     feature,
121     rustc_depr,
122     promotable,
123     allow_const_fn_ptr,
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!(struct ::syntax::ast::Lit {
165     node,
166     token,
167     span
168 });
169
170 impl_stable_hash_for!(enum ::syntax::ast::LitKind {
171     Str(value, style),
172     ByteStr(value),
173     Byte(value),
174     Char(value),
175     Int(value, lit_int_type),
176     Float(value, float_ty),
177     FloatUnsuffixed(value),
178     Bool(value),
179     Err(value)
180 });
181
182 impl_stable_hash_for_spanned!(::syntax::ast::LitKind);
183
184 impl_stable_hash_for!(enum ::syntax::ast::IntTy { Isize, I8, I16, I32, I64, I128 });
185 impl_stable_hash_for!(enum ::syntax::ast::UintTy { Usize, U8, U16, U32, U64, U128 });
186 impl_stable_hash_for!(enum ::syntax::ast::FloatTy { F32, F64 });
187 impl_stable_hash_for!(enum ::syntax::ast::Unsafety { Unsafe, Normal });
188 impl_stable_hash_for!(enum ::syntax::ast::Constness { Const, NotConst });
189 impl_stable_hash_for!(enum ::syntax::ast::Defaultness { Default, Final });
190 impl_stable_hash_for!(struct ::syntax::ast::Lifetime { id, ident });
191 impl_stable_hash_for!(enum ::syntax::ast::StrStyle { Cooked, Raw(pounds) });
192 impl_stable_hash_for!(enum ::syntax::ast::AttrStyle { Outer, Inner });
193
194 impl<'a> HashStable<StableHashingContext<'a>> for [ast::Attribute] {
195     fn hash_stable<W: StableHasherResult>(&self,
196                                           hcx: &mut StableHashingContext<'a>,
197                                           hasher: &mut StableHasher<W>) {
198         if self.len() == 0 {
199             self.len().hash_stable(hcx, hasher);
200             return
201         }
202
203         // Some attributes are always ignored during hashing.
204         let filtered: SmallVec<[&ast::Attribute; 8]> = self
205             .iter()
206             .filter(|attr| {
207                 !attr.is_sugared_doc &&
208                 !attr.ident().map_or(false, |ident| hcx.is_ignored_attr(ident.name))
209             })
210             .collect();
211
212         filtered.len().hash_stable(hcx, hasher);
213         for attr in filtered {
214             attr.hash_stable(hcx, hasher);
215         }
216     }
217 }
218
219 impl<'a> HashStable<StableHashingContext<'a>> for ast::Path {
220     fn hash_stable<W: StableHasherResult>(&self,
221                                           hcx: &mut StableHashingContext<'a>,
222                                           hasher: &mut StableHasher<W>) {
223         self.segments.len().hash_stable(hcx, hasher);
224         for segment in &self.segments {
225             segment.ident.name.hash_stable(hcx, hasher);
226         }
227     }
228 }
229
230 impl<'a> HashStable<StableHashingContext<'a>> for ast::Attribute {
231     fn hash_stable<W: StableHasherResult>(&self,
232                                           hcx: &mut StableHashingContext<'a>,
233                                           hasher: &mut StableHasher<W>) {
234         // Make sure that these have been filtered out.
235         debug_assert!(!self.ident().map_or(false, |ident| hcx.is_ignored_attr(ident.name)));
236         debug_assert!(!self.is_sugared_doc);
237
238         let ast::Attribute {
239             id: _,
240             style,
241             ref path,
242             ref tokens,
243             is_sugared_doc: _,
244             span,
245         } = *self;
246
247         style.hash_stable(hcx, hasher);
248         path.hash_stable(hcx, hasher);
249         for tt in tokens.trees() {
250             tt.hash_stable(hcx, hasher);
251         }
252         span.hash_stable(hcx, hasher);
253     }
254 }
255
256 impl<'a> HashStable<StableHashingContext<'a>>
257 for tokenstream::TokenTree {
258     fn hash_stable<W: StableHasherResult>(&self,
259                                           hcx: &mut StableHashingContext<'a>,
260                                           hasher: &mut StableHasher<W>) {
261         mem::discriminant(self).hash_stable(hcx, hasher);
262         match *self {
263             tokenstream::TokenTree::Token(ref token) => {
264                 token.hash_stable(hcx, hasher);
265             }
266             tokenstream::TokenTree::Delimited(span, delim, ref tts) => {
267                 span.hash_stable(hcx, hasher);
268                 std_hash::Hash::hash(&delim, hasher);
269                 for sub_tt in tts.trees() {
270                     sub_tt.hash_stable(hcx, hasher);
271                 }
272             }
273         }
274     }
275 }
276
277 impl<'a> HashStable<StableHashingContext<'a>>
278 for tokenstream::TokenStream {
279     fn hash_stable<W: StableHasherResult>(&self,
280                                           hcx: &mut StableHashingContext<'a>,
281                                           hasher: &mut StableHasher<W>) {
282         for sub_tt in self.trees() {
283             sub_tt.hash_stable(hcx, hasher);
284         }
285     }
286 }
287
288 impl_stable_hash_for!(enum token::LitKind {
289     Bool,
290     Byte,
291     Char,
292     Integer,
293     Float,
294     Str,
295     ByteStr,
296     StrRaw(n),
297     ByteStrRaw(n),
298     Err
299 });
300
301 impl_stable_hash_for!(struct token::Lit {
302     kind,
303     symbol,
304     suffix
305 });
306
307 impl<'a> HashStable<StableHashingContext<'a>> for token::TokenKind {
308     fn hash_stable<W: StableHasherResult>(&self,
309                                           hcx: &mut StableHashingContext<'a>,
310                                           hasher: &mut StableHasher<W>) {
311         mem::discriminant(self).hash_stable(hcx, hasher);
312         match *self {
313             token::Eq |
314             token::Lt |
315             token::Le |
316             token::EqEq |
317             token::Ne |
318             token::Ge |
319             token::Gt |
320             token::AndAnd |
321             token::OrOr |
322             token::Not |
323             token::Tilde |
324             token::At |
325             token::Dot |
326             token::DotDot |
327             token::DotDotDot |
328             token::DotDotEq |
329             token::Comma |
330             token::Semi |
331             token::Colon |
332             token::ModSep |
333             token::RArrow |
334             token::LArrow |
335             token::FatArrow |
336             token::Pound |
337             token::Dollar |
338             token::Question |
339             token::SingleQuote |
340             token::Whitespace |
341             token::Comment |
342             token::Eof => {}
343
344             token::BinOp(bin_op_token) |
345             token::BinOpEq(bin_op_token) => {
346                 std_hash::Hash::hash(&bin_op_token, hasher);
347             }
348
349             token::OpenDelim(delim_token) |
350             token::CloseDelim(delim_token) => {
351                 std_hash::Hash::hash(&delim_token, hasher);
352             }
353             token::Literal(lit) => lit.hash_stable(hcx, hasher),
354
355             token::Ident(name, is_raw) => {
356                 name.hash_stable(hcx, hasher);
357                 is_raw.hash_stable(hcx, hasher);
358             }
359             token::Lifetime(name) => name.hash_stable(hcx, hasher),
360
361             token::Interpolated(_) => {
362                 bug!("interpolated tokens should not be present in the HIR")
363             }
364
365             token::DocComment(val) |
366             token::Shebang(val) |
367             token::Unknown(val) => val.hash_stable(hcx, hasher),
368         }
369     }
370 }
371
372 impl_stable_hash_for!(struct token::Token {
373     kind,
374     span
375 });
376
377 impl_stable_hash_for!(enum ::syntax::ast::NestedMetaItem {
378     MetaItem(meta_item),
379     Literal(lit)
380 });
381
382 impl_stable_hash_for!(struct ::syntax::ast::MetaItem {
383     path,
384     node,
385     span
386 });
387
388 impl_stable_hash_for!(enum ::syntax::ast::MetaItemKind {
389     Word,
390     List(nested_items),
391     NameValue(lit)
392 });
393
394 impl_stable_hash_for!(enum ::syntax_pos::hygiene::Transparency {
395     Transparent,
396     SemiTransparent,
397     Opaque,
398 });
399
400 impl_stable_hash_for!(struct ::syntax_pos::hygiene::ExpnInfo {
401     call_site,
402     kind,
403     def_site,
404     default_transparency,
405     allow_internal_unstable,
406     allow_internal_unsafe,
407     local_inner_macros,
408     edition
409 });
410
411 impl_stable_hash_for!(enum ::syntax_pos::hygiene::ExpnKind {
412     Root,
413     Macro(kind, descr),
414     Desugaring(kind)
415 });
416
417 impl_stable_hash_for!(enum ::syntax_pos::hygiene::DesugaringKind {
418     CondTemporary,
419     Async,
420     Await,
421     QuestionMark,
422     OpaqueTy,
423     ForLoop,
424     TryBlock
425 });
426
427 impl_stable_hash_for!(enum ::syntax_pos::FileName {
428     Real(pb),
429     Macros(s),
430     QuoteExpansion(s),
431     Anon(s),
432     MacroExpansion(s),
433     ProcMacroSourceCode(s),
434     CliCrateAttr(s),
435     CfgSpec(s),
436     Custom(s),
437     DocTest(pb, line),
438 });
439
440 impl<'a> HashStable<StableHashingContext<'a>> for SourceFile {
441     fn hash_stable<W: StableHasherResult>(&self,
442                                           hcx: &mut StableHashingContext<'a>,
443                                           hasher: &mut StableHasher<W>) {
444         let SourceFile {
445             name: _, // We hash the smaller name_hash instead of this
446             name_hash,
447             name_was_remapped,
448             unmapped_path: _,
449             crate_of_origin,
450             // Do not hash the source as it is not encoded
451             src: _,
452             src_hash,
453             external_src: _,
454             start_pos,
455             end_pos: _,
456             ref lines,
457             ref multibyte_chars,
458             ref non_narrow_chars,
459         } = *self;
460
461         (name_hash as u64).hash_stable(hcx, hasher);
462         name_was_remapped.hash_stable(hcx, hasher);
463
464         DefId {
465             krate: CrateNum::from_u32(crate_of_origin),
466             index: CRATE_DEF_INDEX,
467         }.hash_stable(hcx, hasher);
468
469         src_hash.hash_stable(hcx, hasher);
470
471         // We only hash the relative position within this source_file
472         lines.len().hash_stable(hcx, hasher);
473         for &line in lines.iter() {
474             stable_byte_pos(line, start_pos).hash_stable(hcx, hasher);
475         }
476
477         // We only hash the relative position within this source_file
478         multibyte_chars.len().hash_stable(hcx, hasher);
479         for &char_pos in multibyte_chars.iter() {
480             stable_multibyte_char(char_pos, start_pos).hash_stable(hcx, hasher);
481         }
482
483         non_narrow_chars.len().hash_stable(hcx, hasher);
484         for &char_pos in non_narrow_chars.iter() {
485             stable_non_narrow_char(char_pos, start_pos).hash_stable(hcx, hasher);
486         }
487     }
488 }
489
490 fn stable_byte_pos(pos: ::syntax_pos::BytePos,
491                    source_file_start: ::syntax_pos::BytePos)
492                    -> u32 {
493     pos.0 - source_file_start.0
494 }
495
496 fn stable_multibyte_char(mbc: ::syntax_pos::MultiByteChar,
497                          source_file_start: ::syntax_pos::BytePos)
498                          -> (u32, u32) {
499     let ::syntax_pos::MultiByteChar {
500         pos,
501         bytes,
502     } = mbc;
503
504     (pos.0 - source_file_start.0, bytes as u32)
505 }
506
507 fn stable_non_narrow_char(swc: ::syntax_pos::NonNarrowChar,
508                           source_file_start: ::syntax_pos::BytePos)
509                           -> (u32, u32) {
510     let pos = swc.pos();
511     let width = swc.width();
512
513     (pos.0 - source_file_start.0, width as u32)
514 }
515
516 impl<'tcx> HashStable<StableHashingContext<'tcx>> for feature_gate::Features {
517     fn hash_stable<W: StableHasherResult>(
518         &self,
519         hcx: &mut StableHashingContext<'tcx>,
520         hasher: &mut StableHasher<W>,
521     ) {
522         // Unfortunately we cannot exhaustively list fields here, since the
523         // struct is macro generated.
524         self.declared_lang_features.hash_stable(hcx, hasher);
525         self.declared_lib_features.hash_stable(hcx, hasher);
526
527         self.walk_feature_fields(|feature_name, value| {
528             feature_name.hash_stable(hcx, hasher);
529             value.hash_stable(hcx, hasher);
530         });
531     }
532 }