Move HashStable implementations.

This commit is contained in:
Camille GILLOT 2021-06-22 19:16:18 +02:00
parent 72568552fd
commit cff0ea5f88
2 changed files with 60 additions and 61 deletions

View File

@ -27,7 +27,7 @@
use crate::edition::Edition;
use crate::symbol::{kw, sym, Symbol};
use crate::with_session_globals;
use crate::{BytePos, CachingSourceMapView, ExpnIdCache, SourceFile, Span, DUMMY_SP};
use crate::{BytePos, CachingSourceMapView, HashStableContext, SourceFile, Span, DUMMY_SP};
use crate::def_id::{CrateNum, DefId, DefPathHash, CRATE_DEF_INDEX, LOCAL_CRATE};
use rustc_data_structures::fingerprint::Fingerprint;
@ -36,6 +36,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::sync::{Lock, Lrc};
use rustc_macros::HashStable_Generic;
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
use std::cell::RefCell;
use std::fmt;
use std::hash::Hash;
use std::thread::LocalKey;
@ -1407,3 +1408,60 @@ fn update_disambiguator(expn_id: ExpnId) {
};
}
}
impl<CTX: HashStableContext> HashStable<CTX> for SyntaxContext {
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
const TAG_EXPANSION: u8 = 0;
const TAG_NO_EXPANSION: u8 = 1;
if *self == SyntaxContext::root() {
TAG_NO_EXPANSION.hash_stable(ctx, hasher);
} else {
TAG_EXPANSION.hash_stable(ctx, hasher);
let (expn_id, transparency) = self.outer_mark();
expn_id.hash_stable(ctx, hasher);
transparency.hash_stable(ctx, hasher);
}
}
}
pub type ExpnIdCache = RefCell<Vec<Option<Fingerprint>>>;
impl<CTX: HashStableContext> HashStable<CTX> for ExpnId {
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
const TAG_ROOT: u8 = 0;
const TAG_NOT_ROOT: u8 = 1;
if *self == ExpnId::root() {
TAG_ROOT.hash_stable(ctx, hasher);
return;
}
// Since the same expansion context is usually referenced many
// times, we cache a stable hash of it and hash that instead of
// recursing every time.
let index = self.as_u32() as usize;
let res = CTX::expn_id_cache().with(|cache| cache.borrow().get(index).copied().flatten());
if let Some(res) = res {
res.hash_stable(ctx, hasher);
} else {
let new_len = index + 1;
let mut sub_hasher = StableHasher::new();
TAG_NOT_ROOT.hash_stable(ctx, &mut sub_hasher);
self.expn_data().hash_stable(ctx, &mut sub_hasher);
let sub_hash: Fingerprint = sub_hasher.finish();
CTX::expn_id_cache().with(|cache| {
let mut cache = cache.borrow_mut();
if cache.len() < new_len {
cache.resize(new_len, None);
}
let prev = cache[index].replace(sub_hash);
assert_eq!(prev, None, "Cache slot was filled");
});
sub_hash.hash_stable(ctx, hasher);
}
}
}

View File

@ -36,9 +36,9 @@ use source_map::SourceMap;
pub mod edition;
use edition::Edition;
pub mod hygiene;
pub use hygiene::SyntaxContext;
use hygiene::Transparency;
pub use hygiene::{DesugaringKind, ExpnData, ExpnId, ExpnKind, ForLoopLoc, MacroKind};
pub use hygiene::{ExpnIdCache, SyntaxContext};
pub mod def_id;
use def_id::{CrateNum, DefId, DefPathHash, LOCAL_CRATE};
pub mod lev_distance;
@ -51,12 +51,10 @@ pub use symbol::{sym, Symbol};
mod analyze_source_file;
pub mod fatal_error;
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::sync::{Lock, Lrc};
use std::borrow::Cow;
use std::cell::RefCell;
use std::cmp::{self, Ordering};
use std::fmt;
use std::hash::Hash;
@ -2036,60 +2034,3 @@ where
Hash::hash(&len, hasher);
}
}
impl<CTX: HashStableContext> HashStable<CTX> for SyntaxContext {
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
const TAG_EXPANSION: u8 = 0;
const TAG_NO_EXPANSION: u8 = 1;
if *self == SyntaxContext::root() {
TAG_NO_EXPANSION.hash_stable(ctx, hasher);
} else {
TAG_EXPANSION.hash_stable(ctx, hasher);
let (expn_id, transparency) = self.outer_mark();
expn_id.hash_stable(ctx, hasher);
transparency.hash_stable(ctx, hasher);
}
}
}
pub type ExpnIdCache = RefCell<Vec<Option<Fingerprint>>>;
impl<CTX: HashStableContext> HashStable<CTX> for ExpnId {
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
const TAG_ROOT: u8 = 0;
const TAG_NOT_ROOT: u8 = 1;
if *self == ExpnId::root() {
TAG_ROOT.hash_stable(ctx, hasher);
return;
}
// Since the same expansion context is usually referenced many
// times, we cache a stable hash of it and hash that instead of
// recursing every time.
let index = self.as_u32() as usize;
let res = CTX::expn_id_cache().with(|cache| cache.borrow().get(index).copied().flatten());
if let Some(res) = res {
res.hash_stable(ctx, hasher);
} else {
let new_len = index + 1;
let mut sub_hasher = StableHasher::new();
TAG_NOT_ROOT.hash_stable(ctx, &mut sub_hasher);
self.expn_data().hash_stable(ctx, &mut sub_hasher);
let sub_hash: Fingerprint = sub_hasher.finish();
CTX::expn_id_cache().with(|cache| {
let mut cache = cache.borrow_mut();
if cache.len() < new_len {
cache.resize(new_len, None);
}
let prev = cache[index].replace(sub_hash);
assert_eq!(prev, None, "Cache slot was filled");
});
sub_hash.hash_stable(ctx, hasher);
}
}
}