Skip to content

Build Not yet confirmed elsewhere1 publisher 2 min read Published

Rust's borrow checker lets a stack reference slip past a 'static bound on stable

Rust issue #164250 reports a borrow-checker unsoundness that reproduces on stable, with variants compiling since 1.18.0 in 2017. Exploiting it takes a deliberately hostile Drop impl, and the team downgraded it from P-critical to P-high.

The Engineer · Build desk

How we use AI Send a correction

What happened

  • jsnell filed the issue on October 13 with a reproduction that compiles and prints freed memory.
  • In the reproduction, assigning a stack-local reference into a field after construction unifies the types covariantly, and the T: 'static bound is never re-checked.
  • A Drop impl that assumes the bound held pushes the value into a static list, and a later downcast_ref reads freed stack memory.
  • Commenter maxdexh contributed a version of the unsoundness that goes back to Rust 1.4.
  • A fix is in motion as PR #164277, and lcnr linked the issue to the next-gen trait solver and Project Zero rework.

Why it matters

  • constraint The trigger is wider than a field assignment. maxdexh showed mem::swap reaches the same gap, so a search for post-construction assignments will miss variants.
  • exposure A hostile Drop impl in any dependency is enough to reach the bug, so the exposure sits in the dependency tree for anyone who treats a clean compile as the safety check.
  • decision Teams that compile untrusted crates have to choose between waiting for PR #164277 to land and auditing now for Drop impls that stash generic values in statics.

For code to be hit, it needs three things: a type with a T: 'static bound, a way for a shorter-lived reference to get into that type, and a Drop impl that relies on the bound [4][5]. The reproduction supplies all three.

The post's author ran it on the official playground, stable channel, and got the line "read after scope: hello world, this is long enough", with the same result on nightly [3]. The stack slot had already been freed. Per the issue, the same program under AddressSanitizer crashes with stack-use-after-scope [6].

Everything here comes through one dev.to post that relays the thread. The downgrade rests on age. According to the post, lcnr's pinned note says the issue would have been P-critical regardless of whether anyone hit it in the wild, and it is P-high because it sat latent for eleven years [8]. The note's own words, as the post quotes them, are "very likely that this unsoundness has not caused memory unsafety by accident" [9].

The post frames the result as a floor under the proof: borrow check, then variance rules, then trait bounds, then an unexecuted assumption that Drop impls respect the bounds they inherit [19]. We'd put it differently. maxdexh described the general case as "unification just generally doesn't check lifetime bounds of the type" [16]. That is a checker defect. A Drop impl that trusts T: 'static is relying on what the bound promises [5], and in our view the fix belongs in the checker.

The thread had friction of its own. theemathas asked "How on earth was this not found before this???" [13]. The issue was briefly locked as too heated, then unlocked and re-locked to collaborators [18].

What to watch

  • PR #164277 merging, and which stable release carries it.
  • Whether the next-gen trait solver work lcnr linked to changes the P-high label.
  • Any report of the bug firing in real code without a hostile Drop impl, which would undercut the pinned note's reasoning that it has not happened by accident.

Clarity's read

What the record supports and how the coverage leans. The claims behind it follow.

Reality

Evidence68
Adoption
Insufficient
Hype gap−10
Incentives
Insufficient
Confidence65
Why these scores

Claim ledger

Ranked by verification strength, evidence, and original report placement.

  1. [1]

    Issue #164250 on the rust-lang tracker reports an unsoundness in the borrow checker that reproduces on current stable.

    Reported Supported Source: dev.to post by slabb, relaying rust-lang issue #164250View cited source
  2. [2]

    Variants of the unsoundness have compiled since Rust 1.18.0 (2017).

    Reported Supported Source: dev.to post by slabb, relaying the issue threadView cited source
  3. [3]

    The post's author ran the reproduction on the official playground, stable channel, and it printed 'read after scope: hello world, this is long enough' after the stack slot was freed; the result was the same on nightly.

    Reported Supported Source: dev.to post author's own playground runView cited source

Get this ledger inside ChatGPT. Ask about any of our stories and the answer brings its figure, each claim’s verdict and the sources. Free, no account.

Add to ChatGPTAdd to Claude

Sources

1 independent publisher whose own reporting we read for this story.

  1. dev.to

    1 article · October 14, 2026

    The 11-year-old premise inside Rust's memory-safety proof

Share your take

Let Clarity write the post for you.

Signed-in readers get a short post drafted on this story in the register they choose — narrative, analytical, or a direct position — editable to the last word before it goes anywhere. The share buttons at the top of this story work without an account.

Topics and entities

Follow any of these and your For You feed starts watching them — no settings page required.

Topics

Entities

Loading related stories