diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index c20bbcca44f75..e619129d21290 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -226,7 +226,7 @@ struct SpanLowerer { impl SpanLowerer { fn lower(&self, span: Span) -> Span { if self.is_incremental { - span.with_parent(Some(self.def_id)) + span.with_parent_untracked(Some(self.def_id)) } else { // Do not make spans relative when not using incremental compilation. span diff --git a/compiler/rustc_span/src/span_encoding.rs b/compiler/rustc_span/src/span_encoding.rs index e34efa784dee6..ef457b51258a4 100644 --- a/compiler/rustc_span/src/span_encoding.rs +++ b/compiler/rustc_span/src/span_encoding.rs @@ -429,6 +429,36 @@ impl Span { data.with_parent(parent) } + #[inline] + pub fn with_parent_untracked(self, parent: Option) -> Span { + let data = match_span_kind! { + self, + InlineCtxt(span) => { + // This format occurs 1-2 orders of magnitude more often than others (#126544), + // so it makes sense to micro-optimize it to avoid `span.data()` and `Span::new()`. + // Copypaste from `Span::new`, the small len & ctxt conditions are known to hold. + match parent { + None => return self, + Some(parent) => { + let parent32 = parent.local_def_index.as_u32(); + if span.ctxt == 0 && parent32 <= MAX_CTXT { + return InlineParent::span(span.lo, span.len, parent32 as u16); + } + } + } + span.data() + }, + InlineParent(span) => span.data(), + PartiallyInterned(span) => span.data(), + Interned(span) => span.data(), + }; + + if let Some(_old_parent) = data.parent { + // (*SPAN_TRACK)(old_parent); + } + data.with_parent(parent) + } + #[inline] pub fn parent(self) -> Option { let interned_parent =