diff options
| author | bors <bors@rust-lang.org> | 2020-08-09 14:29:42 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2020-08-09 14:29:42 +0000 |
| commit | 543f03d24118d3af784aa98c507c00e30c796a0e (patch) | |
| tree | b333a9f3af9e77a2c20181615c5889828f79d8a9 | |
| parent | 8bc801b05019cd3e0ef19e6c4c028d55baa645d2 (diff) | |
| parent | 1f63a6a572a0f9afc769a88229d80cc81ff04697 (diff) | |
| download | rust-543f03d24118d3af784aa98c507c00e30c796a0e.tar.gz rust-543f03d24118d3af784aa98c507c00e30c796a0e.zip | |
Auto merge of #75134 - Aaron1011:feature/expn-data-parent-hash, r=petrochenkov
Hash parent ExpnData cc https://github.com/rust-lang/rust/pull/72121#discussion_r460528326
| -rw-r--r-- | src/librustc_span/hygiene.rs | 8 | ||||
| -rw-r--r-- | src/librustc_span/lib.rs | 64 |
2 files changed, 39 insertions, 33 deletions
diff --git a/src/librustc_span/hygiene.rs b/src/librustc_span/hygiene.rs index fe5370b9644..4e21d566071 100644 --- a/src/librustc_span/hygiene.rs +++ b/src/librustc_span/hygiene.rs @@ -80,8 +80,6 @@ pub enum Transparency { Opaque, } -pub(crate) const NUM_TRANSPARENCIES: usize = 3; - impl ExpnId { pub fn fresh(expn_data: Option<ExpnData>) -> Self { HygieneData::with(|data| data.fresh_expn(expn_data)) @@ -619,6 +617,11 @@ impl SyntaxContext { } #[inline] + pub fn outer_mark(self) -> (ExpnId, Transparency) { + HygieneData::with(|data| data.outer_mark(self)) + } + + #[inline] pub fn outer_mark_with_data(self) -> (ExpnId, Transparency, ExpnData) { HygieneData::with(|data| { let (expn_id, transparency) = data.outer_mark(self); @@ -667,7 +670,6 @@ pub struct ExpnData { /// The kind of this expansion - macro or compiler desugaring. pub kind: ExpnKind, /// The expansion that produced this expansion. - #[stable_hasher(ignore)] pub parent: ExpnId, /// The location of the actual macro invocation or syntax sugar , e.g. /// `let x = foo!();` or `if let Some(y) = x {}` diff --git a/src/librustc_span/lib.rs b/src/librustc_span/lib.rs index 4c441e1cc71..697d88ad063 100644 --- a/src/librustc_span/lib.rs +++ b/src/librustc_span/lib.rs @@ -32,8 +32,8 @@ 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}; -use hygiene::{Transparency, NUM_TRANSPARENCIES}; pub mod def_id; use def_id::{CrateNum, DefId, LOCAL_CRATE}; mod span_encoding; @@ -1823,47 +1823,51 @@ impl<CTX: HashStableContext> HashStable<CTX> for SyntaxContext { 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); + } + } +} - // 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. - thread_local! { - static CACHE: RefCell<Vec<Option<[Option<u64>; NUM_TRANSPARENCIES]>>> = Default::default(); - } +impl<CTX: HashStableContext> HashStable<CTX> for ExpnId { + fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { + // 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. + thread_local! { + static CACHE: RefCell<Vec<Option<Fingerprint>>> = Default::default(); + } - let sub_hash: u64 = CACHE.with(|cache| { - let (expn_id, transparency, _) = self.outer_mark_with_data(); - let index = expn_id.as_u32() as usize; + const TAG_ROOT: u8 = 0; + const TAG_NOT_ROOT: u8 = 1; - if let Some(sub_hash_cache) = cache.borrow().get(index).copied().flatten() { - if let Some(sub_hash) = sub_hash_cache[transparency as usize] { - return sub_hash; - } - } + if *self == ExpnId::root() { + TAG_ROOT.hash_stable(ctx, hasher); + return; + } - let new_len = index + 1; + TAG_NOT_ROOT.hash_stable(ctx, hasher); + let index = self.as_u32() as usize; - let mut hasher = StableHasher::new(); - expn_id.expn_data().hash_stable(ctx, &mut hasher); - transparency.hash_stable(ctx, &mut hasher); + let res = 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 sub_hash: Fingerprint = hasher.finish(); - let sub_hash = sub_hash.to_smaller_hash(); + let mut sub_hasher = StableHasher::new(); + self.expn_data().hash_stable(ctx, &mut sub_hasher); + let sub_hash: Fingerprint = sub_hasher.finish(); + CACHE.with(|cache| { let mut cache = cache.borrow_mut(); if cache.len() < new_len { cache.resize(new_len, None); } - if let Some(mut sub_hash_cache) = cache[index] { - sub_hash_cache[transparency as usize] = Some(sub_hash); - } else { - let mut sub_hash_cache = [None; NUM_TRANSPARENCIES]; - sub_hash_cache[transparency as usize] = Some(sub_hash); - cache[index] = Some(sub_hash_cache); - } - sub_hash + cache[index].replace(sub_hash).expect_none("Cache slot was filled"); }); - sub_hash.hash_stable(ctx, hasher); } } |
