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