2017-03-30 15:27:27 +02:00
|
|
|
//! This module contains `HashStable` implementations for various data types
|
2020-02-29 20:16:26 +03:00
|
|
|
//! from librustc_ast in no particular order.
|
2017-03-30 15:27:27 +02:00
|
|
|
|
2019-02-05 11:20:45 -06:00
|
|
|
use crate::ich::StableHashingContext;
|
2017-03-30 15:27:27 +02:00
|
|
|
|
2020-04-27 23:26:11 +05:30
|
|
|
use rustc_ast as ast;
|
2020-01-05 02:37:57 +01:00
|
|
|
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
2020-10-13 10:17:05 +02:00
|
|
|
use rustc_span::{BytePos, NormalizedPos, SourceFile};
|
2017-04-27 16:12:57 +02:00
|
|
|
|
2019-12-22 17:42:04 -05:00
|
|
|
use smallvec::SmallVec;
|
2017-09-12 17:07:09 +02:00
|
|
|
|
2019-11-23 13:58:17 +01:00
|
|
|
impl<'ctx> rustc_target::HashStableContext for StableHashingContext<'ctx> {}
|
2019-11-10 17:19:08 +01:00
|
|
|
|
2018-01-16 10:16:38 +01:00
|
|
|
impl<'a> HashStable<StableHashingContext<'a>> for [ast::Attribute] {
|
2019-09-26 18:54:39 -04:00
|
|
|
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
|
2020-02-28 14:20:33 +01:00
|
|
|
if self.is_empty() {
|
2017-09-14 12:29:16 +02:00
|
|
|
self.len().hash_stable(hcx, hasher);
|
2019-12-22 17:42:04 -05:00
|
|
|
return;
|
2017-09-14 12:29:16 +02:00
|
|
|
}
|
|
|
|
|
|
2017-03-30 15:27:27 +02:00
|
|
|
// Some attributes are always ignored during hashing.
|
2018-08-24 13:51:32 +10:00
|
|
|
let filtered: SmallVec<[&ast::Attribute; 8]> = self
|
2017-03-30 15:27:27 +02:00
|
|
|
.iter()
|
|
|
|
|
.filter(|attr| {
|
2019-12-22 17:42:04 -05:00
|
|
|
!attr.is_doc_comment()
|
|
|
|
|
&& !attr.ident().map_or(false, |ident| hcx.is_ignored_attr(ident.name))
|
2017-03-30 15:27:27 +02:00
|
|
|
})
|
|
|
|
|
.collect();
|
|
|
|
|
|
|
|
|
|
filtered.len().hash_stable(hcx, hasher);
|
|
|
|
|
for attr in filtered {
|
|
|
|
|
attr.hash_stable(hcx, hasher);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-29 20:37:32 +03:00
|
|
|
impl<'ctx> rustc_ast::HashStableContext for StableHashingContext<'ctx> {
|
2020-01-02 05:18:45 +01:00
|
|
|
fn hash_attr(&mut self, attr: &ast::Attribute, hasher: &mut StableHasher) {
|
2017-03-30 15:27:27 +02:00
|
|
|
// Make sure that these have been filtered out.
|
2020-01-02 05:18:45 +01:00
|
|
|
debug_assert!(!attr.ident().map_or(false, |ident| self.is_ignored_attr(ident.name)));
|
|
|
|
|
debug_assert!(!attr.is_doc_comment());
|
2019-10-24 06:33:12 +11:00
|
|
|
|
2020-11-05 20:27:48 +03:00
|
|
|
let ast::Attribute { kind, id: _, style, span } = attr;
|
|
|
|
|
if let ast::AttrKind::Normal(item, tokens) = kind {
|
2020-01-02 05:18:45 +01:00
|
|
|
item.hash_stable(self, hasher);
|
|
|
|
|
style.hash_stable(self, hasher);
|
|
|
|
|
span.hash_stable(self, hasher);
|
2020-09-26 19:33:42 -04:00
|
|
|
tokens.as_ref().expect_none("Tokens should have been removed during lowering!");
|
2019-10-24 06:33:12 +11:00
|
|
|
} else {
|
|
|
|
|
unreachable!();
|
|
|
|
|
}
|
2017-03-30 15:27:27 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-08-18 12:13:52 +02:00
|
|
|
impl<'a> HashStable<StableHashingContext<'a>> for SourceFile {
|
2019-09-26 18:54:39 -04:00
|
|
|
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
|
2018-08-18 12:13:52 +02:00
|
|
|
let SourceFile {
|
2017-12-19 15:14:41 +01:00
|
|
|
name: _, // We hash the smaller name_hash instead of this
|
|
|
|
|
name_hash,
|
2017-04-27 16:12:57 +02:00
|
|
|
name_was_remapped,
|
2017-10-03 19:44:58 +10:00
|
|
|
unmapped_path: _,
|
2020-02-07 14:02:24 -05:00
|
|
|
cnum,
|
2017-04-27 16:12:57 +02:00
|
|
|
// Do not hash the source as it is not encoded
|
|
|
|
|
src: _,
|
2020-03-30 22:17:15 -07:00
|
|
|
ref src_hash,
|
2017-06-10 21:08:32 +02:00
|
|
|
external_src: _,
|
2017-04-27 16:12:57 +02:00
|
|
|
start_pos,
|
|
|
|
|
end_pos: _,
|
|
|
|
|
ref lines,
|
|
|
|
|
ref multibyte_chars,
|
2017-11-02 10:25:54 +09:00
|
|
|
ref non_narrow_chars,
|
2019-10-03 03:55:31 +03:00
|
|
|
ref normalized_pos,
|
2017-04-27 16:12:57 +02:00
|
|
|
} = *self;
|
|
|
|
|
|
2017-12-19 15:14:41 +01:00
|
|
|
(name_hash as u64).hash_stable(hcx, hasher);
|
2017-04-27 16:12:57 +02:00
|
|
|
name_was_remapped.hash_stable(hcx, hasher);
|
|
|
|
|
|
2017-06-10 13:39:39 +02:00
|
|
|
src_hash.hash_stable(hcx, hasher);
|
|
|
|
|
|
2018-08-18 12:13:56 +02:00
|
|
|
// We only hash the relative position within this source_file
|
2018-05-23 15:59:42 +02:00
|
|
|
lines.len().hash_stable(hcx, hasher);
|
|
|
|
|
for &line in lines.iter() {
|
|
|
|
|
stable_byte_pos(line, start_pos).hash_stable(hcx, hasher);
|
|
|
|
|
}
|
2017-04-27 16:12:57 +02:00
|
|
|
|
2018-08-18 12:13:56 +02:00
|
|
|
// We only hash the relative position within this source_file
|
2018-05-23 15:59:42 +02:00
|
|
|
multibyte_chars.len().hash_stable(hcx, hasher);
|
|
|
|
|
for &char_pos in multibyte_chars.iter() {
|
|
|
|
|
stable_multibyte_char(char_pos, start_pos).hash_stable(hcx, hasher);
|
|
|
|
|
}
|
2017-11-02 10:25:54 +09:00
|
|
|
|
2018-05-23 15:59:42 +02:00
|
|
|
non_narrow_chars.len().hash_stable(hcx, hasher);
|
|
|
|
|
for &char_pos in non_narrow_chars.iter() {
|
|
|
|
|
stable_non_narrow_char(char_pos, start_pos).hash_stable(hcx, hasher);
|
|
|
|
|
}
|
2019-10-03 03:55:31 +03:00
|
|
|
|
|
|
|
|
normalized_pos.len().hash_stable(hcx, hasher);
|
|
|
|
|
for &char_pos in normalized_pos.iter() {
|
|
|
|
|
stable_normalized_pos(char_pos, start_pos).hash_stable(hcx, hasher);
|
|
|
|
|
}
|
2020-02-07 14:02:24 -05:00
|
|
|
|
|
|
|
|
cnum.hash_stable(hcx, hasher);
|
2017-04-27 16:12:57 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-13 10:17:05 +02:00
|
|
|
fn stable_byte_pos(pos: BytePos, source_file_start: BytePos) -> u32 {
|
2018-08-18 12:13:56 +02:00
|
|
|
pos.0 - source_file_start.0
|
2017-04-27 16:12:57 +02:00
|
|
|
}
|
|
|
|
|
|
2020-10-13 10:17:05 +02:00
|
|
|
fn stable_multibyte_char(mbc: rustc_span::MultiByteChar, source_file_start: BytePos) -> (u32, u32) {
|
|
|
|
|
let rustc_span::MultiByteChar { pos, bytes } = mbc;
|
2017-04-27 16:12:57 +02:00
|
|
|
|
2018-08-18 12:13:56 +02:00
|
|
|
(pos.0 - source_file_start.0, bytes as u32)
|
2017-04-27 16:12:57 +02:00
|
|
|
}
|
2017-11-02 10:25:54 +09:00
|
|
|
|
2019-12-22 17:42:04 -05:00
|
|
|
fn stable_non_narrow_char(
|
2020-10-13 10:17:05 +02:00
|
|
|
swc: rustc_span::NonNarrowChar,
|
|
|
|
|
source_file_start: BytePos,
|
2019-12-22 17:42:04 -05:00
|
|
|
) -> (u32, u32) {
|
2017-11-02 10:25:54 +09:00
|
|
|
let pos = swc.pos();
|
|
|
|
|
let width = swc.width();
|
|
|
|
|
|
2018-08-18 12:13:56 +02:00
|
|
|
(pos.0 - source_file_start.0, width as u32)
|
2017-11-02 10:25:54 +09:00
|
|
|
}
|
2018-02-14 16:11:02 +01:00
|
|
|
|
2020-10-13 10:17:05 +02:00
|
|
|
fn stable_normalized_pos(np: NormalizedPos, source_file_start: BytePos) -> (u32, u32) {
|
|
|
|
|
let NormalizedPos { pos, diff } = np;
|
2019-10-03 03:55:31 +03:00
|
|
|
|
|
|
|
|
(pos.0 - source_file_start.0, diff)
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-30 00:23:38 +01:00
|
|
|
impl<'tcx> HashStable<StableHashingContext<'tcx>> for rustc_feature::Features {
|
2019-09-26 18:54:39 -04:00
|
|
|
fn hash_stable(&self, hcx: &mut StableHashingContext<'tcx>, hasher: &mut StableHasher) {
|
2018-02-14 16:11:02 +01:00
|
|
|
// Unfortunately we cannot exhaustively list fields here, since the
|
|
|
|
|
// struct is macro generated.
|
2018-07-23 02:03:01 +01:00
|
|
|
self.declared_lang_features.hash_stable(hcx, hasher);
|
2018-02-14 16:11:02 +01:00
|
|
|
self.declared_lib_features.hash_stable(hcx, hasher);
|
|
|
|
|
|
|
|
|
|
self.walk_feature_fields(|feature_name, value| {
|
|
|
|
|
feature_name.hash_stable(hcx, hasher);
|
|
|
|
|
value.hash_stable(hcx, hasher);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|