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