Skip to content

Commit bdb34d2

Browse files
Auto merge of #143882 - cjgillot:relative-span-file, r=<try>
Also hash spans inside the same file as relative.
2 parents f34ba77 + 799e1d0 commit bdb34d2

File tree

4 files changed

+99
-78
lines changed

4 files changed

+99
-78
lines changed

compiler/rustc_middle/src/query/on_disk_cache.rs

Lines changed: 55 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ const TAG_FULL_SPAN: u8 = 0;
3838
// A partial span with no ___location information, encoded only with a `SyntaxContext`
3939
const TAG_PARTIAL_SPAN: u8 = 1;
4040
const TAG_RELATIVE_SPAN: u8 = 2;
41+
const TAG_RELATIVE_OUTER_SPAN: u8 = 3;
4142

4243
const TAG_SYNTAX_CONTEXT: u8 = 0;
4344
const TAG_EXPN_DATA: u8 = 1;
@@ -645,34 +646,41 @@ impl<'a, 'tcx> SpanDecoder for CacheDecoder<'a, 'tcx> {
645646
let parent = Option::<LocalDefId>::decode(self);
646647
let tag: u8 = Decodable::decode(self);
647648

648-
if tag == TAG_PARTIAL_SPAN {
649-
return Span::new(BytePos(0), BytePos(0), ctxt, parent);
650-
} else if tag == TAG_RELATIVE_SPAN {
651-
let dlo = u32::decode(self);
652-
let dto = u32::decode(self);
653-
654-
let enclosing = self.tcx.source_span_untracked(parent.unwrap()).data_untracked();
655-
let span = Span::new(
656-
enclosing.lo + BytePos::from_u32(dlo),
657-
enclosing.lo + BytePos::from_u32(dto),
658-
ctxt,
659-
parent,
660-
);
661-
662-
return span;
663-
} else {
664-
debug_assert_eq!(tag, TAG_FULL_SPAN);
665-
}
649+
let (lo, hi) = match tag {
650+
TAG_PARTIAL_SPAN => (BytePos(0), BytePos(0)),
651+
TAG_RELATIVE_SPAN => {
652+
let dlo = u32::decode(self);
653+
let dto = u32::decode(self);
666654

667-
let file_lo_index = SourceFileIndex::decode(self);
668-
let line_lo = usize::decode(self);
669-
let col_lo = RelativeBytePos::decode(self);
670-
let len = BytePos::decode(self);
671-
672-
let file_lo = self.file_index_to_file(file_lo_index);
673-
let lo = file_lo.lines()[line_lo - 1] + col_lo;
674-
let lo = file_lo.absolute_position(lo);
675-
let hi = lo + len;
655+
let enclosing = self.tcx.source_span_untracked(parent.unwrap()).data_untracked();
656+
(enclosing.lo + BytePos::from_u32(dlo), enclosing.lo + BytePos::from_u32(dto))
657+
}
658+
TAG_RELATIVE_OUTER_SPAN => {
659+
let dlo = isize::decode(self);
660+
let dto = isize::decode(self);
661+
662+
let enclosing = self.tcx.source_span_untracked(parent.unwrap()).data_untracked();
663+
let reference = enclosing.lo.to_u32() as isize;
664+
(
665+
BytePos::from_usize((reference + dlo) as usize),
666+
BytePos::from_usize((reference + dto) as usize),
667+
)
668+
}
669+
TAG_FULL_SPAN => {
670+
let file_lo_index = SourceFileIndex::decode(self);
671+
let line_lo = usize::decode(self);
672+
let col_lo = RelativeBytePos::decode(self);
673+
let len = BytePos::decode(self);
674+
675+
let file_lo = self.file_index_to_file(file_lo_index);
676+
let lo = file_lo.lines()[line_lo - 1] + col_lo;
677+
let lo = file_lo.absolute_position(lo);
678+
let hi = lo + len;
679+
680+
(lo, hi)
681+
}
682+
_ => unreachable!(),
683+
};
676684

677685
Span::new(lo, hi, ctxt, parent)
678686
}
@@ -897,30 +905,33 @@ impl<'a, 'tcx> SpanEncoder for CacheEncoder<'a, 'tcx> {
897905
return TAG_PARTIAL_SPAN.encode(self);
898906
}
899907

