]> git.proxmox.com Git - rustc.git/blob - src/librustc/ich/impls_syntax.rs
New upstream version 1.41.1+dfsg1
[rustc.git] / src / librustc / ich / impls_syntax.rs
1 //! This module contains `HashStable` implementations for various data types
2 //! from libsyntax in no particular order.
3
4 use crate::ich::StableHashingContext;
5
6 use syntax::ast;
7 use syntax_pos::SourceFile;
8
9 use crate::hir::def_id::{DefId, CrateNum, CRATE_DEF_INDEX};
10
11 use smallvec::SmallVec;
12 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
13
14 impl<'ctx> rustc_target::HashStableContext for StableHashingContext<'ctx> {}
15
16 impl<'a> HashStable<StableHashingContext<'a>> for ast::Lifetime {
17 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
18 self.id.hash_stable(hcx, hasher);
19 self.ident.hash_stable(hcx, hasher);
20 }
21 }
22
23 impl<'a> HashStable<StableHashingContext<'a>> for [ast::Attribute] {
24 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
25 if self.len() == 0 {
26 self.len().hash_stable(hcx, hasher);
27 return
28 }
29
30 // Some attributes are always ignored during hashing.
31 let filtered: SmallVec<[&ast::Attribute; 8]> = self
32 .iter()
33 .filter(|attr| {
34 !attr.is_doc_comment() &&
35 !attr.ident().map_or(false, |ident| hcx.is_ignored_attr(ident.name))
36 })
37 .collect();
38
39 filtered.len().hash_stable(hcx, hasher);
40 for attr in filtered {
41 attr.hash_stable(hcx, hasher);
42 }
43 }
44 }
45
46 impl<'a> HashStable<StableHashingContext<'a>> for ast::Attribute {
47 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
48 // Make sure that these have been filtered out.
49 debug_assert!(!self.ident().map_or(false, |ident| hcx.is_ignored_attr(ident.name)));
50 debug_assert!(!self.is_doc_comment());
51
52 let ast::Attribute { kind, id: _, style, span } = self;
53 if let ast::AttrKind::Normal(item) = kind {
54 item.hash_stable(hcx, hasher);
55 style.hash_stable(hcx, hasher);
56 span.hash_stable(hcx, hasher);
57 } else {
58 unreachable!();
59 }
60 }
61 }
62
63 impl<'ctx> syntax::HashStableContext for StableHashingContext<'ctx> {}
64
65 impl<'a> HashStable<StableHashingContext<'a>> for SourceFile {
66 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
67 let SourceFile {
68 name: _, // We hash the smaller name_hash instead of this
69 name_hash,
70 name_was_remapped,
71 unmapped_path: _,
72 crate_of_origin,
73 // Do not hash the source as it is not encoded
74 src: _,
75 src_hash,
76 external_src: _,
77 start_pos,
78 end_pos: _,
79 ref lines,
80 ref multibyte_chars,
81 ref non_narrow_chars,
82 ref normalized_pos,
83 } = *self;
84
85 (name_hash as u64).hash_stable(hcx, hasher);
86 name_was_remapped.hash_stable(hcx, hasher);
87
88 DefId {
89 krate: CrateNum::from_u32(crate_of_origin),
90 index: CRATE_DEF_INDEX,
91 }.hash_stable(hcx, hasher);
92
93 src_hash.hash_stable(hcx, hasher);
94
95 // We only hash the relative position within this source_file
96 lines.len().hash_stable(hcx, hasher);
97 for &line in lines.iter() {
98 stable_byte_pos(line, start_pos).hash_stable(hcx, hasher);
99 }
100
101 // We only hash the relative position within this source_file
102 multibyte_chars.len().hash_stable(hcx, hasher);
103 for &char_pos in multibyte_chars.iter() {
104 stable_multibyte_char(char_pos, start_pos).hash_stable(hcx, hasher);
105 }
106
107 non_narrow_chars.len().hash_stable(hcx, hasher);
108 for &char_pos in non_narrow_chars.iter() {
109 stable_non_narrow_char(char_pos, start_pos).hash_stable(hcx, hasher);
110 }
111
112 normalized_pos.len().hash_stable(hcx, hasher);
113 for &char_pos in normalized_pos.iter() {
114 stable_normalized_pos(char_pos, start_pos).hash_stable(hcx, hasher);
115 }
116
117 }
118 }
119
120 fn stable_byte_pos(pos: ::syntax_pos::BytePos,
121 source_file_start: ::syntax_pos::BytePos)
122 -> u32 {
123 pos.0 - source_file_start.0
124 }
125
126 fn stable_multibyte_char(mbc: ::syntax_pos::MultiByteChar,
127 source_file_start: ::syntax_pos::BytePos)
128 -> (u32, u32) {
129 let ::syntax_pos::MultiByteChar {
130 pos,
131 bytes,
132 } = mbc;
133
134 (pos.0 - source_file_start.0, bytes as u32)
135 }
136
137 fn stable_non_narrow_char(swc: ::syntax_pos::NonNarrowChar,
138 source_file_start: ::syntax_pos::BytePos)
139 -> (u32, u32) {
140 let pos = swc.pos();
141 let width = swc.width();
142
143 (pos.0 - source_file_start.0, width as u32)
144 }
145
146 fn stable_normalized_pos(np: ::syntax_pos::NormalizedPos,
147 source_file_start: ::syntax_pos::BytePos)
148 -> (u32, u32) {
149 let ::syntax_pos::NormalizedPos {
150 pos,
151 diff
152 } = np;
153
154 (pos.0 - source_file_start.0, diff)
155 }
156
157
158 impl<'tcx> HashStable<StableHashingContext<'tcx>> for rustc_feature::Features {
159 fn hash_stable(&self, hcx: &mut StableHashingContext<'tcx>, hasher: &mut StableHasher) {
160 // Unfortunately we cannot exhaustively list fields here, since the
161 // struct is macro generated.
162 self.declared_lang_features.hash_stable(hcx, hasher);
163 self.declared_lib_features.hash_stable(hcx, hasher);
164
165 self.walk_feature_fields(|feature_name, value| {
166 feature_name.hash_stable(hcx, hasher);
167 value.hash_stable(hcx, hasher);
168 });
169 }
170 }