]> git.lizzy.rs Git - rust.git/blob - src/librustc/ich/impls_syntax.rs
Rollup merge of #41135 - japaric:unstable-docs, r=steveklabnik
[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::parse::token;
21 use syntax::tokenstream;
22 use syntax_pos::Span;
23
24 use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
25                                            StableHasherResult};
26 use rustc_data_structures::accumulate_vec::AccumulateVec;
27
28 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ::syntax::symbol::InternedString {
29     #[inline]
30     fn hash_stable<W: StableHasherResult>(&self,
31                                           hcx: &mut StableHashingContext<'a, 'tcx>,
32                                           hasher: &mut StableHasher<W>) {
33         let s: &str = &**self;
34         s.hash_stable(hcx, hasher);
35     }
36 }
37
38 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ast::Name {
39     #[inline]
40     fn hash_stable<W: StableHasherResult>(&self,
41                                           hcx: &mut StableHashingContext<'a, 'tcx>,
42                                           hasher: &mut StableHasher<W>) {
43         self.as_str().hash_stable(hcx, hasher);
44     }
45 }
46
47 impl_stable_hash_for!(enum ::syntax::ast::AsmDialect {
48     Att,
49     Intel
50 });
51
52 impl_stable_hash_for!(enum ::syntax::ext::base::MacroKind {
53     Bang,
54     Attr,
55     Derive
56 });
57
58
59 impl_stable_hash_for!(enum ::syntax::abi::Abi {
60     Cdecl,
61     Stdcall,
62     Fastcall,
63     Vectorcall,
64     Aapcs,
65     Win64,
66     SysV64,
67     PtxKernel,
68     Msp430Interrupt,
69     X86Interrupt,
70     Rust,
71     C,
72     System,
73     RustIntrinsic,
74     RustCall,
75     PlatformIntrinsic,
76     Unadjusted
77 });
78
79 impl_stable_hash_for!(struct ::syntax::attr::Deprecation { since, note });
80 impl_stable_hash_for!(struct ::syntax::attr::Stability { level, feature, rustc_depr });
81
82 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ::syntax::attr::StabilityLevel {
83     fn hash_stable<W: StableHasherResult>(&self,
84                                           hcx: &mut StableHashingContext<'a, 'tcx>,
85                                           hasher: &mut StableHasher<W>) {
86         mem::discriminant(self).hash_stable(hcx, hasher);
87         match *self {
88             ::syntax::attr::StabilityLevel::Unstable { ref reason, ref issue } => {
89                 reason.hash_stable(hcx, hasher);
90                 issue.hash_stable(hcx, hasher);
91             }
92             ::syntax::attr::StabilityLevel::Stable { ref since } => {
93                 since.hash_stable(hcx, hasher);
94             }
95         }
96     }
97 }
98
99 impl_stable_hash_for!(struct ::syntax::attr::RustcDeprecation { since, reason });
100
101
102 impl_stable_hash_for!(enum ::syntax::attr::IntType {
103     SignedInt(int_ty),
104     UnsignedInt(uint_ty)
105 });
106
107 impl_stable_hash_for!(enum ::syntax::ast::LitIntType {
108     Signed(int_ty),
109     Unsigned(int_ty),
110     Unsuffixed
111 });
112
113 impl_stable_hash_for_spanned!(::syntax::ast::LitKind);
114 impl_stable_hash_for!(enum ::syntax::ast::LitKind {
115     Str(value, style),
116     ByteStr(value),
117     Byte(value),
118     Char(value),
119     Int(value, lit_int_type),
120     Float(value, float_ty),
121     FloatUnsuffixed(value),
122     Bool(value)
123 });
124
125 impl_stable_hash_for!(enum ::syntax::ast::IntTy { Is, I8, I16, I32, I64, I128 });
126 impl_stable_hash_for!(enum ::syntax::ast::UintTy { Us, U8, U16, U32, U64, U128 });
127 impl_stable_hash_for!(enum ::syntax::ast::FloatTy { F32, F64 });
128 impl_stable_hash_for!(enum ::syntax::ast::Unsafety { Unsafe, Normal });
129 impl_stable_hash_for!(enum ::syntax::ast::Constness { Const, NotConst });
130 impl_stable_hash_for!(enum ::syntax::ast::Defaultness { Default, Final });
131 impl_stable_hash_for!(struct ::syntax::ast::Lifetime { id, span, name });
132 impl_stable_hash_for!(enum ::syntax::ast::StrStyle { Cooked, Raw(pounds) });
133 impl_stable_hash_for!(enum ::syntax::ast::AttrStyle { Outer, Inner });
134
135 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for [ast::Attribute] {
136     fn hash_stable<W: StableHasherResult>(&self,
137                                           hcx: &mut StableHashingContext<'a, 'tcx>,
138                                           hasher: &mut StableHasher<W>) {
139         // Some attributes are always ignored during hashing.
140         let filtered: AccumulateVec<[&ast::Attribute; 8]> = self
141             .iter()
142             .filter(|attr| {
143                 !attr.is_sugared_doc &&
144                 attr.name().map(|name| !hcx.is_ignored_attr(name)).unwrap_or(true)
145             })
146             .collect();
147
148         filtered.len().hash_stable(hcx, hasher);
149         for attr in filtered {
150             attr.hash_stable(hcx, hasher);
151         }
152     }
153 }
154
155 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ast::Attribute {
156     fn hash_stable<W: StableHasherResult>(&self,
157                                           hcx: &mut StableHashingContext<'a, 'tcx>,
158                                           hasher: &mut StableHasher<W>) {
159         // Make sure that these have been filtered out.
160         debug_assert!(self.name().map(|name| !hcx.is_ignored_attr(name)).unwrap_or(true));
161         debug_assert!(!self.is_sugared_doc);
162
163         let ast::Attribute {
164             id: _,
165             style,
166             ref path,
167             ref tokens,
168             is_sugared_doc: _,
169             span,
170         } = *self;
171
172         style.hash_stable(hcx, hasher);
173         path.segments.len().hash_stable(hcx, hasher);
174         for segment in &path.segments {
175             segment.identifier.name.hash_stable(hcx, hasher);
176         }
177         for tt in tokens.trees() {
178             tt.hash_stable(hcx, hasher);
179         }
180         span.hash_stable(hcx, hasher);
181     }
182 }
183
184 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for tokenstream::TokenTree {
185     fn hash_stable<W: StableHasherResult>(&self,
186                                           hcx: &mut StableHashingContext<'a, 'tcx>,
187                                           hasher: &mut StableHasher<W>) {
188         mem::discriminant(self).hash_stable(hcx, hasher);
189         match *self {
190             tokenstream::TokenTree::Token(span, ref token) => {
191                 span.hash_stable(hcx, hasher);
192                 hash_token(token, hcx, hasher, span);
193             }
194             tokenstream::TokenTree::Delimited(span, ref delimited) => {
195                 span.hash_stable(hcx, hasher);
196                 std_hash::Hash::hash(&delimited.delim, hasher);
197                 for sub_tt in delimited.stream().trees() {
198                     sub_tt.hash_stable(hcx, hasher);
199                 }
200             }
201         }
202     }
203 }
204
205 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for tokenstream::TokenStream {
206     fn hash_stable<W: StableHasherResult>(&self,
207                                           hcx: &mut StableHashingContext<'a, 'tcx>,
208                                           hasher: &mut StableHasher<W>) {
209         for sub_tt in self.trees() {
210             sub_tt.hash_stable(hcx, hasher);
211         }
212     }
213 }
214
215 fn hash_token<'a, 'tcx, W: StableHasherResult>(token: &token::Token,
216                                                hcx: &mut StableHashingContext<'a, 'tcx>,
217                                                hasher: &mut StableHasher<W>,
218                                                error_reporting_span: Span) {
219     mem::discriminant(token).hash_stable(hcx, hasher);
220     match *token {
221         token::Token::Eq |
222         token::Token::Lt |
223         token::Token::Le |
224         token::Token::EqEq |
225         token::Token::Ne |
226         token::Token::Ge |
227         token::Token::Gt |
228         token::Token::AndAnd |
229         token::Token::OrOr |
230         token::Token::Not |
231         token::Token::Tilde |
232         token::Token::At |
233         token::Token::Dot |
234         token::Token::DotDot |
235         token::Token::DotDotDot |
236         token::Token::Comma |
237         token::Token::Semi |
238         token::Token::Colon |
239         token::Token::ModSep |
240         token::Token::RArrow |
241         token::Token::LArrow |
242         token::Token::FatArrow |
243         token::Token::Pound |
244         token::Token::Dollar |
245         token::Token::Question |
246         token::Token::Underscore |
247         token::Token::Whitespace |
248         token::Token::Comment |
249         token::Token::Eof => {}
250
251         token::Token::BinOp(bin_op_token) |
252         token::Token::BinOpEq(bin_op_token) => {
253             std_hash::Hash::hash(&bin_op_token, hasher);
254         }
255
256         token::Token::OpenDelim(delim_token) |
257         token::Token::CloseDelim(delim_token) => {
258             std_hash::Hash::hash(&delim_token, hasher);
259         }
260         token::Token::Literal(ref lit, ref opt_name) => {
261             mem::discriminant(lit).hash_stable(hcx, hasher);
262             match *lit {
263                 token::Lit::Byte(val) |
264                 token::Lit::Char(val) |
265                 token::Lit::Integer(val) |
266                 token::Lit::Float(val) |
267                 token::Lit::Str_(val) |
268                 token::Lit::ByteStr(val) => val.hash_stable(hcx, hasher),
269                 token::Lit::StrRaw(val, n) |
270                 token::Lit::ByteStrRaw(val, n) => {
271                     val.hash_stable(hcx, hasher);
272                     n.hash_stable(hcx, hasher);
273                 }
274             };
275             opt_name.hash_stable(hcx, hasher);
276         }
277
278         token::Token::Ident(ident) |
279         token::Token::Lifetime(ident) |
280         token::Token::SubstNt(ident) => ident.name.hash_stable(hcx, hasher),
281
282         token::Token::Interpolated(ref non_terminal) => {
283             // FIXME(mw): This could be implemented properly. It's just a
284             //            lot of work, since we would need to hash the AST
285             //            in a stable way, in addition to the HIR.
286             //            Since this is hardly used anywhere, just emit a
287             //            warning for now.
288             if hcx.tcx().sess.opts.debugging_opts.incremental.is_some() {
289                 let msg = format!("Quasi-quoting might make incremental \
290                                    compilation very inefficient: {:?}",
291                                   non_terminal);
292                 hcx.tcx().sess.span_warn(error_reporting_span, &msg[..]);
293             }
294
295             std_hash::Hash::hash(non_terminal, hasher);
296         }
297
298         token::Token::DocComment(val) |
299         token::Token::Shebang(val) => val.hash_stable(hcx, hasher),
300     }
301 }