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