1 //! This module contains `HashStable` implementations for various data types
2 //! from libsyntax in no particular order.
4 use crate::ich::StableHashingContext;
7 use syntax::feature_gate;
8 use syntax_pos::SourceFile;
10 use crate::hir::def_id::{DefId, CrateNum, CRATE_DEF_INDEX};
12 use smallvec::SmallVec;
13 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
15 impl<'ctx> rustc_target::HashStableContext for StableHashingContext<'ctx> {}
17 impl<'a> HashStable<StableHashingContext<'a>> for ast::Lifetime {
18 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
19 self.id.hash_stable(hcx, hasher);
20 self.ident.hash_stable(hcx, hasher);
24 impl<'a> HashStable<StableHashingContext<'a>> for [ast::Attribute] {
25 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
27 self.len().hash_stable(hcx, hasher);
31 // Some attributes are always ignored during hashing.
32 let filtered: SmallVec<[&ast::Attribute; 8]> = self
35 !attr.is_doc_comment() &&
36 !attr.ident().map_or(false, |ident| hcx.is_ignored_attr(ident.name))
40 filtered.len().hash_stable(hcx, hasher);
41 for attr in filtered {
42 attr.hash_stable(hcx, hasher);
47 impl<'a> HashStable<StableHashingContext<'a>> for ast::Attribute {
48 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
49 // Make sure that these have been filtered out.
50 debug_assert!(!self.ident().map_or(false, |ident| hcx.is_ignored_attr(ident.name)));
51 debug_assert!(!self.is_doc_comment());
53 let ast::Attribute { kind, id: _, style, span } = self;
54 if let ast::AttrKind::Normal(item) = kind {
55 item.hash_stable(hcx, hasher);
56 style.hash_stable(hcx, hasher);
57 span.hash_stable(hcx, hasher);
64 impl<'ctx> syntax::HashStableContext for StableHashingContext<'ctx> {}
66 impl<'a> HashStable<StableHashingContext<'a>> for SourceFile {
67 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
69 name: _, // We hash the smaller name_hash instead of this
74 // Do not hash the source as it is not encoded
86 (name_hash as u64).hash_stable(hcx, hasher);
87 name_was_remapped.hash_stable(hcx, hasher);
90 krate: CrateNum::from_u32(crate_of_origin),
91 index: CRATE_DEF_INDEX,
92 }.hash_stable(hcx, hasher);
94 src_hash.hash_stable(hcx, hasher);
96 // We only hash the relative position within this source_file
97 lines.len().hash_stable(hcx, hasher);
98 for &line in lines.iter() {
99 stable_byte_pos(line, start_pos).hash_stable(hcx, hasher);
102 // We only hash the relative position within this source_file
103 multibyte_chars.len().hash_stable(hcx, hasher);
104 for &char_pos in multibyte_chars.iter() {
105 stable_multibyte_char(char_pos, start_pos).hash_stable(hcx, hasher);
108 non_narrow_chars.len().hash_stable(hcx, hasher);
109 for &char_pos in non_narrow_chars.iter() {
110 stable_non_narrow_char(char_pos, start_pos).hash_stable(hcx, hasher);
113 normalized_pos.len().hash_stable(hcx, hasher);
114 for &char_pos in normalized_pos.iter() {
115 stable_normalized_pos(char_pos, start_pos).hash_stable(hcx, hasher);
121 fn stable_byte_pos(pos: ::syntax_pos::BytePos,
122 source_file_start: ::syntax_pos::BytePos)
124 pos.0 - source_file_start.0
127 fn stable_multibyte_char(mbc: ::syntax_pos::MultiByteChar,
128 source_file_start: ::syntax_pos::BytePos)
130 let ::syntax_pos::MultiByteChar {
135 (pos.0 - source_file_start.0, bytes as u32)
138 fn stable_non_narrow_char(swc: ::syntax_pos::NonNarrowChar,
139 source_file_start: ::syntax_pos::BytePos)
142 let width = swc.width();
144 (pos.0 - source_file_start.0, width as u32)
147 fn stable_normalized_pos(np: ::syntax_pos::NormalizedPos,
148 source_file_start: ::syntax_pos::BytePos)
150 let ::syntax_pos::NormalizedPos {
155 (pos.0 - source_file_start.0, diff)
159 impl<'tcx> HashStable<StableHashingContext<'tcx>> for feature_gate::Features {
160 fn hash_stable(&self, hcx: &mut StableHashingContext<'tcx>, hasher: &mut StableHasher) {
161 // Unfortunately we cannot exhaustively list fields here, since the
162 // struct is macro generated.
163 self.declared_lang_features.hash_stable(hcx, hasher);
164 self.declared_lib_features.hash_stable(hcx, hasher);
166 self.walk_feature_fields(|feature_name, value| {
167 feature_name.hash_stable(hcx, hasher);
168 value.hash_stable(hcx, hasher);