From 579037273681da121a4bfd81e00750b924c57a5e Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 6 Sep 2023 10:05:35 +1000 Subject: [PATCH] Optimize `Span::is_dummy`. It's quite hot, and worth having a version that works directly at the `Span` level, rather than first converting to the `SpanData` level. --- compiler/rustc_span/src/lib.rs | 12 +----------- compiler/rustc_span/src/span_encoding.rs | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index f1a6e9059d7..148a1391d76 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -510,10 +510,6 @@ impl SpanData { pub fn is_dummy(self) -> bool { self.lo.0 == 0 && self.hi.0 == 0 } - #[inline] - pub fn is_visible(self, sm: &SourceMap) -> bool { - !self.is_dummy() && sm.is_span_accessible(self.span()) - } /// Returns `true` if `self` fully encloses `other`. pub fn contains(self, other: Self) -> bool { self.lo <= other.lo && other.hi <= self.hi @@ -573,15 +569,9 @@ impl Span { self.data().with_parent(ctxt) } - /// Returns `true` if this is a dummy span with any hygienic context. - #[inline] - pub fn is_dummy(self) -> bool { - self.data_untracked().is_dummy() - } - #[inline] pub fn is_visible(self, sm: &SourceMap) -> bool { - self.data_untracked().is_visible(sm) + !self.is_dummy() && sm.is_span_accessible(self) } /// Returns `true` if this span comes from any kind of macro, desugaring or inlining. diff --git a/compiler/rustc_span/src/span_encoding.rs b/compiler/rustc_span/src/span_encoding.rs index 7717469c21a..93ab154601f 100644 --- a/compiler/rustc_span/src/span_encoding.rs +++ b/compiler/rustc_span/src/span_encoding.rs @@ -193,6 +193,23 @@ impl Span { } } + /// Returns `true` if this is a dummy span with any hygienic context. + #[inline] + pub fn is_dummy(self) -> bool { + if self.len_with_tag_or_marker != BASE_LEN_INTERNED_MARKER { + // Inline-context or inline-parent format. + let lo = self.lo_or_index; + let len = (self.len_with_tag_or_marker & !PARENT_TAG) as u32; + debug_assert!(len <= MAX_LEN); + lo == 0 && len == 0 + } else { + // Fully-interned or partially-interned format. + let index = self.lo_or_index; + let data = with_span_interner(|interner| interner.spans[index as usize]); + data.lo == BytePos(0) && data.hi == BytePos(0) + } + } + /// This function is used as a fast path when decoding the full `SpanData` is not necessary. /// It's a cut-down version of `data_untracked`. #[inline]