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