
Rust 1.97.1 shipped today with a single change: a fix for a P-critical LLVM miscompilation that has been silently corrupting programs since Rust 1.87 and started causing guaranteed segfaults in Rust 1.97.0. If you upgraded last week, run this before reading the rest:
rustup update stable
That is the entire remediation. One command. Now here is why this happened and what it means.
The Bug Slept Through Ten Releases
The underlying issue predates last week’s 1.97.0 release by roughly ten compiler versions. An LLVM optimization pass was attempting an unsafe transformation: converting a conditional load sequence — select cond, (load ptr_1), (load ptr_2) — into a single load with a selected pointer — load (select cond, ptr_1, ptr_2).
The problem is what happens when cond is poison rather than a concrete true or false. In the original form, a poison condition produces a poison result — that is safe and defined behavior in LLVM’s IR. In the rewritten form, a poison condition dereferencing a pointer is immediate undefined behavior. LLVM was generating the second form in cases where the first was emitted, and on x86-64 this materialized as out-of-bounds memory reads. The upstream tracking issue is LLVM #208611.
Before 1.97.0, Rust assigned enum discriminants sequentially — the None variant would be represented as one past the last used discriminant value, typically a small positive integer like 2. When the LLVM bug triggered, programs read a few bytes past where they should have. In most allocations, those bytes existed, were harmless, and the values were never actually used. Ten releases of quiet miscompilation that almost never crashed anything.
Why 1.97.0 Broke Everything
Rust 1.97.0, released July 9, changed how enum discriminants are represented. The None variant was assigned -1 instead — a reasonable optimization that reduces branching in certain codepaths. The LLVM bug, however, handled -1 very differently. It treated the signed -1 as an unsigned offset of 2,147,483,647 (2^32 – 1), sending the memory read gigabytes past the intended allocation. At that scale, you are nearly guaranteed to hit an unmapped page and segfault.
The minimal reproducer is a nested enum with differently-sized variants, an Option wrapper, and an optimized build on x86-64:
enum Inner { A(u32), B(u32) }
struct Big { _pad: u64, inner: Inner }
struct Small { a: u16, b: u16, _f: fn() }
enum Checksum { X(Big), Y(Small) }
fn main() {
let val: Option<Checksum> = None;
println!("{:?}", val.map(|_| 42)); // Segfaults on 1.97.0 with -O
}
If your codebase uses nested enums with Option and you ship release builds on x86-64, assume you were affected.
The Fix: Belt and Suspenders
The Rust team went with a two-part fix. First, they backported the LLVM upstream correction (PR #159106), which resolves the load-combining transformation at the source. Second, they reverted the specific rustc IR generation change from 1.97.0 that increased the likelihood of triggering the bug — not strictly required, but a sensible precaution while confidence in the LLVM fix builds.
The bug was filed on July 9, the same day 1.97.0 went stable. Today, July 16, Rust 1.97.1 is live. That is seven days from P-critical regression report to stable patch release. For context, most language runtimes consider thirty days a tight timeline for this class of issue. Rust’s release infrastructure earned its reputation here.
What 1.97.1 Does Not Change
No features were added or removed. The v0 symbol mangling default, Cargo warning controls, and linker output changes from 1.97.0 are all intact. If you were already using those features, they continue to work. This is a pure correctness fix with no behavior changes beyond eliminating the miscompilation.
Debug builds are not affected — the bug only manifests under optimization. That said, release builds for anything non-trivial should be considered suspect if you deployed on 1.97.0 this past week. Verify your update:
rustc --version
# rustc 1.97.1 (expected output)
For full technical details, the Rust 1.97.1 changelog and the LWN analysis are the most complete references available.













