Encode spans relative to their parent.
This commit is contained in:
parent
00485e0c0e
commit
e85ddeb474
5 changed files with 76 additions and 16 deletions
|
@ -165,6 +165,8 @@ struct LoweringContext<'a, 'hir: 'a> {
|
||||||
pub trait ResolverAstLowering {
|
pub trait ResolverAstLowering {
|
||||||
fn def_key(&mut self, id: DefId) -> DefKey;
|
fn def_key(&mut self, id: DefId) -> DefKey;
|
||||||
|
|
||||||
|
fn def_span(&self, id: LocalDefId) -> Span;
|
||||||
|
|
||||||
fn item_generics_num_lifetimes(&self, def: DefId) -> usize;
|
fn item_generics_num_lifetimes(&self, def: DefId) -> usize;
|
||||||
|
|
||||||
fn legacy_const_generic_args(&mut self, expr: &Expr) -> Option<Vec<usize>>;
|
fn legacy_const_generic_args(&mut self, expr: &Expr) -> Option<Vec<usize>>;
|
||||||
|
@ -215,6 +217,11 @@ impl<'a> rustc_span::HashStableContext for LoweringHasher<'a> {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn def_span(&self, id: LocalDefId) -> Span {
|
||||||
|
self.resolver.def_span(id)
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn def_path_hash(&self, def_id: DefId) -> DefPathHash {
|
fn def_path_hash(&self, def_id: DefId) -> DefPathHash {
|
||||||
self.resolver.def_path_hash(def_id)
|
self.resolver.def_path_hash(def_id)
|
||||||
|
|
|
@ -12,7 +12,7 @@ use rustc_hir::definitions::{DefPathHash, Definitions};
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
use rustc_span::source_map::SourceMap;
|
use rustc_span::source_map::SourceMap;
|
||||||
use rustc_span::symbol::Symbol;
|
use rustc_span::symbol::Symbol;
|
||||||
use rustc_span::{BytePos, CachingSourceMapView, SourceFile, SpanData};
|
use rustc_span::{BytePos, CachingSourceMapView, SourceFile, Span, SpanData};
|
||||||
|
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::cmp::Ord;
|
use std::cmp::Ord;
|
||||||
|
@ -229,6 +229,11 @@ impl<'a> rustc_span::HashStableContext for StableHashingContext<'a> {
|
||||||
self.def_path_hash(def_id)
|
self.def_path_hash(def_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn def_span(&self, def_id: LocalDefId) -> Span {
|
||||||
|
self.definitions.def_span(def_id)
|
||||||
|
}
|
||||||
|
|
||||||
fn span_data_to_lines_and_cols(
|
fn span_data_to_lines_and_cols(
|
||||||
&mut self,
|
&mut self,
|
||||||
span: &SpanData,
|
span: &SpanData,
|
||||||
|
|
|
@ -23,7 +23,7 @@ use rustc_span::hygiene::{
|
||||||
};
|
};
|
||||||
use rustc_span::source_map::{SourceMap, StableSourceFileId};
|
use rustc_span::source_map::{SourceMap, StableSourceFileId};
|
||||||
use rustc_span::CachingSourceMapView;
|
use rustc_span::CachingSourceMapView;
|
||||||
use rustc_span::{BytePos, ExpnData, ExpnHash, SourceFile, Span, DUMMY_SP};
|
use rustc_span::{BytePos, ExpnData, ExpnHash, Pos, SourceFile, Span};
|
||||||
use std::collections::hash_map::Entry;
|
use std::collections::hash_map::Entry;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@ const TAG_FILE_FOOTER: u128 = 0xC0FFEE_C0FFEE_C0FFEE_C0FFEE_C0FFEE;
|
||||||
const TAG_FULL_SPAN: u8 = 0;
|
const TAG_FULL_SPAN: u8 = 0;
|
||||||
// A partial span with no location information, encoded only with a `SyntaxContext`
|
// A partial span with no location information, encoded only with a `SyntaxContext`
|
||||||
const TAG_PARTIAL_SPAN: u8 = 1;
|
const TAG_PARTIAL_SPAN: u8 = 1;
|
||||||
|
const TAG_RELATIVE_SPAN: u8 = 2;
|
||||||
|
|
||||||
const TAG_SYNTAX_CONTEXT: u8 = 0;
|
const TAG_SYNTAX_CONTEXT: u8 = 0;
|
||||||
const TAG_EXPN_DATA: u8 = 1;
|
const TAG_EXPN_DATA: u8 = 1;
|
||||||
|
@ -829,11 +830,25 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for ExpnId {
|
||||||
|
|
||||||
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for Span {
|
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 ctxt = SyntaxContext::decode(decoder)?;
|
||||||
|
let parent = Option::<LocalDefId>::decode(decoder)?;
|
||||||
let tag: u8 = Decodable::decode(decoder)?;
|
let tag: u8 = Decodable::decode(decoder)?;
|
||||||
|
|
||||||
if tag == TAG_PARTIAL_SPAN {
|
if tag == TAG_PARTIAL_SPAN {
|
||||||
let ctxt = SyntaxContext::decode(decoder)?;
|
return Ok(Span::new(BytePos(0), BytePos(0), ctxt, parent));
|
||||||
return Ok(DUMMY_SP.with_ctxt(ctxt));
|
} else if tag == TAG_RELATIVE_SPAN {
|
||||||
|
let dlo = u32::decode(decoder)?;
|
||||||
|
let dto = u32::decode(decoder)?;
|
||||||
|
|
||||||
|
let enclosing = decoder.tcx.definitions_untracked().def_span(parent.unwrap()).data();
|
||||||
|
let span = Span::new(
|
||||||
|
enclosing.lo + BytePos::from_u32(dlo),
|
||||||
|
enclosing.lo + BytePos::from_u32(dto),
|
||||||
|
ctxt,
|
||||||
|
parent,
|
||||||
|
);
|
||||||
|
|
||||||
|
return Ok(span);
|
||||||
} else {
|
} else {
|
||||||
debug_assert_eq!(tag, TAG_FULL_SPAN);
|
debug_assert_eq!(tag, TAG_FULL_SPAN);
|
||||||
}
|
}
|
||||||
|
@ -842,13 +857,12 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for Span {
|
||||||
let line_lo = usize::decode(decoder)?;
|
let line_lo = usize::decode(decoder)?;
|
||||||
let col_lo = BytePos::decode(decoder)?;
|
let col_lo = BytePos::decode(decoder)?;
|
||||||
let len = BytePos::decode(decoder)?;
|
let len = BytePos::decode(decoder)?;
|
||||||
let ctxt = SyntaxContext::decode(decoder)?;
|
|
||||||
|
|
||||||
let file_lo = decoder.file_index_to_file(file_lo_index);
|
let file_lo = decoder.file_index_to_file(file_lo_index);
|
||||||
let lo = file_lo.lines[line_lo - 1] + col_lo;
|
let lo = file_lo.lines[line_lo - 1] + col_lo;
|
||||||
let hi = lo + len;
|
let hi = lo + len;
|
||||||
|
|
||||||
Ok(Span::new(lo, hi, ctxt, None))
|
Ok(Span::new(lo, hi, ctxt, parent))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1009,9 +1023,21 @@ 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> {
|
||||||
let span_data = self.data();
|
let span_data = self.data();
|
||||||
if self.is_dummy() {
|
span_data.ctxt.encode(s)?;
|
||||||
TAG_PARTIAL_SPAN.encode(s)?;
|
span_data.parent.encode(s)?;
|
||||||
return span_data.ctxt.encode(s);
|
|
||||||
|
if span_data.is_dummy() {
|
||||||
|
return TAG_PARTIAL_SPAN.encode(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(parent) = span_data.parent {
|
||||||
|
let enclosing = s.tcx.definitions_untracked().def_span(parent).data();
|
||||||
|
if enclosing.contains(span_data) {
|
||||||
|
TAG_RELATIVE_SPAN.encode(s)?;
|
||||||
|
(span_data.lo - enclosing.lo).to_u32().encode(s)?;
|
||||||
|
(span_data.hi - enclosing.lo).to_u32().encode(s)?;
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let pos = 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);
|
||||||
|
@ -1021,8 +1047,7 @@ where
|
||||||
};
|
};
|
||||||
|
|
||||||
if partial_span {
|
if partial_span {
|
||||||
TAG_PARTIAL_SPAN.encode(s)?;
|
return TAG_PARTIAL_SPAN.encode(s);
|
||||||
return span_data.ctxt.encode(s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let (file_lo, line_lo, col_lo) = pos.unwrap();
|
let (file_lo, line_lo, col_lo) = pos.unwrap();
|
||||||
|
@ -1035,8 +1060,7 @@ where
|
||||||
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)?;
|
||||||
len.encode(s)?;
|
len.encode(s)
|
||||||
span_data.ctxt.encode(s)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1114,6 +1114,11 @@ impl ResolverAstLowering for Resolver<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn def_span(&self, id: LocalDefId) -> Span {
|
||||||
|
self.definitions.def_span(id)
|
||||||
|
}
|
||||||
|
|
||||||
fn item_generics_num_lifetimes(&self, def_id: DefId) -> usize {
|
fn item_generics_num_lifetimes(&self, def_id: DefId) -> usize {
|
||||||
if let Some(def_id) = def_id.as_local() {
|
if let Some(def_id) = def_id.as_local() {
|
||||||
self.item_generics_num_lifetimes[&def_id]
|
self.item_generics_num_lifetimes[&def_id]
|
||||||
|
@ -1221,6 +1226,11 @@ impl<'a, 'b> rustc_span::HashStableContext for ExpandHasher<'a, 'b> {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn def_span(&self, id: LocalDefId) -> Span {
|
||||||
|
self.resolver.def_span(id)
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn def_path_hash(&self, def_id: DefId) -> DefPathHash {
|
fn def_path_hash(&self, def_id: DefId) -> DefPathHash {
|
||||||
self.resolver.def_path_hash(def_id)
|
self.resolver.def_path_hash(def_id)
|
||||||
|
|
|
@ -2001,6 +2001,7 @@ impl InnerSpan {
|
||||||
pub trait HashStableContext {
|
pub trait HashStableContext {
|
||||||
fn def_path_hash(&self, def_id: DefId) -> DefPathHash;
|
fn def_path_hash(&self, def_id: DefId) -> DefPathHash;
|
||||||
fn hash_spans(&self) -> bool;
|
fn hash_spans(&self) -> bool;
|
||||||
|
fn def_span(&self, def_id: LocalDefId) -> Span;
|
||||||
fn span_data_to_lines_and_cols(
|
fn span_data_to_lines_and_cols(
|
||||||
&mut self,
|
&mut self,
|
||||||
span: &SpanData,
|
span: &SpanData,
|
||||||
|
@ -2024,22 +2025,35 @@ where
|
||||||
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
|
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
|
||||||
const TAG_VALID_SPAN: u8 = 0;
|
const TAG_VALID_SPAN: u8 = 0;
|
||||||
const TAG_INVALID_SPAN: u8 = 1;
|
const TAG_INVALID_SPAN: u8 = 1;
|
||||||
|
const TAG_RELATIVE_SPAN: u8 = 2;
|
||||||
|
|
||||||
if !ctx.hash_spans() {
|
if !ctx.hash_spans() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.ctxt().hash_stable(ctx, hasher);
|
let span = self.data();
|
||||||
|
span.ctxt.hash_stable(ctx, hasher);
|
||||||
|
span.parent.hash_stable(ctx, hasher);
|
||||||
|
|
||||||
if self.is_dummy() {
|
if span.is_dummy() {
|
||||||
Hash::hash(&TAG_INVALID_SPAN, hasher);
|
Hash::hash(&TAG_INVALID_SPAN, hasher);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(parent) = span.parent {
|
||||||
|
let def_span = ctx.def_span(parent).data();
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If this is not an empty or invalid span, we want to hash the last
|
// If this is not an empty or invalid span, we want to hash the last
|
||||||
// position that belongs to it, as opposed to hashing the first
|
// position that belongs to it, as opposed to hashing the first
|
||||||
// position past it.
|
// position past it.
|
||||||
let span = self.data();
|
|
||||||
let (file, line_lo, col_lo, line_hi, col_hi) = match ctx.span_data_to_lines_and_cols(&span)
|
let (file, line_lo, col_lo, line_hi, col_hi) = match ctx.span_data_to_lines_and_cols(&span)
|
||||||
{
|
{
|
||||||
Some(pos) => pos,
|
Some(pos) => pos,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue