]> git.lizzy.rs Git - rust.git/blob - src/librustc/ich/impls_syntax.rs
144980c53eb5fe7188c51332d52f59acc0eddb20
[rust.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::feature_gate;
8 use syntax_pos::SourceFile;
9
10 use crate::hir::def_id::{DefId, CrateNum, CRATE_DEF_INDEX};
11
12 use smallvec::SmallVec;
13 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
14
15 impl<'ctx> rustc_target::HashStableContext for StableHashingContext<'ctx> {}
16
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);
21     }
22 }
23
24 impl<'a> HashStable<StableHashingContext<'a>> for [ast::Attribute] {
25     fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
26         if self.len() == 0 {
27             self.len().hash_stable(hcx, hasher);
28             return
29         }
30
31         // Some attributes are always ignored during hashing.
32         let filtered: SmallVec<[&ast::Attribute; 8]> = self
33             .iter()
34             .filter(|attr| {
35                 !attr.is_doc_comment() &&
36                 !attr.ident().map_or(false, |ident| hcx.is_ignored_attr(ident.name))
37             })
38             .collect();
39
40         filtered.len().hash_stable(hcx, hasher);
41         for attr in filtered {
42             attr.hash_stable(hcx, hasher);
43         }
44     }
45 }
46
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());
52
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);
58         } else {
59             unreachable!();
60         }
61     }
62 }
63
64 impl<'ctx> syntax::HashStableContext for StableHashingContext<'ctx> {}
65
66 impl<'a> HashStable<StableHashingContext<'a>> for SourceFile {
67     fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
68         let SourceFile {
69             name: _, // We hash the smaller name_hash instead of this
70             name_hash,
71             name_was_remapped,
72             unmapped_path: _,
73             crate_of_origin,
74             // Do not hash the source as it is not encoded
75             src: _,
76             src_hash,
77             external_src: _,
78             start_pos,
79             end_pos: _,
80             ref lines,
81             ref multibyte_chars,
82             ref non_narrow_chars,
83             ref normalized_pos,
84         } = *self;
85
86         (name_hash as u64).hash_stable(hcx, hasher);
87         name_was_remapped.hash_stable(hcx, hasher);
88
89         DefId {
90             krate: CrateNum::from_u32(crate_of_origin),
91             index: CRATE_DEF_INDEX,
92         }.hash_stable(hcx, hasher);
93
94         src_hash.hash_stable(hcx, hasher);
95
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);
100         }
101
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);
106         }
107
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);
111         }
112
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);
116         }
117
118     }
119 }
120
121 fn stable_byte_pos(pos: ::syntax_pos::BytePos,
122                    source_file_start: ::syntax_pos::BytePos)
123                    -> u32 {
124     pos.0 - source_file_start.0
125 }
126
127 fn stable_multibyte_char(mbc: ::syntax_pos::MultiByteChar,
128                          source_file_start: ::syntax_pos::BytePos)
129                          -> (u32, u32) {
130     let ::syntax_pos::MultiByteChar {
131         pos,
132         bytes,
133     } = mbc;
134
135     (pos.0 - source_file_start.0, bytes as u32)
136 }
137
138 fn stable_non_narrow_char(swc: ::syntax_pos::NonNarrowChar,
139                           source_file_start: ::syntax_pos::BytePos)
140                           -> (u32, u32) {
141     let pos = swc.pos();
142     let width = swc.width();
143
144     (pos.0 - source_file_start.0, width as u32)
145 }
146
147 fn stable_normalized_pos(np: ::syntax_pos::NormalizedPos,
148                          source_file_start: ::syntax_pos::BytePos)
149                          -> (u32, u32) {
150     let ::syntax_pos::NormalizedPos {
151         pos,
152         diff
153     } = np;
154
155     (pos.0 - source_file_start.0, diff)
156 }
157
158
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);
165
166         self.walk_feature_fields(|feature_name, value| {
167             feature_name.hash_stable(hcx, hasher);
168             value.hash_stable(hcx, hasher);
169         });
170     }
171 }