]> git.proxmox.com Git - rustc.git/blob - src/librustc/ich/impls_syntax.rs
New upstream version 1.28.0~beta.14+dfsg1
[rustc.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 }