Auto merge of #80654 - Aaron1011:fix/dummy-span-ctxt, r=wesleywiser
Properly handle `SyntaxContext` of dummy spans in incr comp Fixes #80336 Due to macro expansion, we may end up with spans with an invalid location and non-root `SyntaxContext`. This commits preserves the `SyntaxContext` of such spans in the incremental cache, and ensures that we always hash the `SyntaxContext` when computing the `Fingerprint` of a `Span` Previously, we would discard the `SyntaxContext` during serialization to the incremental cache, causing the span's `Fingerprint` to change across compilation sessions.
This commit is contained in:
commit
180fdffa17
@ -32,8 +32,10 @@ use std::mem;
|
|||||||
|
|
||||||
const TAG_FILE_FOOTER: u128 = 0xC0FFEE_C0FFEE_C0FFEE_C0FFEE_C0FFEE;
|
const TAG_FILE_FOOTER: u128 = 0xC0FFEE_C0FFEE_C0FFEE_C0FFEE_C0FFEE;
|
||||||
|
|
||||||
const TAG_VALID_SPAN: u8 = 0;
|
// A normal span encoded with both location information and a `SyntaxContext`
|
||||||
const TAG_INVALID_SPAN: u8 = 1;
|
const TAG_FULL_SPAN: u8 = 0;
|
||||||
|
// A partial span with no location information, encoded only with a `SyntaxContext`
|
||||||
|
const TAG_PARTIAL_SPAN: u8 = 1;
|
||||||
|
|
||||||
const TAG_SYNTAX_CONTEXT: u8 = 0;
|
const TAG_SYNTAX_CONTEXT: u8 = 0;
|
||||||
const TAG_EXPN_DATA: u8 = 1;
|
const TAG_EXPN_DATA: u8 = 1;
|
||||||
@ -864,10 +866,11 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for Span {
|
|||||||
fn decode(decoder: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
|
fn decode(decoder: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
|
||||||
let tag: u8 = Decodable::decode(decoder)?;
|
let tag: u8 = Decodable::decode(decoder)?;
|
||||||
|
|
||||||
if tag == TAG_INVALID_SPAN {
|
if tag == TAG_PARTIAL_SPAN {
|
||||||
return Ok(DUMMY_SP);
|
let ctxt = SyntaxContext::decode(decoder)?;
|
||||||
|
return Ok(DUMMY_SP.with_ctxt(ctxt));
|
||||||
} else {
|
} else {
|
||||||
debug_assert_eq!(tag, TAG_VALID_SPAN);
|
debug_assert_eq!(tag, TAG_FULL_SPAN);
|
||||||
}
|
}
|
||||||
|
|
||||||
let file_lo_index = SourceFileIndex::decode(decoder)?;
|
let file_lo_index = SourceFileIndex::decode(decoder)?;
|
||||||
@ -1057,24 +1060,29 @@ where
|
|||||||
{
|
{
|
||||||
fn encode(&self, s: &mut CacheEncoder<'a, 'tcx, E>) -> Result<(), E::Error> {
|
fn encode(&self, s: &mut CacheEncoder<'a, 'tcx, E>) -> Result<(), E::Error> {
|
||||||
if *self == DUMMY_SP {
|
if *self == DUMMY_SP {
|
||||||
return TAG_INVALID_SPAN.encode(s);
|
TAG_PARTIAL_SPAN.encode(s)?;
|
||||||
|
return SyntaxContext::root().encode(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
let span_data = self.data();
|
let span_data = self.data();
|
||||||
let (file_lo, line_lo, col_lo) = match s.source_map.byte_pos_to_line_and_col(span_data.lo) {
|
let pos = s.source_map.byte_pos_to_line_and_col(span_data.lo);
|
||||||
Some(pos) => pos,
|
let partial_span = match &pos {
|
||||||
None => return TAG_INVALID_SPAN.encode(s),
|
Some((file_lo, _, _)) => !file_lo.contains(span_data.hi),
|
||||||
|
None => true,
|
||||||
};
|
};
|
||||||
|
|
||||||
if !file_lo.contains(span_data.hi) {
|
if partial_span {
|
||||||
return TAG_INVALID_SPAN.encode(s);
|
TAG_PARTIAL_SPAN.encode(s)?;
|
||||||
|
return span_data.ctxt.encode(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let (file_lo, line_lo, col_lo) = pos.unwrap();
|
||||||
|
|
||||||
let len = span_data.hi - span_data.lo;
|
let len = span_data.hi - span_data.lo;
|
||||||
|
|
||||||
let source_file_index = s.source_file_index(file_lo);
|
let source_file_index = s.source_file_index(file_lo);
|
||||||
|
|
||||||
TAG_VALID_SPAN.encode(s)?;
|
TAG_FULL_SPAN.encode(s)?;
|
||||||
source_file_index.encode(s)?;
|
source_file_index.encode(s)?;
|
||||||
line_lo.encode(s)?;
|
line_lo.encode(s)?;
|
||||||
col_lo.encode(s)?;
|
col_lo.encode(s)?;
|
||||||
|
@ -1899,8 +1899,9 @@ where
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if *self == DUMMY_SP {
|
if self.is_dummy() {
|
||||||
Hash::hash(&TAG_INVALID_SPAN, hasher);
|
Hash::hash(&TAG_INVALID_SPAN, hasher);
|
||||||
|
self.ctxt().hash_stable(ctx, hasher);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
10
src/test/incremental/issue-80336-invalid-span.rs
Normal file
10
src/test/incremental/issue-80336-invalid-span.rs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
// Regression test for issue #80336
|
||||||
|
// Test that we properly handle encoding, decoding, and hashing
|
||||||
|
// of spans with an invalid location and non-root `SyntaxContext`
|
||||||
|
|
||||||
|
// revisions:rpass1 rpass2
|
||||||
|
// only-x86_64
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
let _ = is_x86_feature_detected!("avx2");
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user