1 //! This module contains `HashStable` implementations for various data types
2 //! from `rustc_ast` in no particular order.
4 use crate::ich::StableHashingContext;
7 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
8 use rustc_span::{BytePos, NormalizedPos, SourceFile};
9 use std::assert_matches::assert_matches;
11 use smallvec::SmallVec;
13 impl<'ctx> rustc_target::HashStableContext for StableHashingContext<'ctx> {}
15 impl<'a> HashStable<StableHashingContext<'a>> for [ast::Attribute] {
16 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
18 self.len().hash_stable(hcx, hasher);
22 // Some attributes are always ignored during hashing.
23 let filtered: SmallVec<[&ast::Attribute; 8]> = self
26 !attr.is_doc_comment()
27 && !attr.ident().map_or(false, |ident| hcx.is_ignored_attr(ident.name))
31 filtered.len().hash_stable(hcx, hasher);
32 for attr in filtered {
33 attr.hash_stable(hcx, hasher);
38 impl<'ctx> rustc_ast::HashStableContext for StableHashingContext<'ctx> {
39 fn hash_attr(&mut self, attr: &ast::Attribute, hasher: &mut StableHasher) {
40 // Make sure that these have been filtered out.
41 debug_assert!(!attr.ident().map_or(false, |ident| self.is_ignored_attr(ident.name)));
42 debug_assert!(!attr.is_doc_comment());
44 let ast::Attribute { kind, id: _, style, span } = attr;
45 if let ast::AttrKind::Normal(normal) = kind {
46 normal.item.hash_stable(self, hasher);
47 style.hash_stable(self, hasher);
48 span.hash_stable(self, hasher);
50 normal.tokens.as_ref(),
52 "Tokens should have been removed during lowering!"
60 impl<'a> HashStable<StableHashingContext<'a>> for SourceFile {
61 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
63 name: _, // We hash the smaller name_hash instead of this
66 // Do not hash the source as it is not encoded
78 (name_hash as u64).hash_stable(hcx, hasher);
80 src_hash.hash_stable(hcx, hasher);
82 // We are always in `Lines` form by the time we reach here.
83 assert!(self.lines.borrow().is_lines());
85 // We only hash the relative position within this source_file
86 lines.len().hash_stable(hcx, hasher);
87 for &line in lines.iter() {
88 stable_byte_pos(line, start_pos).hash_stable(hcx, hasher);
92 // We only hash the relative position within this source_file
93 multibyte_chars.len().hash_stable(hcx, hasher);
94 for &char_pos in multibyte_chars.iter() {
95 stable_multibyte_char(char_pos, start_pos).hash_stable(hcx, hasher);
98 non_narrow_chars.len().hash_stable(hcx, hasher);
99 for &char_pos in non_narrow_chars.iter() {
100 stable_non_narrow_char(char_pos, start_pos).hash_stable(hcx, hasher);
103 normalized_pos.len().hash_stable(hcx, hasher);
104 for &char_pos in normalized_pos.iter() {
105 stable_normalized_pos(char_pos, start_pos).hash_stable(hcx, hasher);
108 cnum.hash_stable(hcx, hasher);
112 fn stable_byte_pos(pos: BytePos, source_file_start: BytePos) -> u32 {
113 pos.0 - source_file_start.0
116 fn stable_multibyte_char(mbc: rustc_span::MultiByteChar, source_file_start: BytePos) -> (u32, u32) {
117 let rustc_span::MultiByteChar { pos, bytes } = mbc;
119 (pos.0 - source_file_start.0, bytes as u32)
122 fn stable_non_narrow_char(
123 swc: rustc_span::NonNarrowChar,
124 source_file_start: BytePos,
127 let width = swc.width();
129 (pos.0 - source_file_start.0, width as u32)
132 fn stable_normalized_pos(np: NormalizedPos, source_file_start: BytePos) -> (u32, u32) {
133 let NormalizedPos { pos, diff } = np;
135 (pos.0 - source_file_start.0, diff)
138 impl<'tcx> HashStable<StableHashingContext<'tcx>> for rustc_feature::Features {
139 fn hash_stable(&self, hcx: &mut StableHashingContext<'tcx>, hasher: &mut StableHasher) {
140 // Unfortunately we cannot exhaustively list fields here, since the
141 // struct is macro generated.
142 self.declared_lang_features.hash_stable(hcx, hasher);
143 self.declared_lib_features.hash_stable(hcx, hasher);
145 self.walk_feature_fields(|feature_name, value| {
146 feature_name.hash_stable(hcx, hasher);
147 value.hash_stable(hcx, hasher);
152 impl<'ctx> rustc_type_ir::HashStableContext for StableHashingContext<'ctx> {}