Auto merge of #84373 - cjgillot:resolve-span, r=michaelwoerister,petrochenkov
Encode spans relative to the enclosing item The aim of this PR is to avoid recomputing queries when code is moved without modification. MCP at https://github.com/rust-lang/compiler-team/issues/443 This is achieved by : 1. storing the HIR owner LocalDefId information inside the span; 2. encoding and decoding spans relative to the enclosing item in the incremental on-disk cache; 3. marking a dependency to the `source_span(LocalDefId)` query when we translate a span from the short (`Span`) representation to its explicit (`SpanData`) representation. Since all client code uses `Span`, step 3 ensures that all manipulations of span byte positions actually create the dependency edge between the caller and the `source_span(LocalDefId)`. This query return the actual absolute span of the parent item. As a consequence, any source code motion that changes the absolute byte position of a node will either: - modify the distance to the parent's beginning, so change the relative span's hash; - dirty `source_span`, and trigger the incremental recomputation of all code that depends on the span's absolute byte position. With this scheme, I believe the dependency tracking to be accurate. For the moment, the spans are marked during lowering. I'd rather do this during def-collection, but the AST MutVisitor is not practical enough just yet. The only difference is that we attach macro-expanded spans to their expansion point instead of the macro itself.
This commit is contained in:
commit
547d9374d2
68 changed files with 2800 additions and 1170 deletions
|
@ -422,7 +422,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
let if_kind = hir::ExprKind::If(new_cond, self.arena.alloc(then), Some(else_expr));
|
||||
let if_expr = self.expr(span, if_kind, ThinVec::new());
|
||||
let block = self.block_expr(self.arena.alloc(if_expr));
|
||||
hir::ExprKind::Loop(block, opt_label, hir::LoopSource::While, span.with_hi(cond.span.hi()))
|
||||
let span = self.lower_span(span.with_hi(cond.span.hi()));
|
||||
let opt_label = self.lower_label(opt_label);
|
||||
hir::ExprKind::Loop(block, opt_label, hir::LoopSource::While, span)
|
||||
}
|
||||
|
||||
/// Desugar `try { <stmts>; <expr> }` into `{ <stmts>; ::std::ops::Try::from_output(<expr>) }`,
|
||||
|
|
|
@ -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)
|
||||
|
@ -711,9 +718,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
}
|
||||
|
||||
/// Intercept all spans entering HIR.
|
||||
/// For now we are not doing anything with the intercepted spans.
|
||||
/// Mark a span as relative to the current owning item.
|
||||
fn lower_span(&self, span: Span) -> Span {
|
||||
span
|
||||
if self.sess.opts.debugging_opts.incremental_relative_spans {
|
||||
span.with_parent(Some(self.current_hir_id_owner.0))
|
||||
} else {
|
||||
// Do not make spans relative when not using incremental compilation.
|
||||
span
|
||||
}
|
||||
}
|
||||
|
||||
fn lower_ident(&self, ident: Ident) -> Ident {
|
||||
|
@ -781,7 +793,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
node_id,
|
||||
DefPathData::LifetimeNs(str_name),
|
||||
ExpnId::root(),
|
||||
span,
|
||||
span.with_parent(None),
|
||||
);
|
||||
|
||||
hir::GenericParam {
|
||||
|
@ -1513,7 +1525,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
def_node_id,
|
||||
DefPathData::LifetimeNs(name.ident().name),
|
||||
ExpnId::root(),
|
||||
span,
|
||||
span.with_parent(None),
|
||||
);
|
||||
|
||||
let (name, kind) = match name {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue