]> git.proxmox.com Git - rustc.git/blame - src/librustc/ich/impls_syntax.rs
New upstream version 1.18.0+dfsg1
[rustc.git] / src / librustc / ich / impls_syntax.rs
CommitLineData
cc61c64b
XL
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
14use ich::StableHashingContext;
15
16use std::hash as std_hash;
17use std::mem;
18
19use syntax::ast;
20use syntax::parse::token;
21use syntax::tokenstream;
22use syntax_pos::Span;
23
24use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
25 StableHasherResult};
26use rustc_data_structures::accumulate_vec::AccumulateVec;
27
28impl<'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
38impl<'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
47impl_stable_hash_for!(enum ::syntax::ast::AsmDialect {
48 Att,
49 Intel
50});
51
52impl_stable_hash_for!(enum ::syntax::ext::base::MacroKind {
53 Bang,
54 Attr,
55 Derive
56});
57
58
59impl_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
79impl_stable_hash_for!(struct ::syntax::attr::Deprecation { since, note });
80impl_stable_hash_for!(struct ::syntax::attr::Stability { level, feature, rustc_depr });
81
82impl<'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
99impl_stable_hash_for!(struct ::syntax::attr::RustcDeprecation { since, reason });
100
101
102impl_stable_hash_for!(enum ::syntax::attr::IntType {
103 SignedInt(int_ty),
104 UnsignedInt(uint_ty)
105});
106
107impl_stable_hash_for!(enum ::syntax::ast::LitIntType {
108 Signed(int_ty),
109 Unsigned(int_ty),
110 Unsuffixed
111});
112
113impl_stable_hash_for_spanned!(::syntax::ast::LitKind);
114impl_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
125impl_stable_hash_for!(enum ::syntax::ast::IntTy { Is, I8, I16, I32, I64, I128 });
126impl_stable_hash_for!(enum ::syntax::ast::UintTy { Us, U8, U16, U32, U64, U128 });
127impl_stable_hash_for!(enum ::syntax::ast::FloatTy { F32, F64 });
128impl_stable_hash_for!(enum ::syntax::ast::Unsafety { Unsafe, Normal });
129impl_stable_hash_for!(enum ::syntax::ast::Constness { Const, NotConst });
130impl_stable_hash_for!(enum ::syntax::ast::Defaultness { Default, Final });
131impl_stable_hash_for!(struct ::syntax::ast::Lifetime { id, span, name });
132impl_stable_hash_for!(enum ::syntax::ast::StrStyle { Cooked, Raw(pounds) });
133impl_stable_hash_for!(enum ::syntax::ast::AttrStyle { Outer, Inner });
134
135impl<'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
155impl<'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
184impl<'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
205impl<'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
215fn 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}