1 //! This module contains `HashStable` implementations for various data types
2 //! from libsyntax in no particular order.
4 use crate::ich::StableHashingContext;
6 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
7 use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX};
8 use rustc_span::SourceFile;
11 use smallvec::SmallVec;
13 impl<'ctx> rustc_target::HashStableContext for StableHashingContext<'ctx> {}
15 impl<'a> HashStable<StableHashingContext<'a>> for ast::Lifetime {
16 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
17 self.id.hash_stable(hcx, hasher);
18 self.ident.hash_stable(hcx, hasher);
22 impl<'a> HashStable<StableHashingContext<'a>> for [ast::Attribute] {
23 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
25 self.len().hash_stable(hcx, hasher);
29 // Some attributes are always ignored during hashing.
30 let filtered: SmallVec<[&ast::Attribute; 8]> = self
33 !attr.is_doc_comment()
34 && !attr.ident().map_or(false, |ident| hcx.is_ignored_attr(ident.name))
38 filtered.len().hash_stable(hcx, hasher);
39 for attr in filtered {
40 attr.hash_stable(hcx, hasher);
45 impl<'ctx> syntax::HashStableContext for StableHashingContext<'ctx> {
46 fn hash_attr(&mut self, attr: &ast::Attribute, hasher: &mut StableHasher) {
47 // Make sure that these have been filtered out.
48 debug_assert!(!attr.ident().map_or(false, |ident| self.is_ignored_attr(ident.name)));
49 debug_assert!(!attr.is_doc_comment());
51 let ast::Attribute { kind, id: _, style, span } = attr;
52 if let ast::AttrKind::Normal(item) = kind {
53 item.hash_stable(self, hasher);
54 style.hash_stable(self, hasher);
55 span.hash_stable(self, hasher);
62 impl<'a> HashStable<StableHashingContext<'a>> for SourceFile {
63 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
65 name: _, // We hash the smaller name_hash instead of this
70 // Do not hash the source as it is not encoded
82 (name_hash as u64).hash_stable(hcx, hasher);
83 name_was_remapped.hash_stable(hcx, hasher);
85 DefId { krate: CrateNum::from_u32(crate_of_origin), index: CRATE_DEF_INDEX }
86 .hash_stable(hcx, hasher);
88 src_hash.hash_stable(hcx, hasher);
90 // We only hash the relative position within this source_file
91 lines.len().hash_stable(hcx, hasher);
92 for &line in lines.iter() {
93 stable_byte_pos(line, start_pos).hash_stable(hcx, hasher);
96 // We only hash the relative position within this source_file
97 multibyte_chars.len().hash_stable(hcx, hasher);
98 for &char_pos in multibyte_chars.iter() {
99 stable_multibyte_char(char_pos, start_pos).hash_stable(hcx, hasher);
102 non_narrow_chars.len().hash_stable(hcx, hasher);
103 for &char_pos in non_narrow_chars.iter() {
104 stable_non_narrow_char(char_pos, start_pos).hash_stable(hcx, hasher);
107 normalized_pos.len().hash_stable(hcx, hasher);
108 for &char_pos in normalized_pos.iter() {
109 stable_normalized_pos(char_pos, start_pos).hash_stable(hcx, hasher);
114 fn stable_byte_pos(pos: ::rustc_span::BytePos, source_file_start: ::rustc_span::BytePos) -> u32 {
115 pos.0 - source_file_start.0
118 fn stable_multibyte_char(
119 mbc: ::rustc_span::MultiByteChar,
120 source_file_start: ::rustc_span::BytePos,
122 let ::rustc_span::MultiByteChar { pos, bytes } = mbc;
124 (pos.0 - source_file_start.0, bytes as u32)
127 fn stable_non_narrow_char(
128 swc: ::rustc_span::NonNarrowChar,
129 source_file_start: ::rustc_span::BytePos,
132 let width = swc.width();
134 (pos.0 - source_file_start.0, width as u32)
137 fn stable_normalized_pos(
138 np: ::rustc_span::NormalizedPos,
139 source_file_start: ::rustc_span::BytePos,
141 let ::rustc_span::NormalizedPos { pos, diff } = np;
143 (pos.0 - source_file_start.0, diff)
146 impl<'tcx> HashStable<StableHashingContext<'tcx>> for rustc_feature::Features {
147 fn hash_stable(&self, hcx: &mut StableHashingContext<'tcx>, hasher: &mut StableHasher) {
148 // Unfortunately we cannot exhaustively list fields here, since the
149 // struct is macro generated.
150 self.declared_lang_features.hash_stable(hcx, hasher);
151 self.declared_lib_features.hash_stable(hcx, hasher);
153 self.walk_feature_fields(|feature_name, value| {
154 feature_name.hash_stable(hcx, hasher);
155 value.hash_stable(hcx, hasher);