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