Skip to content

Commit 543f03d

Browse files
committed
Auto merge of rust-lang#75134 - Aaron1011:feature/expn-data-parent-hash, r=petrochenkov
Hash parent ExpnData cc rust-lang#72121 (comment)
2 parents 8bc801b + 1f63a6a commit 543f03d

File tree

2 files changed

+39
-33
lines changed

2 files changed

+39
-33
lines changed

src/librustc_span/hygiene.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,6 @@ pub enum Transparency {
8080
Opaque,
8181
}
8282

83-
pub(crate) const NUM_TRANSPARENCIES: usize = 3;
84-
8583
impl ExpnId {
8684
pub fn fresh(expn_data: Option<ExpnData>) -> Self {
8785
HygieneData::with(|data| data.fresh_expn(expn_data))
@@ -618,6 +616,11 @@ impl SyntaxContext {
618616
HygieneData::with(|data| data.expn_data(data.outer_expn(self)).clone())
619617
}
620618

619+
#[inline]
620+
pub fn outer_mark(self) -> (ExpnId, Transparency) {
621+
HygieneData::with(|data| data.outer_mark(self))
622+
}
623+
621624
#[inline]
622625
pub fn outer_mark_with_data(self) -> (ExpnId, Transparency, ExpnData) {
623626
HygieneData::with(|data| {
@@ -667,7 +670,6 @@ pub struct ExpnData {
667670
/// The kind of this expansion - macro or compiler desugaring.
668671
pub kind: ExpnKind,
669672
/// The expansion that produced this expansion.
670-
#[stable_hasher(ignore)]
671673
pub parent: ExpnId,
672674
/// The location of the actual macro invocation or syntax sugar , e.g.
673675
/// `let x = foo!();` or `if let Some(y) = x {}`

src/librustc_span/lib.rs

+34-30
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ pub mod edition;
3232
use edition::Edition;
3333
pub mod hygiene;
3434
pub use hygiene::SyntaxContext;
35+
use hygiene::Transparency;
3536
pub use hygiene::{DesugaringKind, ExpnData, ExpnId, ExpnKind, ForLoopLoc, MacroKind};
36-
use hygiene::{Transparency, NUM_TRANSPARENCIES};
3737
pub mod def_id;
3838
use def_id::{CrateNum, DefId, LOCAL_CRATE};
3939
mod span_encoding;
@@ -1823,47 +1823,51 @@ impl<CTX: HashStableContext> HashStable<CTX> for SyntaxContext {
18231823
TAG_NO_EXPANSION.hash_stable(ctx, hasher);
18241824
} else {
18251825
TAG_EXPANSION.hash_stable(ctx, hasher);
1826+
let (expn_id, transparency) = self.outer_mark();
1827+
expn_id.hash_stable(ctx, hasher);
1828+
transparency.hash_stable(ctx, hasher);
1829+
}
1830+
}
1831+
}
18261832

1827-
// Since the same expansion context is usually referenced many
1828-
// times, we cache a stable hash of it and hash that instead of
1829-
// recursing every time.
1830-
thread_local! {
1831-
static CACHE: RefCell<Vec<Option<[Option<u64>; NUM_TRANSPARENCIES]>>> = Default::default();
1832-
}
1833+
impl<CTX: HashStableContext> HashStable<CTX> for ExpnId {
1834+
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
1835+
// Since the same expansion context is usually referenced many
1836+
// times, we cache a stable hash of it and hash that instead of
1837+
// recursing every time.
1838+
thread_local! {
1839+
static CACHE: RefCell<Vec<Option<Fingerprint>>> = Default::default();
1840+
}
18331841

1834-
let sub_hash: u64 = CACHE.with(|cache| {
1835-
let (expn_id, transparency, _) = self.outer_mark_with_data();
1836-
let index = expn_id.as_u32() as usize;
1842+
const TAG_ROOT: u8 = 0;
1843+
const TAG_NOT_ROOT: u8 = 1;
18371844

1838-
if let Some(sub_hash_cache) = cache.borrow().get(index).copied().flatten() {
1839-
if let Some(sub_hash) = sub_hash_cache[transparency as usize] {
1840-
return sub_hash;
1841-
}
1842-
}
1845+
if *self == ExpnId::root() {
1846+
TAG_ROOT.hash_stable(ctx, hasher);
1847+
return;
1848+
}
18431849

1844-
let new_len = index + 1;
1850+
TAG_NOT_ROOT.hash_stable(ctx, hasher);
1851+
let index = self.as_u32() as usize;
18451852

1846-
let mut hasher = StableHasher::new();
1847-
expn_id.expn_data().hash_stable(ctx, &mut hasher);
1848-
transparency.hash_stable(ctx, &mut hasher);
1853+
let res = CACHE.with(|cache| cache.borrow().get(index).copied().flatten());
1854+
1855+
if let Some(res) = res {
1856+
res.hash_stable(ctx, hasher);
1857+
} else {
1858+
let new_len = index + 1;
18491859

1850-
let sub_hash: Fingerprint = hasher.finish();
1851-
let sub_hash = sub_hash.to_smaller_hash();
1860+
let mut sub_hasher = StableHasher::new();
1861+
self.expn_data().hash_stable(ctx, &mut sub_hasher);
1862+
let sub_hash: Fingerprint = sub_hasher.finish();
18521863

1864+
CACHE.with(|cache| {
18531865
let mut cache = cache.borrow_mut();
18541866
if cache.len() < new_len {
18551867
cache.resize(new_len, None);
18561868
}
1857-
if let Some(mut sub_hash_cache) = cache[index] {
1858-
sub_hash_cache[transparency as usize] = Some(sub_hash);
1859-
} else {
1860-
let mut sub_hash_cache = [None; NUM_TRANSPARENCIES];
1861-
sub_hash_cache[transparency as usize] = Some(sub_hash);
1862-
cache[index] = Some(sub_hash_cache);
1863-
}
1864-
sub_hash
1869+
cache[index].replace(sub_hash).expect_none("Cache slot was filled");
18651870
});
1866-
18671871
sub_hash.hash_stable(ctx, hasher);
18681872
}
18691873
}

0 commit comments

Comments
 (0)