about summary refs log tree commit diff
path: root/compiler/rustc_span/src
diff options
context:
space:
mode:
authorMatthias Krüger <476013+matthiaskrgr@users.noreply.github.com>2025-05-02 19:37:56 +0200
committerGitHub <noreply@github.com>2025-05-02 19:37:56 +0200
commita2ae171b97741ebf1f7c3e7a1ca118faa91d6662 (patch)
tree752e491ecefb5bbfc86e98925ae0e6f671dad531 /compiler/rustc_span/src
parent7c96085b64580af5c5f619384f0e3f082138ff13 (diff)
parentd9c060b88be29569e615496e20bdcf8ecdf780f8 (diff)
downloadrust-a2ae171b97741ebf1f7c3e7a1ca118faa91d6662.tar.gz
rust-a2ae171b97741ebf1f7c3e7a1ca118faa91d6662.zip
Rollup merge of #140485 - Jarcho:from_expansion_opt, r=petrochenkov
Optimize the codegen for `Span::from_expansion`

See https://godbolt.org/z/bq65Y6bc4 for the difference. the new version is less than half the number of instructions.

Also tried fully writing the function by hand:
```rust
sp.ctxt_or_parent_or_marker != 0
        && (
            sp.len_with_tag_or_marker == BASE_LEN_INTERNED_MARKER
            || sp.len_with_tag_or_marker & PARENT_TAG == 0
        )
```

But that was no better than this PR's current use of `match_span_kind`.
Diffstat (limited to 'compiler/rustc_span/src')
-rw-r--r--compiler/rustc_span/src/span_encoding.rs17
1 files changed, 15 insertions, 2 deletions
diff --git a/compiler/rustc_span/src/span_encoding.rs b/compiler/rustc_span/src/span_encoding.rs
index 9d6c7d2a42a..a4a47dc99b0 100644
--- a/compiler/rustc_span/src/span_encoding.rs
+++ b/compiler/rustc_span/src/span_encoding.rs
@@ -306,8 +306,21 @@ impl Span {
     /// Returns `true` if this span comes from any kind of macro, desugaring or inlining.
     #[inline]
     pub fn from_expansion(self) -> bool {
-        // If the span is fully inferred then ctxt > MAX_CTXT
-        self.inline_ctxt().map_or(true, |ctxt| !ctxt.is_root())
+        let ctxt = match_span_kind! {
+            self,
+            // All branches here, except `InlineParent`, actually return `span.ctxt_or_parent_or_marker`.
+            // Since `Interned` is selected if the field contains `CTXT_INTERNED_MARKER` returning that value
+            // as the context allows the compiler to optimize out the branch that selects between either
+            // `Interned` and `PartiallyInterned`.
+            //
+            // Interned contexts can never be the root context and `CTXT_INTERNED_MARKER` has a different value
+            // than the root context so this works for checking is this is an expansion.
+            InlineCtxt(span) => SyntaxContext::from_u16(span.ctxt),
+            InlineParent(_span) => SyntaxContext::root(),
+            PartiallyInterned(span) => SyntaxContext::from_u16(span.ctxt),
+            Interned(_span) => SyntaxContext::from_u16(CTXT_INTERNED_MARKER),
+        };
+        !ctxt.is_root()
     }
 
     /// Returns `true` if this is a dummy span with any hygienic context.