1 //! This module contains `HashStable` implementations for various data types
2 //! from libsyntax in no particular order.
4 use crate::ich::StableHashingContext;
6 use std::hash as std_hash;
10 use syntax::feature_gate;
11 use syntax::parse::token;
12 use syntax::symbol::{InternedString, LocalInternedString};
13 use syntax::tokenstream;
14 use syntax_pos::SourceFile;
16 use crate::hir::def_id::{DefId, CrateNum, CRATE_DEF_INDEX};
18 use smallvec::SmallVec;
19 use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey,
20 StableHasher, StableHasherResult};
22 impl<'a> HashStable<StableHashingContext<'a>> for InternedString {
24 fn hash_stable<W: StableHasherResult>(&self,
25 hcx: &mut StableHashingContext<'a>,
26 hasher: &mut StableHasher<W>) {
27 self.with(|s| s.hash_stable(hcx, hasher))
31 impl<'a> ToStableHashKey<StableHashingContext<'a>> for InternedString {
32 type KeyType = InternedString;
35 fn to_stable_hash_key(&self,
36 _: &StableHashingContext<'a>)
42 impl<'a> HashStable<StableHashingContext<'a>> for LocalInternedString {
44 fn hash_stable<W: StableHasherResult>(&self,
45 hcx: &mut StableHashingContext<'a>,
46 hasher: &mut StableHasher<W>) {
47 let s: &str = &**self;
48 s.hash_stable(hcx, hasher);
52 impl<'a> ToStableHashKey<StableHashingContext<'a>> for LocalInternedString {
53 type KeyType = LocalInternedString;
56 fn to_stable_hash_key(&self,
57 _: &StableHashingContext<'a>)
58 -> LocalInternedString {
63 impl<'a> HashStable<StableHashingContext<'a>> for ast::Name {
65 fn hash_stable<W: StableHasherResult>(&self,
66 hcx: &mut StableHashingContext<'a>,
67 hasher: &mut StableHasher<W>) {
68 self.as_str().hash_stable(hcx, hasher);
72 impl<'a> ToStableHashKey<StableHashingContext<'a>> for ast::Name {
73 type KeyType = InternedString;
76 fn to_stable_hash_key(&self,
77 _: &StableHashingContext<'a>)
79 self.as_interned_str()
83 impl_stable_hash_for!(enum ::syntax::ast::AsmDialect {
88 impl_stable_hash_for!(enum ::syntax::ext::base::MacroKind {
96 impl_stable_hash_for!(enum ::rustc_target::spec::abi::Abi {
118 impl_stable_hash_for!(struct ::syntax::attr::Deprecation { since, note });
119 impl_stable_hash_for!(struct ::syntax::attr::Stability {
128 impl_stable_hash_for!(enum ::syntax::edition::Edition {
133 impl<'a> HashStable<StableHashingContext<'a>>
134 for ::syntax::attr::StabilityLevel {
135 fn hash_stable<W: StableHasherResult>(&self,
136 hcx: &mut StableHashingContext<'a>,
137 hasher: &mut StableHasher<W>) {
138 mem::discriminant(self).hash_stable(hcx, hasher);
140 ::syntax::attr::StabilityLevel::Unstable { ref reason, ref issue } => {
141 reason.hash_stable(hcx, hasher);
142 issue.hash_stable(hcx, hasher);
144 ::syntax::attr::StabilityLevel::Stable { ref since } => {
145 since.hash_stable(hcx, hasher);
151 impl_stable_hash_for!(struct ::syntax::attr::RustcDeprecation { since, reason, suggestion });
154 impl_stable_hash_for!(enum ::syntax::attr::IntType {
159 impl_stable_hash_for!(enum ::syntax::ast::LitIntType {
165 impl_stable_hash_for!(struct ::syntax::ast::Lit {
171 impl_stable_hash_for!(enum ::syntax::ast::LitKind {
177 Int(value, lit_int_type),
178 Float(value, float_ty),
179 FloatUnsuffixed(value),
183 impl_stable_hash_for_spanned!(::syntax::ast::LitKind);
185 impl_stable_hash_for!(enum ::syntax::ast::IntTy { Isize, I8, I16, I32, I64, I128 });
186 impl_stable_hash_for!(enum ::syntax::ast::UintTy { Usize, U8, U16, U32, U64, U128 });
187 impl_stable_hash_for!(enum ::syntax::ast::FloatTy { F32, F64 });
188 impl_stable_hash_for!(enum ::syntax::ast::Unsafety { Unsafe, Normal });
189 impl_stable_hash_for!(enum ::syntax::ast::Constness { Const, NotConst });
190 impl_stable_hash_for!(enum ::syntax::ast::Defaultness { Default, Final });
191 impl_stable_hash_for!(struct ::syntax::ast::Lifetime { id, ident });
192 impl_stable_hash_for!(enum ::syntax::ast::StrStyle { Cooked, Raw(pounds) });
193 impl_stable_hash_for!(enum ::syntax::ast::AttrStyle { Outer, Inner });
195 impl<'a> HashStable<StableHashingContext<'a>> for [ast::Attribute] {
196 fn hash_stable<W: StableHasherResult>(&self,
197 hcx: &mut StableHashingContext<'a>,
198 hasher: &mut StableHasher<W>) {
200 self.len().hash_stable(hcx, hasher);
204 // Some attributes are always ignored during hashing.
205 let filtered: SmallVec<[&ast::Attribute; 8]> = self
208 !attr.is_sugared_doc &&
209 !attr.ident().map_or(false, |ident| hcx.is_ignored_attr(ident.name))
213 filtered.len().hash_stable(hcx, hasher);
214 for attr in filtered {
215 attr.hash_stable(hcx, hasher);
220 impl<'a> HashStable<StableHashingContext<'a>> for ast::Path {
221 fn hash_stable<W: StableHasherResult>(&self,
222 hcx: &mut StableHashingContext<'a>,
223 hasher: &mut StableHasher<W>) {
224 self.segments.len().hash_stable(hcx, hasher);
225 for segment in &self.segments {
226 segment.ident.name.hash_stable(hcx, hasher);
231 impl<'a> HashStable<StableHashingContext<'a>> for ast::Attribute {
232 fn hash_stable<W: StableHasherResult>(&self,
233 hcx: &mut StableHashingContext<'a>,
234 hasher: &mut StableHasher<W>) {
235 // Make sure that these have been filtered out.
236 debug_assert!(!self.ident().map_or(false, |ident| hcx.is_ignored_attr(ident.name)));
237 debug_assert!(!self.is_sugared_doc);
248 style.hash_stable(hcx, hasher);
249 path.hash_stable(hcx, hasher);
250 for tt in tokens.trees() {
251 tt.hash_stable(hcx, hasher);
253 span.hash_stable(hcx, hasher);
257 impl<'a> HashStable<StableHashingContext<'a>>
258 for tokenstream::TokenTree {
259 fn hash_stable<W: StableHasherResult>(&self,
260 hcx: &mut StableHashingContext<'a>,
261 hasher: &mut StableHasher<W>) {
262 mem::discriminant(self).hash_stable(hcx, hasher);
264 tokenstream::TokenTree::Token(span, ref token) => {
265 span.hash_stable(hcx, hasher);
266 hash_token(token, hcx, hasher);
268 tokenstream::TokenTree::Delimited(span, delim, ref tts) => {
269 span.hash_stable(hcx, hasher);
270 std_hash::Hash::hash(&delim, hasher);
271 for sub_tt in tts.trees() {
272 sub_tt.hash_stable(hcx, hasher);
279 impl<'a> HashStable<StableHashingContext<'a>>
280 for tokenstream::TokenStream {
281 fn hash_stable<W: StableHasherResult>(&self,
282 hcx: &mut StableHashingContext<'a>,
283 hasher: &mut StableHasher<W>) {
284 for sub_tt in self.trees() {
285 sub_tt.hash_stable(hcx, hasher);
290 impl_stable_hash_for!(enum token::LitKind {
303 impl_stable_hash_for!(struct token::Lit {
309 fn hash_token<'a, 'gcx, W: StableHasherResult>(
310 token: &token::Token,
311 hcx: &mut StableHashingContext<'a>,
312 hasher: &mut StableHasher<W>,
314 mem::discriminant(token).hash_stable(hcx, hasher);
323 token::Token::AndAnd |
326 token::Token::Tilde |
329 token::Token::DotDot |
330 token::Token::DotDotDot |
331 token::Token::DotDotEq |
332 token::Token::Comma |
334 token::Token::Colon |
335 token::Token::ModSep |
336 token::Token::RArrow |
337 token::Token::LArrow |
338 token::Token::FatArrow |
339 token::Token::Pound |
340 token::Token::Dollar |
341 token::Token::Question |
342 token::Token::SingleQuote |
343 token::Token::Whitespace |
344 token::Token::Comment |
345 token::Token::Eof => {}
347 token::Token::BinOp(bin_op_token) |
348 token::Token::BinOpEq(bin_op_token) => {
349 std_hash::Hash::hash(&bin_op_token, hasher);
352 token::Token::OpenDelim(delim_token) |
353 token::Token::CloseDelim(delim_token) => {
354 std_hash::Hash::hash(&delim_token, hasher);
356 token::Token::Literal(lit) => lit.hash_stable(hcx, hasher),
358 token::Token::Ident(ident, is_raw) => {
359 ident.name.hash_stable(hcx, hasher);
360 is_raw.hash_stable(hcx, hasher);
362 token::Token::Lifetime(ident) => ident.name.hash_stable(hcx, hasher),
364 token::Token::Interpolated(_) => {
365 bug!("interpolated tokens should not be present in the HIR")
368 token::Token::DocComment(val) |
369 token::Token::Shebang(val) => val.hash_stable(hcx, hasher),
373 impl_stable_hash_for!(enum ::syntax::ast::NestedMetaItem {
378 impl_stable_hash_for!(struct ::syntax::ast::MetaItem {
384 impl_stable_hash_for!(enum ::syntax::ast::MetaItemKind {
390 impl_stable_hash_for!(struct ::syntax_pos::hygiene::ExpnInfo {
394 allow_internal_unstable,
395 allow_internal_unsafe,
400 impl_stable_hash_for!(enum ::syntax_pos::hygiene::ExpnFormat {
403 CompilerDesugaring(kind)
406 impl_stable_hash_for!(enum ::syntax_pos::hygiene::CompilerDesugaringKind {
411 ExistentialReturnType,
416 impl_stable_hash_for!(enum ::syntax_pos::FileName {
422 ProcMacroSourceCode(s),
429 impl<'a> HashStable<StableHashingContext<'a>> for SourceFile {
430 fn hash_stable<W: StableHasherResult>(&self,
431 hcx: &mut StableHashingContext<'a>,
432 hasher: &mut StableHasher<W>) {
434 name: _, // We hash the smaller name_hash instead of this
439 // Do not hash the source as it is not encoded
447 ref non_narrow_chars,
450 (name_hash as u64).hash_stable(hcx, hasher);
451 name_was_remapped.hash_stable(hcx, hasher);
454 krate: CrateNum::from_u32(crate_of_origin),
455 index: CRATE_DEF_INDEX,
456 }.hash_stable(hcx, hasher);
458 src_hash.hash_stable(hcx, hasher);
460 // We only hash the relative position within this source_file
461 lines.len().hash_stable(hcx, hasher);
462 for &line in lines.iter() {
463 stable_byte_pos(line, start_pos).hash_stable(hcx, hasher);
466 // We only hash the relative position within this source_file
467 multibyte_chars.len().hash_stable(hcx, hasher);
468 for &char_pos in multibyte_chars.iter() {
469 stable_multibyte_char(char_pos, start_pos).hash_stable(hcx, hasher);
472 non_narrow_chars.len().hash_stable(hcx, hasher);
473 for &char_pos in non_narrow_chars.iter() {
474 stable_non_narrow_char(char_pos, start_pos).hash_stable(hcx, hasher);
479 fn stable_byte_pos(pos: ::syntax_pos::BytePos,
480 source_file_start: ::syntax_pos::BytePos)
482 pos.0 - source_file_start.0
485 fn stable_multibyte_char(mbc: ::syntax_pos::MultiByteChar,
486 source_file_start: ::syntax_pos::BytePos)
488 let ::syntax_pos::MultiByteChar {
493 (pos.0 - source_file_start.0, bytes as u32)
496 fn stable_non_narrow_char(swc: ::syntax_pos::NonNarrowChar,
497 source_file_start: ::syntax_pos::BytePos)
500 let width = swc.width();
502 (pos.0 - source_file_start.0, width as u32)
507 impl<'gcx> HashStable<StableHashingContext<'gcx>> for feature_gate::Features {
508 fn hash_stable<W: StableHasherResult>(&self,
509 hcx: &mut StableHashingContext<'gcx>,
510 hasher: &mut StableHasher<W>) {
511 // Unfortunately we cannot exhaustively list fields here, since the
512 // struct is macro generated.
513 self.declared_lang_features.hash_stable(hcx, hasher);
514 self.declared_lib_features.hash_stable(hcx, hasher);
516 self.walk_feature_fields(|feature_name, value| {
517 feature_name.hash_stable(hcx, hasher);
518 value.hash_stable(hcx, hasher);