]> git.lizzy.rs Git - rust.git/blob - src/librustc/ich/impls_syntax.rs
Combine all builtin late lints
[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, LocalInternedString};
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         self.with(|s| s.hash_stable(hcx, hasher))
38     }
39 }
40
41 impl<'a> ToStableHashKey<StableHashingContext<'a>> for InternedString {
42     type KeyType = InternedString;
43
44     #[inline]
45     fn to_stable_hash_key(&self,
46                           _: &StableHashingContext<'a>)
47                           -> InternedString {
48         self.clone()
49     }
50 }
51
52 impl<'a> HashStable<StableHashingContext<'a>> for LocalInternedString {
53     #[inline]
54     fn hash_stable<W: StableHasherResult>(&self,
55                                           hcx: &mut StableHashingContext<'a>,
56                                           hasher: &mut StableHasher<W>) {
57         let s: &str = &**self;
58         s.hash_stable(hcx, hasher);
59     }
60 }
61
62 impl<'a> ToStableHashKey<StableHashingContext<'a>> for LocalInternedString {
63     type KeyType = LocalInternedString;
64
65     #[inline]
66     fn to_stable_hash_key(&self,
67                           _: &StableHashingContext<'a>)
68                           -> LocalInternedString {
69         self.clone()
70     }
71 }
72
73 impl<'a> HashStable<StableHashingContext<'a>> for ast::Name {
74     #[inline]
75     fn hash_stable<W: StableHasherResult>(&self,
76                                           hcx: &mut StableHashingContext<'a>,
77                                           hasher: &mut StableHasher<W>) {
78         self.as_str().hash_stable(hcx, hasher);
79     }
80 }
81
82 impl<'a> ToStableHashKey<StableHashingContext<'a>> for ast::Name {
83     type KeyType = InternedString;
84
85     #[inline]
86     fn to_stable_hash_key(&self,
87                           _: &StableHashingContext<'a>)
88                           -> InternedString {
89         self.as_interned_str()
90     }
91 }
92
93 impl_stable_hash_for!(enum ::syntax::ast::AsmDialect {
94     Att,
95     Intel
96 });
97
98 impl_stable_hash_for!(enum ::syntax::ext::base::MacroKind {
99     Bang,
100     Attr,
101     Derive
102 });
103
104
105 impl_stable_hash_for!(enum ::rustc_target::spec::abi::Abi {
106     Cdecl,
107     Stdcall,
108     Fastcall,
109     Vectorcall,
110     Thiscall,
111     Aapcs,
112     Win64,
113     SysV64,
114     PtxKernel,
115     Msp430Interrupt,
116     X86Interrupt,
117     Rust,
118     C,
119     System,
120     RustIntrinsic,
121     RustCall,
122     PlatformIntrinsic,
123     Unadjusted
124 });
125
126 impl_stable_hash_for!(struct ::syntax::attr::Deprecation { since, note });
127 impl_stable_hash_for!(struct ::syntax::attr::Stability {
128     level,
129     feature,
130     rustc_depr,
131     rustc_const_unstable
132 });
133
134 impl<'a> HashStable<StableHashingContext<'a>>
135 for ::syntax::edition::Edition {
136     fn hash_stable<W: StableHasherResult>(&self,
137                                           hcx: &mut StableHashingContext<'a>,
138                                           hasher: &mut StableHasher<W>) {
139         mem::discriminant(self).hash_stable(hcx, hasher);
140     }
141 }
142
143 impl<'a> HashStable<StableHashingContext<'a>>
144 for ::syntax::attr::StabilityLevel {
145     fn hash_stable<W: StableHasherResult>(&self,
146                                           hcx: &mut StableHashingContext<'a>,
147                                           hasher: &mut StableHasher<W>) {
148         mem::discriminant(self).hash_stable(hcx, hasher);
149         match *self {
150             ::syntax::attr::StabilityLevel::Unstable { ref reason, ref issue } => {
151                 reason.hash_stable(hcx, hasher);
152                 issue.hash_stable(hcx, hasher);
153             }
154             ::syntax::attr::StabilityLevel::Stable { ref since } => {
155                 since.hash_stable(hcx, hasher);
156             }
157         }
158     }
159 }
160
161 impl_stable_hash_for!(struct ::syntax::attr::RustcDeprecation { since, reason });
162 impl_stable_hash_for!(struct ::syntax::attr::RustcConstUnstable { feature });
163
164
165 impl_stable_hash_for!(enum ::syntax::attr::IntType {
166     SignedInt(int_ty),
167     UnsignedInt(uint_ty)
168 });
169
170 impl_stable_hash_for!(enum ::syntax::ast::LitIntType {
171     Signed(int_ty),
172     Unsigned(int_ty),
173     Unsuffixed
174 });
175
176 impl_stable_hash_for_spanned!(::syntax::ast::LitKind);
177 impl_stable_hash_for!(enum ::syntax::ast::LitKind {
178     Str(value, style),
179     ByteStr(value),
180     Byte(value),
181     Char(value),
182     Int(value, lit_int_type),
183     Float(value, float_ty),
184     FloatUnsuffixed(value),
185     Bool(value)
186 });
187
188 impl_stable_hash_for!(enum ::syntax::ast::IntTy { Isize, I8, I16, I32, I64, I128 });
189 impl_stable_hash_for!(enum ::syntax::ast::UintTy { Usize, U8, U16, U32, U64, U128 });
190 impl_stable_hash_for!(enum ::syntax::ast::FloatTy { F32, F64 });
191 impl_stable_hash_for!(enum ::syntax::ast::Unsafety { Unsafe, Normal });
192 impl_stable_hash_for!(enum ::syntax::ast::Constness { Const, NotConst });
193 impl_stable_hash_for!(enum ::syntax::ast::Defaultness { Default, Final });
194 impl_stable_hash_for!(struct ::syntax::ast::Lifetime { id, ident });
195 impl_stable_hash_for!(enum ::syntax::ast::StrStyle { Cooked, Raw(pounds) });
196 impl_stable_hash_for!(enum ::syntax::ast::AttrStyle { Outer, Inner });
197
198 impl<'a> HashStable<StableHashingContext<'a>> for [ast::Attribute] {
199     fn hash_stable<W: StableHasherResult>(&self,
200                                           hcx: &mut StableHashingContext<'a>,
201                                           hasher: &mut StableHasher<W>) {
202         if self.len() == 0 {
203             self.len().hash_stable(hcx, hasher);
204             return
205         }
206
207         // Some attributes are always ignored during hashing.
208         let filtered: AccumulateVec<[&ast::Attribute; 8]> = self
209             .iter()
210             .filter(|attr| {
211                 !attr.is_sugared_doc && !hcx.is_ignored_attr(attr.name())
212             })
213             .collect();
214
215         filtered.len().hash_stable(hcx, hasher);
216         for attr in filtered {
217             attr.hash_stable(hcx, hasher);
218         }
219     }
220 }
221
222 impl<'a> HashStable<StableHashingContext<'a>> for ast::Path {
223     fn hash_stable<W: StableHasherResult>(&self,
224                                           hcx: &mut StableHashingContext<'a>,
225                                           hasher: &mut StableHasher<W>) {
226         self.segments.len().hash_stable(hcx, hasher);
227         for segment in &self.segments {
228             segment.ident.name.hash_stable(hcx, hasher);
229         }
230     }
231 }
232
233 impl<'a> HashStable<StableHashingContext<'a>> for ast::Attribute {
234     fn hash_stable<W: StableHasherResult>(&self,
235                                           hcx: &mut StableHashingContext<'a>,
236                                           hasher: &mut StableHasher<W>) {
237         // Make sure that these have been filtered out.
238         debug_assert!(!hcx.is_ignored_attr(self.name()));
239         debug_assert!(!self.is_sugared_doc);
240
241         let ast::Attribute {
242             id: _,
243             style,
244             ref path,
245             ref tokens,
246             is_sugared_doc: _,
247             span,
248         } = *self;
249
250         style.hash_stable(hcx, hasher);
251         path.hash_stable(hcx, hasher);
252         for tt in tokens.trees() {
253             tt.hash_stable(hcx, hasher);
254         }
255         span.hash_stable(hcx, hasher);
256     }
257 }
258
259 impl<'a> HashStable<StableHashingContext<'a>>
260 for tokenstream::TokenTree {
261     fn hash_stable<W: StableHasherResult>(&self,
262                                           hcx: &mut StableHashingContext<'a>,
263                                           hasher: &mut StableHasher<W>) {
264         mem::discriminant(self).hash_stable(hcx, hasher);
265         match *self {
266             tokenstream::TokenTree::Token(span, ref token) => {
267                 span.hash_stable(hcx, hasher);
268                 hash_token(token, hcx, hasher);
269             }
270             tokenstream::TokenTree::Delimited(span, ref delimited) => {
271                 span.hash_stable(hcx, hasher);
272                 std_hash::Hash::hash(&delimited.delim, hasher);
273                 for sub_tt in delimited.stream().trees() {
274                     sub_tt.hash_stable(hcx, hasher);
275                 }
276             }
277         }
278     }
279 }
280
281 impl<'a> HashStable<StableHashingContext<'a>>
282 for tokenstream::TokenStream {
283     fn hash_stable<W: StableHasherResult>(&self,
284                                           hcx: &mut StableHashingContext<'a>,
285                                           hasher: &mut StableHasher<W>) {
286         for sub_tt in self.trees() {
287             sub_tt.hash_stable(hcx, hasher);
288         }
289     }
290 }
291
292 fn hash_token<'a, 'gcx, W: StableHasherResult>(
293     token: &token::Token,
294     hcx: &mut StableHashingContext<'a>,
295     hasher: &mut StableHasher<W>,
296 ) {
297     mem::discriminant(token).hash_stable(hcx, hasher);
298     match *token {
299         token::Token::Eq |
300         token::Token::Lt |
301         token::Token::Le |
302         token::Token::EqEq |
303         token::Token::Ne |
304         token::Token::Ge |
305         token::Token::Gt |
306         token::Token::AndAnd |
307         token::Token::OrOr |
308         token::Token::Not |
309         token::Token::Tilde |
310         token::Token::At |
311         token::Token::Dot |
312         token::Token::DotDot |
313         token::Token::DotDotDot |
314         token::Token::DotDotEq |
315         token::Token::DotEq |
316         token::Token::Comma |
317         token::Token::Semi |
318         token::Token::Colon |
319         token::Token::ModSep |
320         token::Token::RArrow |
321         token::Token::LArrow |
322         token::Token::FatArrow |
323         token::Token::Pound |
324         token::Token::Dollar |
325         token::Token::Question |
326         token::Token::SingleQuote |
327         token::Token::Whitespace |
328         token::Token::Comment |
329         token::Token::Eof => {}
330
331         token::Token::BinOp(bin_op_token) |
332         token::Token::BinOpEq(bin_op_token) => {
333             std_hash::Hash::hash(&bin_op_token, hasher);
334         }
335
336         token::Token::OpenDelim(delim_token) |
337         token::Token::CloseDelim(delim_token) => {
338             std_hash::Hash::hash(&delim_token, hasher);
339         }
340         token::Token::Literal(ref lit, ref opt_name) => {
341             mem::discriminant(lit).hash_stable(hcx, hasher);
342             match *lit {
343                 token::Lit::Byte(val) |
344                 token::Lit::Char(val) |
345                 token::Lit::Integer(val) |
346                 token::Lit::Float(val) |
347                 token::Lit::Str_(val) |
348                 token::Lit::ByteStr(val) => val.hash_stable(hcx, hasher),
349                 token::Lit::StrRaw(val, n) |
350                 token::Lit::ByteStrRaw(val, n) => {
351                     val.hash_stable(hcx, hasher);
352                     n.hash_stable(hcx, hasher);
353                 }
354             };
355             opt_name.hash_stable(hcx, hasher);
356         }
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_spanned!(::syntax::ast::NestedMetaItemKind);
374
375 impl_stable_hash_for!(enum ::syntax::ast::NestedMetaItemKind {
376     MetaItem(meta_item),
377     Literal(lit)
378 });
379
380 impl_stable_hash_for!(struct ::syntax::ast::MetaItem {
381     ident,
382     node,
383     span
384 });
385
386 impl_stable_hash_for!(enum ::syntax::ast::MetaItemKind {
387     Word,
388     List(nested_items),
389     NameValue(lit)
390 });
391
392 impl_stable_hash_for!(struct ::syntax_pos::hygiene::ExpnInfo {
393     call_site,
394     callee
395 });
396
397 impl_stable_hash_for!(struct ::syntax_pos::hygiene::NameAndSpan {
398     format,
399     allow_internal_unstable,
400     allow_internal_unsafe,
401     edition,
402     span
403 });
404
405 impl_stable_hash_for!(enum ::syntax_pos::hygiene::ExpnFormat {
406     MacroAttribute(sym),
407     MacroBang(sym),
408     CompilerDesugaring(kind)
409 });
410
411 impl_stable_hash_for!(enum ::syntax_pos::hygiene::CompilerDesugaringKind {
412     DotFill,
413     QuestionMark,
414     ExistentialReturnType,
415     Catch
416 });
417
418 impl_stable_hash_for!(enum ::syntax_pos::FileName {
419     Real(pb),
420     Macros(s),
421     QuoteExpansion,
422     Anon,
423     MacroExpansion,
424     ProcMacroSourceCode,
425     CfgSpec,
426     Custom(s)
427 });
428
429 impl<'a> HashStable<StableHashingContext<'a>> for FileMap {
430     fn hash_stable<W: StableHasherResult>(&self,
431                                           hcx: &mut StableHashingContext<'a>,
432                                           hasher: &mut StableHasher<W>) {
433         let FileMap {
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 filemap
461         lines.with_lock(|lines| {
462             lines.len().hash_stable(hcx, hasher);
463             for &line in lines.iter() {
464                 stable_byte_pos(line, start_pos).hash_stable(hcx, hasher);
465             }
466         });
467
468         // We only hash the relative position within this filemap
469         multibyte_chars.with_lock(|multibyte_chars| {
470             multibyte_chars.len().hash_stable(hcx, hasher);
471             for &char_pos in multibyte_chars.iter() {
472                 stable_multibyte_char(char_pos, start_pos).hash_stable(hcx, hasher);
473             }
474         });
475
476         non_narrow_chars.with_lock(|non_narrow_chars| {
477             non_narrow_chars.len().hash_stable(hcx, hasher);
478             for &char_pos in non_narrow_chars.iter() {
479                 stable_non_narrow_char(char_pos, start_pos).hash_stable(hcx, hasher);
480             }
481         });
482     }
483 }
484
485 fn stable_byte_pos(pos: ::syntax_pos::BytePos,
486                    filemap_start: ::syntax_pos::BytePos)
487                    -> u32 {
488     pos.0 - filemap_start.0
489 }
490
491 fn stable_multibyte_char(mbc: ::syntax_pos::MultiByteChar,
492                          filemap_start: ::syntax_pos::BytePos)
493                          -> (u32, u32) {
494     let ::syntax_pos::MultiByteChar {
495         pos,
496         bytes,
497     } = mbc;
498
499     (pos.0 - filemap_start.0, bytes as u32)
500 }
501
502 fn stable_non_narrow_char(swc: ::syntax_pos::NonNarrowChar,
503                           filemap_start: ::syntax_pos::BytePos)
504                           -> (u32, u32) {
505     let pos = swc.pos();
506     let width = swc.width();
507
508     (pos.0 - filemap_start.0, width as u32)
509 }
510
511
512
513 impl<'gcx> HashStable<StableHashingContext<'gcx>> for feature_gate::Features {
514     fn hash_stable<W: StableHasherResult>(&self,
515                                           hcx: &mut StableHashingContext<'gcx>,
516                                           hasher: &mut StableHasher<W>) {
517         // Unfortunately we cannot exhaustively list fields here, since the
518         // struct is macro generated.
519         self.declared_stable_lang_features.hash_stable(hcx, hasher);
520         self.declared_lib_features.hash_stable(hcx, hasher);
521
522         self.walk_feature_fields(|feature_name, value| {
523             feature_name.hash_stable(hcx, hasher);
524             value.hash_stable(hcx, hasher);
525         });
526     }
527 }