Skip to content

Commit

Permalink
Encode spans relative to their parent.
Browse files Browse the repository at this point in the history
  • Loading branch information
cjgillot committed Sep 10, 2021
1 parent 00485e0 commit e85ddeb
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 16 deletions.
7 changes: 7 additions & 0 deletions compiler/rustc_ast_lowering/src/lib.rs
Expand Up @@ -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>>;
Expand Down Expand Up @@ -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)
Expand Down
7 changes: 6 additions & 1 deletion compiler/rustc_middle/src/ich/hcx.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand Down
48 changes: 36 additions & 12 deletions compiler/rustc_query_impl/src/on_disk_cache.rs
Expand Up @@ -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;

Expand All @@ -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;
Expand Down Expand Up @@ -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);
}
Expand All @@ -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))
}
}

Expand Down Expand Up @@ -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);
Expand All @@ -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();
Expand All @@ -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)
}
}

Expand Down
10 changes: 10 additions & 0 deletions compiler/rustc_resolve/src/lib.rs
Expand Up @@ -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]
Expand Down Expand Up @@ -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)
Expand Down
20 changes: 17 additions & 3 deletions compiler/rustc_span/src/lib.rs
Expand Up @@ -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,
Expand All @@ -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,
Expand Down

0 comments on commit e85ddeb

Please sign in to comment.