mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-04 19:29:07 +00:00
Track span dependency using a callback.
This commit is contained in:
parent
e85ddeb474
commit
b19ae20aad
@ -25,6 +25,14 @@ fn span_debug(span: rustc_span::Span, f: &mut fmt::Formatter<'_>) -> fmt::Result
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn track_span_parent(def_id: rustc_span::def_id::LocalDefId) {
|
||||||
|
tls::with_opt(|tcx| {
|
||||||
|
if let Some(tcx) = tcx {
|
||||||
|
let _ = tcx.source_span(def_id);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/// This is a callback from `rustc_ast` as it cannot access the implicit state
|
/// This is a callback from `rustc_ast` as it cannot access the implicit state
|
||||||
/// in `rustc_middle` otherwise. It is used to when diagnostic messages are
|
/// in `rustc_middle` otherwise. It is used to when diagnostic messages are
|
||||||
/// emitted and stores them in the current query, if there is one.
|
/// emitted and stores them in the current query, if there is one.
|
||||||
@ -56,6 +64,7 @@ fn def_id_debug(def_id: rustc_hir::def_id::DefId, f: &mut fmt::Formatter<'_>) ->
|
|||||||
/// TyCtxt in.
|
/// TyCtxt in.
|
||||||
pub fn setup_callbacks() {
|
pub fn setup_callbacks() {
|
||||||
rustc_span::SPAN_DEBUG.swap(&(span_debug as fn(_, &mut fmt::Formatter<'_>) -> _));
|
rustc_span::SPAN_DEBUG.swap(&(span_debug as fn(_, &mut fmt::Formatter<'_>) -> _));
|
||||||
|
rustc_span::SPAN_TRACK.swap(&(track_span_parent as fn(_)));
|
||||||
rustc_hir::def_id::DEF_ID_DEBUG.swap(&(def_id_debug as fn(_, &mut fmt::Formatter<'_>) -> _));
|
rustc_hir::def_id::DEF_ID_DEBUG.swap(&(def_id_debug as fn(_, &mut fmt::Formatter<'_>) -> _));
|
||||||
TRACK_DIAGNOSTICS.swap(&(track_diagnostic as fn(&_)));
|
TRACK_DIAGNOSTICS.swap(&(track_diagnostic as fn(&_)));
|
||||||
}
|
}
|
||||||
|
@ -153,6 +153,7 @@ pub fn provide(providers: &mut Providers) {
|
|||||||
index.parenting.get(&id).copied().unwrap_or(CRATE_HIR_ID)
|
index.parenting.get(&id).copied().unwrap_or(CRATE_HIR_ID)
|
||||||
};
|
};
|
||||||
providers.hir_attrs = |tcx, id| AttributeMap { map: &tcx.untracked_crate.attrs, prefix: id };
|
providers.hir_attrs = |tcx, id| AttributeMap { map: &tcx.untracked_crate.attrs, prefix: id };
|
||||||
|
providers.source_span = |tcx, def_id| tcx.resolutions(()).definitions.def_span(def_id);
|
||||||
providers.def_span = |tcx, def_id| tcx.hir().span_if_local(def_id).unwrap_or(DUMMY_SP);
|
providers.def_span = |tcx, def_id| tcx.hir().span_if_local(def_id).unwrap_or(DUMMY_SP);
|
||||||
providers.fn_arg_names = |tcx, id| {
|
providers.fn_arg_names = |tcx, id| {
|
||||||
let hir = tcx.hir();
|
let hir = tcx.hir();
|
||||||
|
@ -20,6 +20,14 @@ rustc_queries! {
|
|||||||
desc { "get the resolver outputs" }
|
desc { "get the resolver outputs" }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return the span for a definition.
|
||||||
|
/// Contrary to `def_span` below, this query returns the full absolute span of the definition.
|
||||||
|
/// This span is meant for dep-tracking rather than diagnostics. It should not be used outside
|
||||||
|
/// of rustc_middle::hir::source_map.
|
||||||
|
query source_span(key: LocalDefId) -> Span {
|
||||||
|
desc { "get the source span" }
|
||||||
|
}
|
||||||
|
|
||||||
/// Represents crate as a whole (as distinct from the top-level crate module).
|
/// Represents crate as a whole (as distinct from the top-level crate module).
|
||||||
/// If you call `hir_crate` (e.g., indirectly by calling `tcx.hir().krate()`),
|
/// If you call `hir_crate` (e.g., indirectly by calling `tcx.hir().krate()`),
|
||||||
/// we will have to assume that any change means that you need to be recompiled.
|
/// we will have to assume that any change means that you need to be recompiled.
|
||||||
|
@ -840,7 +840,7 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for Span {
|
|||||||
let dlo = u32::decode(decoder)?;
|
let dlo = u32::decode(decoder)?;
|
||||||
let dto = u32::decode(decoder)?;
|
let dto = u32::decode(decoder)?;
|
||||||
|
|
||||||
let enclosing = decoder.tcx.definitions_untracked().def_span(parent.unwrap()).data();
|
let enclosing = decoder.tcx.definitions_untracked().def_span(parent.unwrap()).decode();
|
||||||
let span = Span::new(
|
let span = Span::new(
|
||||||
enclosing.lo + BytePos::from_u32(dlo),
|
enclosing.lo + BytePos::from_u32(dlo),
|
||||||
enclosing.lo + BytePos::from_u32(dto),
|
enclosing.lo + BytePos::from_u32(dto),
|
||||||
@ -1022,7 +1022,7 @@ where
|
|||||||
E: 'a + OpaqueEncoder,
|
E: 'a + OpaqueEncoder,
|
||||||
{
|
{
|
||||||
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.decode();
|
||||||
span_data.ctxt.encode(s)?;
|
span_data.ctxt.encode(s)?;
|
||||||
span_data.parent.encode(s)?;
|
span_data.parent.encode(s)?;
|
||||||
|
|
||||||
@ -1031,7 +1031,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(parent) = span_data.parent {
|
if let Some(parent) = span_data.parent {
|
||||||
let enclosing = s.tcx.definitions_untracked().def_span(parent).data();
|
let enclosing = s.tcx.definitions_untracked().def_span(parent).decode();
|
||||||
if enclosing.contains(span_data) {
|
if enclosing.contains(span_data) {
|
||||||
TAG_RELATIVE_SPAN.encode(s)?;
|
TAG_RELATIVE_SPAN.encode(s)?;
|
||||||
(span_data.lo - enclosing.lo).to_u32().encode(s)?;
|
(span_data.lo - enclosing.lo).to_u32().encode(s)?;
|
||||||
|
@ -1947,6 +1947,7 @@ pub struct FileLines {
|
|||||||
|
|
||||||
pub static SPAN_DEBUG: AtomicRef<fn(Span, &mut fmt::Formatter<'_>) -> fmt::Result> =
|
pub static SPAN_DEBUG: AtomicRef<fn(Span, &mut fmt::Formatter<'_>) -> fmt::Result> =
|
||||||
AtomicRef::new(&(default_span_debug as fn(_, &mut fmt::Formatter<'_>) -> _));
|
AtomicRef::new(&(default_span_debug as fn(_, &mut fmt::Formatter<'_>) -> _));
|
||||||
|
pub static SPAN_TRACK: AtomicRef<fn(LocalDefId)> = AtomicRef::new(&((|_| {}) as fn(_)));
|
||||||
|
|
||||||
// _____________________________________________________________________________
|
// _____________________________________________________________________________
|
||||||
// SpanLinesError, SpanSnippetError, DistinctSources, MalformedSourceMapPositions
|
// SpanLinesError, SpanSnippetError, DistinctSources, MalformedSourceMapPositions
|
||||||
@ -2031,7 +2032,7 @@ where
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let span = self.data();
|
let span = self.decode();
|
||||||
span.ctxt.hash_stable(ctx, hasher);
|
span.ctxt.hash_stable(ctx, hasher);
|
||||||
span.parent.hash_stable(ctx, hasher);
|
span.parent.hash_stable(ctx, hasher);
|
||||||
|
|
||||||
@ -2041,7 +2042,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(parent) = span.parent {
|
if let Some(parent) = span.parent {
|
||||||
let def_span = ctx.def_span(parent).data();
|
let def_span = ctx.def_span(parent).decode();
|
||||||
if def_span.contains(span) {
|
if def_span.contains(span) {
|
||||||
// This span is enclosed in a definition: only hash the relative position.
|
// This span is enclosed in a definition: only hash the relative position.
|
||||||
Hash::hash(&TAG_RELATIVE_SPAN, hasher);
|
Hash::hash(&TAG_RELATIVE_SPAN, hasher);
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
use crate::def_id::LocalDefId;
|
use crate::def_id::LocalDefId;
|
||||||
use crate::hygiene::SyntaxContext;
|
use crate::hygiene::SyntaxContext;
|
||||||
|
use crate::SPAN_TRACK;
|
||||||
use crate::{BytePos, SpanData};
|
use crate::{BytePos, SpanData};
|
||||||
|
|
||||||
use rustc_data_structures::fx::FxIndexSet;
|
use rustc_data_structures::fx::FxIndexSet;
|
||||||
@ -55,6 +56,10 @@ use rustc_data_structures::fx::FxIndexSet;
|
|||||||
/// the code. No crates in `rustc-perf` need more than 15 bits for `ctxt`,
|
/// the code. No crates in `rustc-perf` need more than 15 bits for `ctxt`,
|
||||||
/// but larger crates might need more than 16 bits.
|
/// but larger crates might need more than 16 bits.
|
||||||
///
|
///
|
||||||
|
/// In order to reliably use parented spans in incremental compilation,
|
||||||
|
/// the dependency to the parent definition's span. This is performed
|
||||||
|
/// using the callback `SPAN_TRACK` to access the query engine.
|
||||||
|
///
|
||||||
#[derive(Clone, Copy, Eq, PartialEq, Hash)]
|
#[derive(Clone, Copy, Eq, PartialEq, Hash)]
|
||||||
pub struct Span {
|
pub struct Span {
|
||||||
base_or_index: u32,
|
base_or_index: u32,
|
||||||
@ -96,6 +101,17 @@ impl Span {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn data(self) -> SpanData {
|
pub fn data(self) -> SpanData {
|
||||||
|
let data = self.decode();
|
||||||
|
if let Some(parent) = data.parent {
|
||||||
|
(*SPAN_TRACK)(parent);
|
||||||
|
}
|
||||||
|
data
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Internal function to translate between an encoded span and the expanded representation.
|
||||||
|
/// This function must not be used outside the incremental engine.
|
||||||
|
#[inline]
|
||||||
|
pub fn decode(self) -> SpanData {
|
||||||
if self.len_or_tag != LEN_TAG {
|
if self.len_or_tag != LEN_TAG {
|
||||||
// Inline format.
|
// Inline format.
|
||||||
debug_assert!(self.len_or_tag as u32 <= MAX_LEN);
|
debug_assert!(self.len_or_tag as u32 <= MAX_LEN);
|
||||||
|
Loading…
Reference in New Issue
Block a user