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