Files
rust/src/librustc/ich/impls_syntax.rs

237 lines
7.5 KiB
Rust
Raw Normal View History

//! This module contains `HashStable` implementations for various data types
//! from libsyntax in no particular order.
2019-02-05 11:20:45 -06:00
use crate::ich::StableHashingContext;
use std::hash as std_hash;
use std::mem;
use syntax::ast;
2018-02-14 16:11:02 +01:00
use syntax::feature_gate;
2019-10-11 12:46:32 +02:00
use syntax::token;
2018-08-18 12:13:52 +02:00
use syntax_pos::SourceFile;
2019-02-05 11:20:45 -06:00
use crate::hir::def_id::{DefId, CrateNum, CRATE_DEF_INDEX};
use smallvec::SmallVec;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
impl<'ctx> rustc_target::HashStableContext for StableHashingContext<'ctx> {}
2019-11-10 19:32:04 +01:00
impl<'a> HashStable<StableHashingContext<'a>> for ast::Lifetime {
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
self.id.hash_stable(hcx, hasher);
self.ident.hash_stable(hcx, hasher);
}
}
impl<'a> HashStable<StableHashingContext<'a>> for [ast::Attribute] {
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
if self.len() == 0 {
self.len().hash_stable(hcx, hasher);
return
}
// Some attributes are always ignored during hashing.
let filtered: SmallVec<[&ast::Attribute; 8]> = self
.iter()
.filter(|attr| {
!attr.is_doc_comment() &&
!attr.ident().map_or(false, |ident| hcx.is_ignored_attr(ident.name))
})
.collect();
filtered.len().hash_stable(hcx, hasher);
for attr in filtered {
attr.hash_stable(hcx, hasher);
}
}
}
impl<'a> HashStable<StableHashingContext<'a>> for ast::Attribute {
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
// Make sure that these have been filtered out.
debug_assert!(!self.ident().map_or(false, |ident| hcx.is_ignored_attr(ident.name)));
debug_assert!(!self.is_doc_comment());
let ast::Attribute { kind, id: _, style, span } = self;
if let ast::AttrKind::Normal(item) = kind {
item.hash_stable(hcx, hasher);
style.hash_stable(hcx, hasher);
span.hash_stable(hcx, hasher);
} else {
unreachable!();
}
}
}
impl<'ctx> syntax::HashStableContext for StableHashingContext<'ctx> {
fn hash_stable_tokenkind(&mut self, tokenkind: &token::TokenKind, hasher: &mut StableHasher) {
mem::discriminant(tokenkind).hash_stable(self, hasher);
match *tokenkind {
token::Eq |
token::Lt |
token::Le |
token::EqEq |
token::Ne |
token::Ge |
token::Gt |
token::AndAnd |
token::OrOr |
token::Not |
token::Tilde |
token::At |
token::Dot |
token::DotDot |
token::DotDotDot |
token::DotDotEq |
token::Comma |
token::Semi |
token::Colon |
token::ModSep |
token::RArrow |
token::LArrow |
token::FatArrow |
token::Pound |
token::Dollar |
token::Question |
token::SingleQuote |
token::Whitespace |
token::Comment |
token::Eof => {}
token::BinOp(bin_op_token) |
token::BinOpEq(bin_op_token) => {
std_hash::Hash::hash(&bin_op_token, hasher);
}
token::OpenDelim(delim_token) |
token::CloseDelim(delim_token) => {
std_hash::Hash::hash(&delim_token, hasher);
}
token::Literal(lit) => lit.hash_stable(self, hasher),
token::Ident(name, is_raw) => {
name.hash_stable(self, hasher);
is_raw.hash_stable(self, hasher);
}
token::Lifetime(name) => name.hash_stable(self, hasher),
token::Interpolated(_) => {
bug!("interpolated tokens should not be present in the HIR")
}
token::DocComment(val) |
2019-07-30 12:31:41 +03:00
token::Shebang(val) |
token::Unknown(val) => val.hash_stable(self, hasher),
}
}
}
2018-08-18 12:13:52 +02:00
impl<'a> HashStable<StableHashingContext<'a>> for SourceFile {
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
2018-08-18 12:13:52 +02:00
let SourceFile {
name: _, // We hash the smaller name_hash instead of this
name_hash,
name_was_remapped,
unmapped_path: _,
crate_of_origin,
// Do not hash the source as it is not encoded
src: _,
src_hash,
external_src: _,
start_pos,
end_pos: _,
ref lines,
ref multibyte_chars,
ref non_narrow_chars,
ref normalized_pos,
} = *self;
(name_hash as u64).hash_stable(hcx, hasher);
name_was_remapped.hash_stable(hcx, hasher);
DefId {
krate: CrateNum::from_u32(crate_of_origin),
index: CRATE_DEF_INDEX,
}.hash_stable(hcx, hasher);
src_hash.hash_stable(hcx, hasher);
2018-08-18 12:13:56 +02:00
// We only hash the relative position within this source_file
lines.len().hash_stable(hcx, hasher);
for &line in lines.iter() {
stable_byte_pos(line, start_pos).hash_stable(hcx, hasher);
}
2018-08-18 12:13:56 +02:00
// We only hash the relative position within this source_file
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);
}
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);
}
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);
}
}
}
fn stable_byte_pos(pos: ::syntax_pos::BytePos,
2018-08-18 12:13:56 +02:00
source_file_start: ::syntax_pos::BytePos)
-> u32 {
2018-08-18 12:13:56 +02:00
pos.0 - source_file_start.0
}
fn stable_multibyte_char(mbc: ::syntax_pos::MultiByteChar,
2018-08-18 12:13:56 +02:00
source_file_start: ::syntax_pos::BytePos)
-> (u32, u32) {
let ::syntax_pos::MultiByteChar {
pos,
bytes,
} = mbc;
2018-08-18 12:13:56 +02:00
(pos.0 - source_file_start.0, bytes as u32)
}
fn stable_non_narrow_char(swc: ::syntax_pos::NonNarrowChar,
2018-08-18 12:13:56 +02:00
source_file_start: ::syntax_pos::BytePos)
-> (u32, u32) {
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)
}
2018-02-14 16:11:02 +01:00
fn stable_normalized_pos(np: ::syntax_pos::NormalizedPos,
source_file_start: ::syntax_pos::BytePos)
-> (u32, u32) {
let ::syntax_pos::NormalizedPos {
pos,
diff
} = np;
(pos.0 - source_file_start.0, diff)
}
2019-06-14 00:48:52 +03:00
impl<'tcx> HashStable<StableHashingContext<'tcx>> for feature_gate::Features {
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);
});
}
}