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