mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-23 21:23:20 +00:00
Encode spans relative to their parent.
This commit is contained in:
parent
00485e0c0e
commit
e85ddeb474
@ -165,6 +165,8 @@ struct LoweringContext<'a, 'hir: 'a> {
|
||||
pub trait ResolverAstLowering {
|
||||
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 legacy_const_generic_args(&mut self, expr: &Expr) -> Option<Vec<usize>>;
|
||||
@ -215,6 +217,11 @@ impl<'a> rustc_span::HashStableContext for LoweringHasher<'a> {
|
||||
true
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn def_span(&self, id: LocalDefId) -> Span {
|
||||
self.resolver.def_span(id)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn def_path_hash(&self, def_id: DefId) -> DefPathHash {
|
||||
self.resolver.def_path_hash(def_id)
|
||||
|
@ -12,7 +12,7 @@ use rustc_hir::definitions::{DefPathHash, Definitions};
|
||||
use rustc_session::Session;
|
||||
use rustc_span::source_map::SourceMap;
|
||||
use rustc_span::symbol::Symbol;
|
||||
use rustc_span::{BytePos, CachingSourceMapView, SourceFile, SpanData};
|
||||
use rustc_span::{BytePos, CachingSourceMapView, SourceFile, Span, SpanData};
|
||||
|
||||
use smallvec::SmallVec;
|
||||
use std::cmp::Ord;
|
||||
@ -229,6 +229,11 @@ impl<'a> rustc_span::HashStableContext for StableHashingContext<'a> {
|
||||
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(
|
||||
&mut self,
|
||||
span: &SpanData,
|
||||
|
@ -23,7 +23,7 @@ use rustc_span::hygiene::{
|
||||
};
|
||||
use rustc_span::source_map::{SourceMap, StableSourceFileId};
|
||||
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::mem;
|
||||
|
||||
@ -33,6 +33,7 @@ const TAG_FILE_FOOTER: u128 = 0xC0FFEE_C0FFEE_C0FFEE_C0FFEE_C0FFEE;
|
||||
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_RELATIVE_SPAN: u8 = 2;
|
||||
|
||||
const TAG_SYNTAX_CONTEXT: u8 = 0;
|
||||
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 {
|
||||
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)?;
|
||||
|
||||
if tag == TAG_PARTIAL_SPAN {
|
||||
let ctxt = SyntaxContext::decode(decoder)?;
|
||||
return Ok(DUMMY_SP.with_ctxt(ctxt));
|
||||
return Ok(Span::new(BytePos(0), BytePos(0), ctxt, parent));
|
||||
} 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 {
|
||||
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 col_lo = 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 lo = file_lo.lines[line_lo - 1] + col_lo;
|
||||
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> {
|
||||
let span_data = self.data();
|
||||
if self.is_dummy() {
|
||||
TAG_PARTIAL_SPAN.encode(s)?;
|
||||
return span_data.ctxt.encode(s);
|
||||
span_data.ctxt.encode(s)?;
|
||||
span_data.parent.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);
|
||||
@ -1021,8 +1047,7 @@ where
|
||||
};
|
||||
|
||||
if partial_span {
|
||||
TAG_PARTIAL_SPAN.encode(s)?;
|
||||
return span_data.ctxt.encode(s);
|
||||
return TAG_PARTIAL_SPAN.encode(s);
|
||||
}
|
||||
|
||||
let (file_lo, line_lo, col_lo) = pos.unwrap();
|
||||
@ -1035,8 +1060,7 @@ where
|
||||
source_file_index.encode(s)?;
|
||||
line_lo.encode(s)?;
|
||||
col_lo.encode(s)?;
|
||||
len.encode(s)?;
|
||||
span_data.ctxt.encode(s)
|
||||
len.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 {
|
||||
if let Some(def_id) = def_id.as_local() {
|
||||
self.item_generics_num_lifetimes[&def_id]
|
||||
@ -1221,6 +1226,11 @@ impl<'a, 'b> rustc_span::HashStableContext for ExpandHasher<'a, 'b> {
|
||||
true
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn def_span(&self, id: LocalDefId) -> Span {
|
||||
self.resolver.def_span(id)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn def_path_hash(&self, def_id: DefId) -> DefPathHash {
|
||||
self.resolver.def_path_hash(def_id)
|
||||
|
@ -2001,6 +2001,7 @@ impl InnerSpan {
|
||||
pub trait HashStableContext {
|
||||
fn def_path_hash(&self, def_id: DefId) -> DefPathHash;
|
||||
fn hash_spans(&self) -> bool;
|
||||
fn def_span(&self, def_id: LocalDefId) -> Span;
|
||||
fn span_data_to_lines_and_cols(
|
||||
&mut self,
|
||||
span: &SpanData,
|
||||
@ -2024,22 +2025,35 @@ where
|
||||
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
|
||||
const TAG_VALID_SPAN: u8 = 0;
|
||||
const TAG_INVALID_SPAN: u8 = 1;
|
||||
const TAG_RELATIVE_SPAN: u8 = 2;
|
||||
|
||||
if !ctx.hash_spans() {
|
||||
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);
|
||||
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
|
||||
// position that belongs to it, as opposed to hashing the first
|
||||
// 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)
|
||||
{
|
||||
Some(pos) => pos,
|
||||
|
Loading…
Reference in New Issue
Block a user