900-
if let Some(parent) = span_data.parent {
901-
let enclosing = self.tcx.source_span_untracked(parent).data_untracked();
902-
if enclosing.contains(span_data) {
903-
TAG_RELATIVE_SPAN.encode(self);
904-
(span_data.lo - enclosing.lo).to_u32().encode(self);
905-
(span_data.hi - enclosing.lo).to_u32().encode(self);
906-
return;
907-
}
908+
let parent =
909+
span_data.parent.map(|parent| self.tcx.source_span_untracked(parent).data_untracked());
910+
if let Some(parent) = parent
911+
&& parent.contains(span_data)
912+
{
913+
TAG_RELATIVE_SPAN.encode(self);
914+
(span_data.lo - parent.lo).to_u32().encode(self);
915+
(span_data.hi - parent.lo).to_u32().encode(self);
916+
return;
908917
}
909918

910-
let pos = self.source_map.byte_pos_to_line_and_col(span_data.lo);
911-
let partial_span = match &pos {
912-
Some((file_lo, _, _)) => !file_lo.contains(span_data.hi),
913-
None => true,
919+
let Some((file_lo, line_lo, col_lo)) =
920+
self.source_map.byte_pos_to_line_and_col(span_data.lo)
921+
else {
922+
return TAG_PARTIAL_SPAN.encode(self);
914923
};
915924

916-
if partial_span {
917-
return TAG_PARTIAL_SPAN.encode(self);
925+
if let Some(parent) = parent
926+
&& file_lo.contains(parent.lo)
927+
{
928+
TAG_RELATIVE_OUTER_SPAN.encode(self);
929+
(span_data.lo.to_u32() as isize - parent.lo.to_u32() as isize).encode(self);
930+
(span_data.hi.to_u32() as isize - parent.lo.to_u32() as isize).encode(self);
931+
return;
918932
}
919933

920-
let (file_lo, line_lo, col_lo) = pos.unwrap();
921-
922934
let len = span_data.hi - span_data.lo;
923-
924935
let source_file_index = self.source_file_index(file_lo);
925936

926937
TAG_FULL_SPAN.encode(self);

compiler/rustc_query_system/src/ich/hcx.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@ use rustc_hir::definitions::DefPathHash;
55
use rustc_session::Session;
66
use rustc_session::cstore::Untracked;
77
use rustc_span::source_map::SourceMap;
8-
use rustc_span::{
9-
BytePos, CachingSourceMapView, DUMMY_SP, Span, SpanData, StableSourceFileId, Symbol,
10-
};
8+
use rustc_span::{BytePos, CachingSourceMapView, DUMMY_SP, SourceFile, Span, SpanData, Symbol};
119

1210
use crate::ich;
1311

@@ -118,7 +116,7 @@ impl<'a> rustc_span::HashStableContext for StableHashingContext<'a> {
118116
fn span_data_to_lines_and_cols(
119117
&mut self,
120118
span: &SpanData,
121-
) -> Option<(StableSourceFileId, usize, BytePos, usize, BytePos)> {
119+
) -> Option<(&SourceFile, usize, BytePos, usize, BytePos)> {
122120
self.source_map().span_data_to_lines_and_cols(span)
123121
}
124122

compiler/rustc_span/src/caching_source_map_view.rs

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::ops::Range;
22
use std::sync::Arc;
33

44
use crate::source_map::SourceMap;
5-
use crate::{BytePos, Pos, RelativeBytePos, SourceFile, SpanData, StableSourceFileId};
5+
use crate::{BytePos, Pos, RelativeBytePos, SourceFile, SpanData};
66

77
#[derive(Clone)]
88
struct CacheEntry {
@@ -114,7 +114,7 @@ impl<'sm> CachingSourceMapView<'sm> {
114114
pub fn span_data_to_lines_and_cols(
115115
&mut self,
116116
span_data: &SpanData,
117-
) -> Option<(StableSourceFileId, usize, BytePos, usize, BytePos)> {
117+
) -> Option<(&SourceFile, usize, BytePos, usize, BytePos)> {
118118
self.time_stamp += 1;
119119

120120
// Check if lo and hi are in the cached lines.
@@ -123,27 +123,25 @@ impl<'sm> CachingSourceMapView<'sm> {
123123

124124
if lo_cache_idx != -1 && hi_cache_idx != -1 {
125125
// Cache hit for span lo and hi. Check if they belong to the same file.
126-
let result = {
127-
let lo = &self.line_cache[lo_cache_idx as usize];
128-
let hi = &self.line_cache[hi_cache_idx as usize];
126+
let lo_file_index = self.line_cache[lo_cache_idx as usize].file_index;
127+
let hi_file_index = self.line_cache[hi_cache_idx as usize].file_index;
129128

130-
if lo.file_index != hi.file_index {
131-
return None;
132-
}
133-
134-
(
135-
lo.file.stable_id,
136-
lo.line_number,
137-
span_data.lo - lo.line.start,
138-
hi.line_number,
139-
span_data.hi - hi.line.start,
140-
)
141-
};
129+
if lo_file_index != hi_file_index {
130+
return None;
131+
}
142132

143133
self.line_cache[lo_cache_idx as usize].touch(self.time_stamp);
144134
self.line_cache[hi_cache_idx as usize].touch(self.time_stamp);
145135

146-
return Some(result);
136+
let lo = &self.line_cache[lo_cache_idx as usize];
137+
let hi = &self.line_cache[hi_cache_idx as usize];
138+
return Some((
139+
&*lo.file,
140+
lo.line_number,
141+
span_data.lo - lo.line.start,
142+
hi.line_number,
143+
span_data.hi - hi.line.start,
144+
));
147145
}
148146

149147
// No cache hit or cache hit for only one of span lo and hi.
@@ -226,7 +224,7 @@ impl<'sm> CachingSourceMapView<'sm> {
226224
assert_eq!(lo.file_index, hi.file_index);
227225

228226
Some((
229-
lo.file.stable_id,
227+
&*lo.file,
230228
lo.line_number,
231229
span_data.lo - lo.line.start,
232230
hi.line_number,

compiler/rustc_span/src/lib.rs

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2634,7 +2634,7 @@ pub trait HashStableContext {
26342634
fn span_data_to_lines_and_cols(
26352635
&mut self,
26362636
span: &SpanData,
2637-
) -> Option<(StableSourceFileId, usize, BytePos, usize, BytePos)>;
2637+
) -> Option<(&SourceFile, usize, BytePos, usize, BytePos)>;
26382638
fn hashing_controls(&self) -> HashingControls;
26392639
}
26402640

@@ -2652,6 +2652,7 @@ where
26522652
/// codepoint offsets. For the purpose of the hash that's sufficient.
26532653
/// Also, hashing filenames is expensive so we avoid doing it twice when the
26542654
/// span starts and ends in the same file, which is almost always the case.
2655+
// Important: changes to this method should be reflected in implementations of `SpanEncoder`.
26552656
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
26562657
const TAG_VALID_SPAN: u8 = 0;
26572658
const TAG_INVALID_SPAN: u8 = 1;
@@ -2670,15 +2671,15 @@ where
26702671
return;
26712672
}
26722673

2673-
if let Some(parent) = span.parent {
2674-
let def_span = ctx.def_span(parent).data_untracked();
2675-
if def_span.contains(span) {
2676-
// This span is enclosed in a definition: only hash the relative position.
2677-
Hash::hash(&TAG_RELATIVE_SPAN, hasher);
2678-
(span.lo - def_span.lo).to_u32().hash_stable(ctx, hasher);
2679-
(span.hi - def_span.lo).to_u32().hash_stable(ctx, hasher);
2680-
return;
2681-
}
2674+
let parent = span.parent.map(|parent| ctx.def_span(parent).data_untracked());
2675+
if let Some(parent) = parent
2676+
&& parent.contains(span)
2677+
{
2678+
// This span is enclosed in a definition: only hash the relative position.
2679+
Hash::hash(&TAG_RELATIVE_SPAN, hasher);
2680+
Hash::hash(&(span.lo - parent.lo), hasher);
2681+
Hash::hash(&(span.hi - parent.lo), hasher);
2682+
return;
26822683
}
26832684

26842685
// If this is not an empty or invalid span, we want to hash the last
@@ -2691,7 +2692,20 @@ where
26912692
};
26922693

26932694
Hash::hash(&TAG_VALID_SPAN, hasher);
2694-
Hash::hash(&file, hasher);
2695+
Hash::hash(&file.stable_id, hasher);
2696+
2697+
if let Some(parent) = parent
2698+
&& file.contains(parent.lo)
2699+
{
2700+
// This span is relative to another span in the same file,
2701+
// only hash the relative position.
2702+
Hash::hash(&TAG_RELATIVE_SPAN, hasher);
2703+
// Use signed difference as `span` may start before `parent`,
2704+
// for instance attributes start before their item's span.
2705+
Hash::hash(&(span.lo.to_u32() as isize - parent.lo.to_u32() as isize), hasher);
2706+
Hash::hash(&(span.hi.to_u32() as isize - parent.lo.to_u32() as isize), hasher);
2707+
return;
2708+
}
26952709

26962710
// Hash both the length and the end ___location (line/column) of a span. If we
26972711
// hash only the length, for example, then two otherwise equal spans with

0 commit comments

Comments
 (0)