Hash all spans relatively to their parent
Co-authored-by: Camille Gillot <gillot.camille@gmail.com>
This commit is contained in:
parent
b49c7d784e
commit
dc505a51a4
4 changed files with 58 additions and 39 deletions
|
|
@ -20,8 +20,8 @@ use rustc_span::hygiene::{
|
|||
};
|
||||
use rustc_span::source_map::Spanned;
|
||||
use rustc_span::{
|
||||
BlobDecoder, BytePos, ByteSymbol, CachingSourceMapView, ExpnData, ExpnHash, Pos,
|
||||
RelativeBytePos, SourceFile, Span, SpanDecoder, SpanEncoder, StableSourceFileId, Symbol,
|
||||
BlobDecoder, BytePos, ByteSymbol, CachingSourceMapView, ExpnData, ExpnHash, RelativeBytePos,
|
||||
SourceFile, Span, SpanDecoder, SpanEncoder, StableSourceFileId, Symbol,
|
||||
};
|
||||
|
||||
use crate::dep_graph::{DepNodeIndex, SerializedDepNodeIndex};
|
||||
|
|
@ -652,7 +652,10 @@ impl<'a, 'tcx> SpanDecoder for CacheDecoder<'a, 'tcx> {
|
|||
let dto = u32::decode(self);
|
||||
|
||||
let enclosing = self.tcx.source_span_untracked(parent.unwrap()).data_untracked();
|
||||
(enclosing.lo + BytePos::from_u32(dlo), enclosing.lo + BytePos::from_u32(dto))
|
||||
(
|
||||
BytePos(enclosing.lo.0.wrapping_add(dlo)),
|
||||
BytePos(enclosing.lo.0.wrapping_add(dto)),
|
||||
)
|
||||
}
|
||||
TAG_FULL_SPAN => {
|
||||
let file_lo_index = SourceFileIndex::decode(self);
|
||||
|
|
@ -894,30 +897,33 @@ impl<'a, 'tcx> SpanEncoder for CacheEncoder<'a, 'tcx> {
|
|||
return TAG_PARTIAL_SPAN.encode(self);
|
||||
}
|
||||
|
||||
if let Some(parent) = span_data.parent {
|
||||
let enclosing = self.tcx.source_span_untracked(parent).data_untracked();
|
||||
if enclosing.contains(span_data) {
|
||||
TAG_RELATIVE_SPAN.encode(self);
|
||||
(span_data.lo - enclosing.lo).to_u32().encode(self);
|
||||
(span_data.hi - enclosing.lo).to_u32().encode(self);
|
||||
return;
|
||||
}
|
||||
let parent =
|
||||
span_data.parent.map(|parent| self.tcx.source_span_untracked(parent).data_untracked());
|
||||
if let Some(parent) = parent
|
||||
&& parent.contains(span_data)
|
||||
{
|
||||
TAG_RELATIVE_SPAN.encode(self);
|
||||
(span_data.lo.0.wrapping_sub(parent.lo.0)).encode(self);
|
||||
(span_data.hi.0.wrapping_sub(parent.lo.0)).encode(self);
|
||||
return;
|
||||
}
|
||||
|
||||
let pos = self.source_map.byte_pos_to_line_and_col(span_data.lo);
|
||||
let partial_span = match &pos {
|
||||
Some((file_lo, _, _)) => !file_lo.contains(span_data.hi),
|
||||
None => true,
|
||||
let Some((file_lo, line_lo, col_lo)) =
|
||||
self.source_map.byte_pos_to_line_and_col(span_data.lo)
|
||||
else {
|
||||
return TAG_PARTIAL_SPAN.encode(self);
|
||||
};
|
||||
|
||||
if partial_span {
|
||||
return TAG_PARTIAL_SPAN.encode(self);
|
||||
if let Some(parent) = parent
|
||||
&& file_lo.contains(parent.lo)
|
||||
{
|
||||
TAG_RELATIVE_SPAN.encode(self);
|
||||
(span_data.lo.0.wrapping_sub(parent.lo.0)).encode(self);
|
||||
(span_data.hi.0.wrapping_sub(parent.lo.0)).encode(self);
|
||||
return;
|
||||
}
|
||||
|
||||
let (file_lo, line_lo, col_lo) = pos.unwrap();
|
||||
|
||||
let len = span_data.hi - span_data.lo;
|
||||
|
||||
let source_file_index = self.source_file_index(file_lo);
|
||||
|
||||
TAG_FULL_SPAN.encode(self);
|
||||
|
|
|
|||
|
|
@ -5,9 +5,7 @@ use rustc_hir::definitions::DefPathHash;
|
|||
use rustc_session::Session;
|
||||
use rustc_session::cstore::Untracked;
|
||||
use rustc_span::source_map::SourceMap;
|
||||
use rustc_span::{
|
||||
BytePos, CachingSourceMapView, DUMMY_SP, Span, SpanData, StableSourceFileId, Symbol,
|
||||
};
|
||||
use rustc_span::{BytePos, CachingSourceMapView, DUMMY_SP, SourceFile, Span, SpanData, Symbol};
|
||||
|
||||
use crate::ich;
|
||||
|
||||
|
|
@ -118,7 +116,7 @@ impl<'a> rustc_span::HashStableContext for StableHashingContext<'a> {
|
|||
fn span_data_to_lines_and_cols(
|
||||
&mut self,
|
||||
span: &SpanData,
|
||||
) -> Option<(StableSourceFileId, usize, BytePos, usize, BytePos)> {
|
||||
) -> Option<(&SourceFile, usize, BytePos, usize, BytePos)> {
|
||||
self.source_map().span_data_to_lines_and_cols(span)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use std::ops::Range;
|
|||
use std::sync::Arc;
|
||||
|
||||
use crate::source_map::SourceMap;
|
||||
use crate::{BytePos, Pos, RelativeBytePos, SourceFile, SpanData, StableSourceFileId};
|
||||
use crate::{BytePos, Pos, RelativeBytePos, SourceFile, SpanData};
|
||||
|
||||
#[derive(Clone)]
|
||||
struct CacheEntry {
|
||||
|
|
@ -114,7 +114,7 @@ impl<'sm> CachingSourceMapView<'sm> {
|
|||
pub fn span_data_to_lines_and_cols(
|
||||
&mut self,
|
||||
span_data: &SpanData,
|
||||
) -> Option<(StableSourceFileId, usize, BytePos, usize, BytePos)> {
|
||||
) -> Option<(&SourceFile, usize, BytePos, usize, BytePos)> {
|
||||
self.time_stamp += 1;
|
||||
|
||||
// Check if lo and hi are in the cached lines.
|
||||
|
|
@ -136,7 +136,7 @@ impl<'sm> CachingSourceMapView<'sm> {
|
|||
let lo = &self.line_cache[lo_cache_idx as usize];
|
||||
let hi = &self.line_cache[hi_cache_idx as usize];
|
||||
return Some((
|
||||
lo.file.stable_id,
|
||||
&lo.file,
|
||||
lo.line_number,
|
||||
span_data.lo - lo.line.start,
|
||||
hi.line_number,
|
||||
|
|
@ -224,7 +224,7 @@ impl<'sm> CachingSourceMapView<'sm> {
|
|||
assert_eq!(lo.file_index, hi.file_index);
|
||||
|
||||
Some((
|
||||
lo.file.stable_id,
|
||||
&lo.file,
|
||||
lo.line_number,
|
||||
span_data.lo - lo.line.start,
|
||||
hi.line_number,
|
||||
|
|
|
|||
|
|
@ -2831,7 +2831,7 @@ pub trait HashStableContext {
|
|||
fn span_data_to_lines_and_cols(
|
||||
&mut self,
|
||||
span: &SpanData,
|
||||
) -> Option<(StableSourceFileId, usize, BytePos, usize, BytePos)>;
|
||||
) -> Option<(&SourceFile, usize, BytePos, usize, BytePos)>;
|
||||
fn hashing_controls(&self) -> HashingControls;
|
||||
}
|
||||
|
||||
|
|
@ -2849,6 +2849,8 @@ where
|
|||
/// codepoint offsets. For the purpose of the hash that's sufficient.
|
||||
/// Also, hashing filenames is expensive so we avoid doing it twice when the
|
||||
/// span starts and ends in the same file, which is almost always the case.
|
||||
///
|
||||
/// IMPORTANT: changes to this method should be reflected in implementations of `SpanEncoder`.
|
||||
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
|
||||
const TAG_VALID_SPAN: u8 = 0;
|
||||
const TAG_INVALID_SPAN: u8 = 1;
|
||||
|
|
@ -2867,15 +2869,17 @@ where
|
|||
return;
|
||||
}
|
||||
|
||||
if let Some(parent) = span.parent {
|
||||
let def_span = ctx.def_span(parent).data_untracked();
|
||||
if def_span.contains(span) {
|
||||
// This span is enclosed in a definition: only hash the relative position.
|
||||
Hash::hash(&TAG_RELATIVE_SPAN, hasher);
|
||||
(span.lo - def_span.lo).to_u32().hash_stable(ctx, hasher);
|
||||
(span.hi - def_span.lo).to_u32().hash_stable(ctx, hasher);
|
||||
return;
|
||||
}
|
||||
let parent = span.parent.map(|parent| ctx.def_span(parent).data_untracked());
|
||||
if let Some(parent) = parent
|
||||
&& parent.contains(span)
|
||||
{
|
||||
// This span is enclosed in a definition: only hash the relative position.
|
||||
// This catches a subset of the cases from the `file.contains(parent.lo)`,
|
||||
// But we can do this check cheaply without the expensive `span_data_to_lines_and_cols` query.
|
||||
Hash::hash(&TAG_RELATIVE_SPAN, hasher);
|
||||
(span.lo - parent.lo).to_u32().hash_stable(ctx, hasher);
|
||||
(span.hi - parent.lo).to_u32().hash_stable(ctx, hasher);
|
||||
return;
|
||||
}
|
||||
|
||||
// If this is not an empty or invalid span, we want to hash the last
|
||||
|
|
@ -2887,8 +2891,19 @@ where
|
|||
return;
|
||||
};
|
||||
|
||||
if let Some(parent) = parent
|
||||
&& file.contains(parent.lo)
|
||||
{
|
||||
// This span is relative to another span in the same file,
|
||||
// only hash the relative position.
|
||||
Hash::hash(&TAG_RELATIVE_SPAN, hasher);
|
||||
Hash::hash(&(span.lo.0.wrapping_sub(parent.lo.0)), hasher);
|
||||
Hash::hash(&(span.hi.0.wrapping_sub(parent.lo.0)), hasher);
|
||||
return;
|
||||
}
|
||||
|
||||
Hash::hash(&TAG_VALID_SPAN, hasher);
|
||||
Hash::hash(&file, hasher);
|
||||
Hash::hash(&file.stable_id, hasher);
|
||||
|
||||
// Hash both the length and the end location (line/column) of a span. If we
|
||||
// hash only the length, for example, then two otherwise equal spans with
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue