Skip to content

Commit e85ddeb

Browse files
committed
Encode spans relative to their parent.
1 parent 00485e0 commit e85ddeb

File tree

5 files changed

+76
-16
lines changed

5 files changed

+76
-16
lines changed

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,8 @@ struct LoweringContext<'a, 'hir: 'a> {
165165
pub trait ResolverAstLowering {
166166
fn def_key(&mut self, id: DefId) -> DefKey;
167167

168+
fn def_span(&self, id: LocalDefId) -> Span;
169+
168170
fn item_generics_num_lifetimes(&self, def: DefId) -> usize;
169171

170172
fn legacy_const_generic_args(&mut self, expr: &Expr) -> Option<Vec<usize>>;
@@ -215,6 +217,11 @@ impl<'a> rustc_span::HashStableContext for LoweringHasher<'a> {
215217
true
216218
}
217219

220+
#[inline]
221+
fn def_span(&self, id: LocalDefId) -> Span {
222+
self.resolver.def_span(id)
223+
}
224+
218225
#[inline]
219226
fn def_path_hash(&self, def_id: DefId) -> DefPathHash {
220227
self.resolver.def_path_hash(def_id)

compiler/rustc_middle/src/ich/hcx.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use rustc_hir::definitions::{DefPathHash, Definitions};
1212
use rustc_session::Session;
1313
use rustc_span::source_map::SourceMap;
1414
use rustc_span::symbol::Symbol;
15-
use rustc_span::{BytePos, CachingSourceMapView, SourceFile, SpanData};
15+
use rustc_span::{BytePos, CachingSourceMapView, SourceFile, Span, SpanData};
1616

1717
use smallvec::SmallVec;
1818
use std::cmp::Ord;
@@ -229,6 +229,11 @@ impl<'a> rustc_span::HashStableContext for StableHashingContext<'a> {
229229
self.def_path_hash(def_id)
230230
}
231231

232+
#[inline]
233+
fn def_span(&self, def_id: LocalDefId) -> Span {
234+
self.definitions.def_span(def_id)
235+
}
236+
232237
fn span_data_to_lines_and_cols(
233238
&mut self,
234239
span: &SpanData,

compiler/rustc_query_impl/src/on_disk_cache.rs

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use rustc_span::hygiene::{
2323
};
2424
use rustc_span::source_map::{SourceMap, StableSourceFileId};
2525
use rustc_span::CachingSourceMapView;
26-
use rustc_span::{BytePos, ExpnData, ExpnHash, SourceFile, Span, DUMMY_SP};
26+
use rustc_span::{BytePos, ExpnData, ExpnHash, Pos, SourceFile, Span};
2727
use std::collections::hash_map::Entry;
2828
use std::mem;
2929

@@ -33,6 +33,7 @@ const TAG_FILE_FOOTER: u128 = 0xC0FFEE_C0FFEE_C0FFEE_C0FFEE_C0FFEE;
3333
const TAG_FULL_SPAN: u8 = 0;
3434
// A partial span with no location information, encoded only with a `SyntaxContext`
3535
const TAG_PARTIAL_SPAN: u8 = 1;
36+
const TAG_RELATIVE_SPAN: u8 = 2;
3637

3738
const TAG_SYNTAX_CONTEXT: u8 = 0;
3839
const TAG_EXPN_DATA: u8 = 1;
@@ -829,11 +830,25 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for ExpnId {
829830

830831
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for Span {
831832
fn decode(decoder: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
833+
let ctxt = SyntaxContext::decode(decoder)?;
834+
let parent = Option::<LocalDefId>::decode(decoder)?;
832835
let tag: u8 = Decodable::decode(decoder)?;
833836

834837
if tag == TAG_PARTIAL_SPAN {
835-
let ctxt = SyntaxContext::decode(decoder)?;
836-
return Ok(DUMMY_SP.with_ctxt(ctxt));
838+
return Ok(Span::new(BytePos(0), BytePos(0), ctxt, parent));
839+
} else if tag == TAG_RELATIVE_SPAN {
840+
let dlo = u32::decode(decoder)?;
841+
let dto = u32::decode(decoder)?;
842+
843+
let enclosing = decoder.tcx.definitions_untracked().def_span(parent.unwrap()).data();
844+
let span = Span::new(
845+
enclosing.lo + BytePos::from_u32(dlo),
846+
enclosing.lo + BytePos::from_u32(dto),
847+
ctxt,
848+
parent,
849+
);
850+
851+
return Ok(span);
837852
} else {
838853
debug_assert_eq!(tag, TAG_FULL_SPAN);
839854
}
@@ -842,13 +857,12 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for Span {
842857
let line_lo = usize::decode(decoder)?;
843858
let col_lo = BytePos::decode(decoder)?;
844859
let len = BytePos::decode(decoder)?;
845-
let ctxt = SyntaxContext::decode(decoder)?;
846860

847861
let file_lo = decoder.file_index_to_file(file_lo_index);
848862
let lo = file_lo.lines[line_lo - 1] + col_lo;
849863
let hi = lo + len;
850864

851-
Ok(Span::new(lo, hi, ctxt, None))
865+
Ok(Span::new(lo, hi, ctxt, parent))
852866
}
853867
}
854868

@@ -1009,9 +1023,21 @@ where
10091023
{
10101024
fn encode(&self, s: &mut CacheEncoder<'a, 'tcx, E>) -> Result<(), E::Error> {
10111025
let span_data = self.data();
1012-
if self.is_dummy() {
1013-
TAG_PARTIAL_SPAN.encode(s)?;
1014-
return span_data.ctxt.encode(s);
1026+
span_data.ctxt.encode(s)?;
1027+
span_data.parent.encode(s)?;
1028+
1029+
if span_data.is_dummy() {
1030+
return TAG_PARTIAL_SPAN.encode(s);
1031+
}
1032+
1033+
if let Some(parent) = span_data.parent {
1034+
let enclosing = s.tcx.definitions_untracked().def_span(parent).data();
1035+
if enclosing.contains(span_data) {
1036+
TAG_RELATIVE_SPAN.encode(s)?;
1037+
(span_data.lo - enclosing.lo).to_u32().encode(s)?;
1038+
(span_data.hi - enclosing.lo).to_u32().encode(s)?;
1039+
return Ok(());
1040+
}
10151041
}
10161042

10171043
let pos = s.source_map.byte_pos_to_line_and_col(span_data.lo);
@@ -1021,8 +1047,7 @@ where
10211047
};
10221048

10231049
if partial_span {
1024-
TAG_PARTIAL_SPAN.encode(s)?;
1025-
return span_data.ctxt.encode(s);
1050+
return TAG_PARTIAL_SPAN.encode(s);
10261051
}
10271052

10281053
let (file_lo, line_lo, col_lo) = pos.unwrap();
@@ -1035,8 +1060,7 @@ where
10351060
source_file_index.encode(s)?;
10361061
line_lo.encode(s)?;
10371062
col_lo.encode(s)?;
1038-
len.encode(s)?;
1039-
span_data.ctxt.encode(s)
1063+
len.encode(s)
10401064
}
10411065
}
10421066

compiler/rustc_resolve/src/lib.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1114,6 +1114,11 @@ impl ResolverAstLowering for Resolver<'_> {
11141114
}
11151115
}
11161116

1117+
#[inline]
1118+
fn def_span(&self, id: LocalDefId) -> Span {
1119+
self.definitions.def_span(id)
1120+
}
1121+
11171122
fn item_generics_num_lifetimes(&self, def_id: DefId) -> usize {
11181123
if let Some(def_id) = def_id.as_local() {
11191124
self.item_generics_num_lifetimes[&def_id]
@@ -1221,6 +1226,11 @@ impl<'a, 'b> rustc_span::HashStableContext for ExpandHasher<'a, 'b> {
12211226
true
12221227
}
12231228

1229+
#[inline]
1230+
fn def_span(&self, id: LocalDefId) -> Span {
1231+
self.resolver.def_span(id)
1232+
}
1233+
12241234
#[inline]
12251235
fn def_path_hash(&self, def_id: DefId) -> DefPathHash {
12261236
self.resolver.def_path_hash(def_id)

compiler/rustc_span/src/lib.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2001,6 +2001,7 @@ impl InnerSpan {
20012001
pub trait HashStableContext {
20022002
fn def_path_hash(&self, def_id: DefId) -> DefPathHash;
20032003
fn hash_spans(&self) -> bool;
2004+
fn def_span(&self, def_id: LocalDefId) -> Span;
20042005
fn span_data_to_lines_and_cols(
20052006
&mut self,
20062007
span: &SpanData,
@@ -2024,22 +2025,35 @@ where
20242025
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
20252026
const TAG_VALID_SPAN: u8 = 0;
20262027
const TAG_INVALID_SPAN: u8 = 1;
2028+
const TAG_RELATIVE_SPAN: u8 = 2;
20272029

20282030
if !ctx.hash_spans() {
20292031
return;
20302032
}
20312033

2032-
self.ctxt().hash_stable(ctx, hasher);
2034+
let span = self.data();
2035+
span.ctxt.hash_stable(ctx, hasher);
2036+
span.parent.hash_stable(ctx, hasher);
20332037

2034-
if self.is_dummy() {
2038+
if span.is_dummy() {
20352039
Hash::hash(&TAG_INVALID_SPAN, hasher);
20362040
return;
20372041
}
20382042

2043+
if let Some(parent) = span.parent {
2044+
let def_span = ctx.def_span(parent).data();
2045+
if def_span.contains(span) {
2046+
// This span is enclosed in a definition: only hash the relative position.
2047+
Hash::hash(&TAG_RELATIVE_SPAN, hasher);
2048+
(span.lo - def_span.lo).to_u32().hash_stable(ctx, hasher);
2049+
(span.hi - def_span.lo).to_u32().hash_stable(ctx, hasher);
2050+
return;
2051+
}
2052+
}
2053+
20392054
// If this is not an empty or invalid span, we want to hash the last
20402055
// position that belongs to it, as opposed to hashing the first
20412056
// position past it.
2042-
let span = self.data();
20432057
let (file, line_lo, col_lo, line_hi, col_hi) = match ctx.span_data_to_lines_and_cols(&span)
20442058
{
20452059
Some(pos) => pos,

0 commit comments

Comments
 (0)