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