Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions RELEASES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
Version 1.97.1 (2026-07-16)
==========================

<a id="1.97.1"></a>

- [rustc: Fix miscompilation in LLVM optimization](https://github.com/rust-lang/rust/issues/159035)
This backports an LLVM submodule bump to include the LLVM-side fix and a
revert of the rustc change that is one known trigger for the bug. The rustc
side revert should not be strictly necessary but is done out of abundance of caution.

Version 1.97.0 (2026-07-09)
==========================

Expand Down Expand Up @@ -35,14 +45,14 @@ Stabilized APIs
- [`Send for std::fs::File` on UEFI](https://github.com/rust-lang/rust/pull/154003)
- [`<{integer}>::isolate_highest_one`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.isolate_highest_one)
- [`<{integer}>::isolate_lowest_one`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.isolate_lowest_one)
- [`<{integer}>::highest_one`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.highest_one)
- [`<{integer}>::lowest_one`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.lowest_one)
- [`<{integer}>::bit_width`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.bit_width)
- [`NonZero<{integer}>::isolate_highest_one`](https://doc.rust-lang.org/stable/std/num/struct.NonZero.html#method.isolate_highest_one)
- [`NonZero<{integer}>::isolate_lowest_one`](https://doc.rust-lang.org/stable/std/num/struct.NonZero.html#method.isolate_lowest_one)
- [`<{integer}>::bit_width`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.bit_width)
- [`<{integer}>::lowest_one`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.lowest_one)
- [`<{integer}>::highest_one`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.highest_one)
- [`NonZero<{integer}>::bit_width`](https://doc.rust-lang.org/stable/std/num/struct.NonZero.html#method.bit_width)
- [`NonZero<{integer}>::highest_one`](https://doc.rust-lang.org/stable/std/num/struct.NonZero.html#method.highest_one)
- [`NonZero<{integer}>::lowest_one`](https://doc.rust-lang.org/stable/std/num/struct.NonZero.html#method.lowest_one)
- [`NonZero<{integer}>::bit_width`](https://doc.rust-lang.org/stable/std/num/struct.NonZero.html#method.bit_width)


These previously stable APIs are now stable in const contexts:
Expand All @@ -66,6 +76,8 @@ Rustdoc
-----
- [Stabilize `--emit` flag](https://github.com/rust-lang/rust/pull/146220)
- [Stabilize `--remap-path-prefix`](https://github.com/rust-lang/rust/pull/155307)


<a id="1.97.0-Compatibility-Notes"></a>

Compatibility Notes
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_abi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2063,8 +2063,7 @@ impl Niche {
let distance_end_zero = max_value - v.end;
// FIXME: this ought to work for `bool` too, but that seems to be hitting a miscompilation
// <https://github.com/rust-lang/rust/pull/155473#issuecomment-4302036343>
let is_bool = size.bytes() == 1 && v == WrappingRange { start: 0, end: 1 };
if count == 1 && !is_bool {
if count == 1 && v != (WrappingRange { start: 0, end: 1 }) {
// We only need one, so just pick the one closest to zero.
// Not only does that obviously use zero if it's possible, but it also
// simplifies testing things like `Option<char>`, since looking for `-1`
Expand Down
2 changes: 1 addition & 1 deletion src/version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.97.0
1.97.1
2 changes: 1 addition & 1 deletion tests/codegen-llvm/function-arguments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ pub fn return_slice(x: &[u16]) -> &[u16] {
x
}

// CHECK: { i16, i16 } @enum_id_1(i16 noundef{{( range\(i16 -1, 2\))?}} %x.0, i16 %x.1)
// CHECK: { i16, i16 } @enum_id_1(i16 noundef{{( range\(i16 0, 3\))?}} %x.0, i16 %x.1)
#[no_mangle]
pub fn enum_id_1(x: Option<Result<u16, u16>>) -> Option<Result<u16, u16>> {
x
Expand Down
43 changes: 43 additions & 0 deletions tests/ui/codegen/dont-miscompile-enums.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//@ run-pass

// Bad regression test for https://github.com/rust-lang/rust/issues/159035
// This should probably be replaced with a codegen test, though that might need to be in LLVM,
// as it seems that the miscompilation may occur on correct IR misoptimized by SimplifyCFG.

#![allow(dead_code)]

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),
}
impl Checksum {
fn finalize(self) -> u32 {
match self {
Checksum::X(h) => match h.inner {
Inner::A(s) => s,
Inner::B(s) => s,
},
Checksum::Y(s) => (u32::from(s.b) << 16) | u32::from(s.a),
}
}
}
#[inline(never)]
fn run(c: Option<Checksum>) -> Option<u32> {
c.map(|c| c.finalize())
}
fn main() {
println!("{:?}", run(std::hint::black_box(None)));
}
Loading