incremental: Do not rely on default transparency when decoding syntax contexts
Using `ExpnId`s default transparency here instead of the mark's real transparency was actually incorrect.
This commit is contained in:
parent
bf345dd6e3
commit
b0c4d0f8cb
2 changed files with 27 additions and 19 deletions
|
|
@ -23,7 +23,7 @@ use std::mem;
|
|||
use syntax::ast::NodeId;
|
||||
use syntax::source_map::{SourceMap, StableSourceFileId};
|
||||
use syntax_pos::{BytePos, Span, DUMMY_SP, SourceFile};
|
||||
use syntax_pos::hygiene::{ExpnId, SyntaxContext, ExpnData};
|
||||
use syntax_pos::hygiene::{ExpnId, SyntaxContext};
|
||||
|
||||
const TAG_FILE_FOOTER: u128 = 0xC0FFEE_C0FFEE_C0FFEE_C0FFEE_C0FFEE;
|
||||
|
||||
|
|
@ -593,8 +593,8 @@ impl<'a, 'tcx> SpecializedDecoder<Span> for CacheDecoder<'a, 'tcx> {
|
|||
// don't seem to be used after HIR lowering, so everything should be fine
|
||||
// as long as incremental compilation does not kick in before that.
|
||||
let location = || Span::with_root_ctxt(lo, hi);
|
||||
let recover_from_expn_data = |this: &Self, expn_data, pos| {
|
||||
let span = location().fresh_expansion(expn_data);
|
||||
let recover_from_expn_data = |this: &Self, expn_data, transparency, pos| {
|
||||
let span = location().fresh_expansion_with_transparency(expn_data, transparency);
|
||||
this.synthetic_syntax_contexts.borrow_mut().insert(pos, span.ctxt());
|
||||
span
|
||||
};
|
||||
|
|
@ -603,9 +603,9 @@ impl<'a, 'tcx> SpecializedDecoder<Span> for CacheDecoder<'a, 'tcx> {
|
|||
location()
|
||||
}
|
||||
TAG_EXPN_DATA_INLINE => {
|
||||
let expn_data = Decodable::decode(self)?;
|
||||
let (expn_data, transparency) = Decodable::decode(self)?;
|
||||
recover_from_expn_data(
|
||||
self, expn_data, AbsoluteBytePos::new(self.opaque.position())
|
||||
self, expn_data, transparency, AbsoluteBytePos::new(self.opaque.position())
|
||||
)
|
||||
}
|
||||
TAG_EXPN_DATA_SHORTHAND => {
|
||||
|
|
@ -614,9 +614,9 @@ impl<'a, 'tcx> SpecializedDecoder<Span> for CacheDecoder<'a, 'tcx> {
|
|||
if let Some(ctxt) = cached_ctxt {
|
||||
Span::new(lo, hi, ctxt)
|
||||
} else {
|
||||
let expn_data =
|
||||
self.with_position(pos.to_usize(), |this| ExpnData::decode(this))?;
|
||||
recover_from_expn_data(self, expn_data, pos)
|
||||
let (expn_data, transparency) =
|
||||
self.with_position(pos.to_usize(), |this| Decodable::decode(this))?;
|
||||
recover_from_expn_data(self, expn_data, transparency, pos)
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
|
|
@ -819,7 +819,7 @@ where
|
|||
if span_data.ctxt == SyntaxContext::root() {
|
||||
TAG_NO_EXPN_DATA.encode(self)
|
||||
} else {
|
||||
let (expn_id, expn_data) = span_data.ctxt.outer_expn_with_data();
|
||||
let (expn_id, transparency, expn_data) = span_data.ctxt.outer_mark_with_data();
|
||||
if let Some(pos) = self.expn_data_shorthands.get(&expn_id).cloned() {
|
||||
TAG_EXPN_DATA_SHORTHAND.encode(self)?;
|
||||
pos.encode(self)
|
||||
|
|
@ -827,7 +827,7 @@ where
|
|||
TAG_EXPN_DATA_INLINE.encode(self)?;
|
||||
let pos = AbsoluteBytePos::new(self.position());
|
||||
self.expn_data_shorthands.insert(expn_id, pos);
|
||||
expn_data.encode(self)
|
||||
(expn_data, transparency).encode(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -183,8 +183,9 @@ impl HygieneData {
|
|||
self.syntax_context_data[ctxt.0 as usize].outer_expn
|
||||
}
|
||||
|
||||
fn outer_transparency(&self, ctxt: SyntaxContext) -> Transparency {
|
||||
self.syntax_context_data[ctxt.0 as usize].outer_transparency
|
||||
fn outer_mark(&self, ctxt: SyntaxContext) -> (ExpnId, Transparency) {
|
||||
let data = &self.syntax_context_data[ctxt.0 as usize];
|
||||
(data.outer_expn, data.outer_transparency)
|
||||
}
|
||||
|
||||
fn parent_ctxt(&self, ctxt: SyntaxContext) -> SyntaxContext {
|
||||
|
|
@ -200,7 +201,7 @@ impl HygieneData {
|
|||
fn marks(&self, mut ctxt: SyntaxContext) -> Vec<(ExpnId, Transparency)> {
|
||||
let mut marks = Vec::new();
|
||||
while ctxt != SyntaxContext::root() {
|
||||
marks.push((self.outer_expn(ctxt), self.outer_transparency(ctxt)));
|
||||
marks.push(self.outer_mark(ctxt));
|
||||
ctxt = self.parent_ctxt(ctxt);
|
||||
}
|
||||
marks.reverse();
|
||||
|
|
@ -535,13 +536,11 @@ impl SyntaxContext {
|
|||
HygieneData::with(|data| data.expn_data(data.outer_expn(self)).clone())
|
||||
}
|
||||
|
||||
/// `ctxt.outer_expn_with_data()` is equivalent to but faster than
|
||||
/// `{ let outer = ctxt.outer_expn(); (outer, outer.expn_data()) }`.
|
||||
#[inline]
|
||||
pub fn outer_expn_with_data(self) -> (ExpnId, ExpnData) {
|
||||
pub fn outer_mark_with_data(self) -> (ExpnId, Transparency, ExpnData) {
|
||||
HygieneData::with(|data| {
|
||||
let outer = data.outer_expn(self);
|
||||
(outer, data.expn_data(outer).clone())
|
||||
let (expn_id, transparency) = data.outer_mark(self);
|
||||
(expn_id, transparency, data.expn_data(expn_id).clone())
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -563,9 +562,18 @@ impl Span {
|
|||
/// The returned span belongs to the created expansion and has the new properties,
|
||||
/// but its location is inherited from the current span.
|
||||
pub fn fresh_expansion(self, expn_data: ExpnData) -> Span {
|
||||
let transparency = expn_data.default_transparency;
|
||||
self.fresh_expansion_with_transparency(expn_data, transparency)
|
||||
}
|
||||
|
||||
pub fn fresh_expansion_with_transparency(
|
||||
self, expn_data: ExpnData, transparency: Transparency
|
||||
) -> Span {
|
||||
HygieneData::with(|data| {
|
||||
let expn_id = data.fresh_expn(Some(expn_data));
|
||||
self.with_ctxt(data.apply_mark(SyntaxContext::root(), expn_id))
|
||||
self.with_ctxt(data.apply_mark_with_transparency(
|
||||
SyntaxContext::root(), expn_id, transparency
|
||||
))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue