diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
commit | 698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch) | |
tree | 173a775858bd501c378080a10dca74132f05bc50 /compiler/rustc_query_system/src/ich/impls_syntax.rs | |
parent | Initial commit. (diff) | |
download | rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip |
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_query_system/src/ich/impls_syntax.rs')
-rw-r--r-- | compiler/rustc_query_system/src/ich/impls_syntax.rs | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/compiler/rustc_query_system/src/ich/impls_syntax.rs b/compiler/rustc_query_system/src/ich/impls_syntax.rs new file mode 100644 index 000000000..1fa085926 --- /dev/null +++ b/compiler/rustc_query_system/src/ich/impls_syntax.rs @@ -0,0 +1,150 @@ +//! This module contains `HashStable` implementations for various data types +//! from `rustc_ast` in no particular order. + +use crate::ich::StableHashingContext; + +use rustc_ast as ast; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_span::{BytePos, NormalizedPos, SourceFile}; +use std::assert_matches::assert_matches; + +use smallvec::SmallVec; + +impl<'ctx> rustc_target::HashStableContext for StableHashingContext<'ctx> {} + +impl<'a> HashStable<StableHashingContext<'a>> for [ast::Attribute] { + fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { + if self.is_empty() { + self.len().hash_stable(hcx, hasher); + return; + } + + // Some attributes are always ignored during hashing. + let filtered: SmallVec<[&ast::Attribute; 8]> = self + .iter() + .filter(|attr| { + !attr.is_doc_comment() + && !attr.ident().map_or(false, |ident| hcx.is_ignored_attr(ident.name)) + }) + .collect(); + + filtered.len().hash_stable(hcx, hasher); + for attr in filtered { + attr.hash_stable(hcx, hasher); + } + } +} + +impl<'ctx> rustc_ast::HashStableContext for StableHashingContext<'ctx> { + fn hash_attr(&mut self, attr: &ast::Attribute, hasher: &mut StableHasher) { + // Make sure that these have been filtered out. + debug_assert!(!attr.ident().map_or(false, |ident| self.is_ignored_attr(ident.name))); + debug_assert!(!attr.is_doc_comment()); + + let ast::Attribute { kind, id: _, style, span } = attr; + if let ast::AttrKind::Normal(item, tokens) = kind { + item.hash_stable(self, hasher); + style.hash_stable(self, hasher); + span.hash_stable(self, hasher); + assert_matches!( + tokens.as_ref(), + None, + "Tokens should have been removed during lowering!" + ); + } else { + unreachable!(); + } + } +} + +impl<'a> HashStable<StableHashingContext<'a>> for SourceFile { + fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { + let SourceFile { + name: _, // We hash the smaller name_hash instead of this + name_hash, + cnum, + // Do not hash the source as it is not encoded + src: _, + ref src_hash, + external_src: _, + start_pos, + end_pos: _, + lines: _, + ref multibyte_chars, + ref non_narrow_chars, + ref normalized_pos, + } = *self; + + (name_hash as u64).hash_stable(hcx, hasher); + + src_hash.hash_stable(hcx, hasher); + + // We are always in `Lines` form by the time we reach here. + assert!(self.lines.borrow().is_lines()); + self.lines(|lines| { + // We only hash the relative position within this source_file + lines.len().hash_stable(hcx, hasher); + for &line in lines.iter() { + stable_byte_pos(line, start_pos).hash_stable(hcx, hasher); + } + }); + + // We only hash the relative position within this source_file + multibyte_chars.len().hash_stable(hcx, hasher); + for &char_pos in multibyte_chars.iter() { + stable_multibyte_char(char_pos, start_pos).hash_stable(hcx, hasher); + } + + non_narrow_chars.len().hash_stable(hcx, hasher); + for &char_pos in non_narrow_chars.iter() { + stable_non_narrow_char(char_pos, start_pos).hash_stable(hcx, hasher); + } + + normalized_pos.len().hash_stable(hcx, hasher); + for &char_pos in normalized_pos.iter() { + stable_normalized_pos(char_pos, start_pos).hash_stable(hcx, hasher); + } + + cnum.hash_stable(hcx, hasher); + } +} + +fn stable_byte_pos(pos: BytePos, source_file_start: BytePos) -> u32 { + pos.0 - source_file_start.0 +} + +fn stable_multibyte_char(mbc: rustc_span::MultiByteChar, source_file_start: BytePos) -> (u32, u32) { + let rustc_span::MultiByteChar { pos, bytes } = mbc; + + (pos.0 - source_file_start.0, bytes as u32) +} + +fn stable_non_narrow_char( + swc: rustc_span::NonNarrowChar, + source_file_start: BytePos, +) -> (u32, u32) { + let pos = swc.pos(); + let width = swc.width(); + + (pos.0 - source_file_start.0, width as u32) +} + +fn stable_normalized_pos(np: NormalizedPos, source_file_start: BytePos) -> (u32, u32) { + let NormalizedPos { pos, diff } = np; + + (pos.0 - source_file_start.0, diff) +} + +impl<'tcx> HashStable<StableHashingContext<'tcx>> for rustc_feature::Features { + fn hash_stable(&self, hcx: &mut StableHashingContext<'tcx>, hasher: &mut StableHasher) { + // Unfortunately we cannot exhaustively list fields here, since the + // struct is macro generated. + self.declared_lang_features.hash_stable(hcx, hasher); + self.declared_lib_features.hash_stable(hcx, hasher); + + self.walk_feature_fields(|feature_name, value| { + feature_name.hash_stable(hcx, hasher); + value.hash_stable(hcx, hasher); + }); + } +} |