Auto merge of #158331 - Mark-Simulacrum:stable-patch, r=Mark-Simulacrum

[stable] 1.96.1 release



This prepares 1.96.1 release with:

- [Cargo: fix timeout/retry behavior](https://github.com/rust-lang/cargo/pull/17131)
- [rustc: fix unsoundness in MIR opt](https://github.com/rust-lang/rust/pull/158214)

Currently targeting this Thursday.

r? me
This commit is contained in:
bors
2026-06-26 21:46:14 +00:00
11 changed files with 97 additions and 41 deletions
+9
View File
@@ -1,3 +1,12 @@
Version 1.96.1 (2026-06-30)
===========================
<a id="1.96.1"></a>
- [Cargo: fix timeout/retry behavior](https://github.com/rust-lang/cargo/pull/17131)
- [Cargo: apply patches for CVE-2025-15661, CVE-2026-55199, and CVE-2026-55200 to libssh2](https://github.com/rust-lang/cargo/pull/17140)
- [rustc: fix miscompilation in MIR optimization](https://github.com/rust-lang/rust/pull/158214)
Version 1.96.0 (2026-05-28)
==========================
@@ -76,30 +76,24 @@ impl<'tcx> crate::MirPass<'tcx> for SimplifyComparisonIntegral {
_ => unreachable!(),
}
// delete comparison statement if it the value being switched on was moved, which means
// it can not be used later on
if opt.can_remove_bin_op_stmt {
bb.statements[opt.bin_op_stmt_idx].make_nop(true);
} else {
// if the integer being compared to a const integral is being moved into the
// comparison, e.g `_2 = Eq(move _3, const 'x');`
// we want to avoid making a double move later on in the switchInt on _3.
// So to avoid `switchInt(move _3) -> ['x': bb2, otherwise: bb1];`,
// we convert the move in the comparison statement to a copy.
// if the integer being compared to a const integral is being moved into the
// comparison, e.g `_2 = Eq(move _3, const 'x');`
// we want to avoid making a double move later on in the switchInt on _3.
// So to avoid `switchInt(move _3) -> ['x': bb2, otherwise: bb1];`,
// we convert the move in the comparison statement to a copy.
// unwrap is safe as we know this statement is an assign
let (_, rhs) = bb.statements[opt.bin_op_stmt_idx].kind.as_assign_mut().unwrap();
// unwrap is safe as we know this statement is an assign
let (_, rhs) = bb.statements[opt.bin_op_stmt_idx].kind.as_assign_mut().unwrap();
use Operand::*;
match rhs {
Rvalue::BinaryOp(_, box (left @ Move(_), Constant(_))) => {
*left = Copy(opt.to_switch_on);
}
Rvalue::BinaryOp(_, box (Constant(_), right @ Move(_))) => {
*right = Copy(opt.to_switch_on);
}
_ => (),
use Operand::*;
match rhs {
Rvalue::BinaryOp(_, box (left @ Move(_), Constant(_))) => {
*left = Copy(opt.to_switch_on);
}
Rvalue::BinaryOp(_, box (Constant(_), right @ Move(_))) => {
*right = Copy(opt.to_switch_on);
}
_ => (),
}
let terminator = bb.terminator();
@@ -187,7 +181,6 @@ impl<'tcx> OptimizationFinder<'_, 'tcx> {
Some(OptimizationInfo {
bin_op_stmt_idx: stmt_idx,
bb_idx,
can_remove_bin_op_stmt: discr.is_move(),
to_switch_on,
branch_value_scalar,
branch_value_ty,
@@ -238,11 +231,8 @@ fn find_branch_value_info<'tcx>(
struct OptimizationInfo<'tcx> {
/// Basic block to apply the optimization
bb_idx: BasicBlock,
/// Statement index of Eq/Ne assignment that can be removed. None if the assignment can not be
/// removed - i.e the statement is used later on
/// Statement index of Eq/Ne assignment
bin_op_stmt_idx: usize,
/// Can remove Eq/Ne assignment
can_remove_bin_op_stmt: bool,
/// Place that needs to be switched on. This place is of type integral
to_switch_on: Place<'tcx>,
/// Constant to use in switch target value
+1 -1
View File
@@ -1 +1 @@
1.96.0
1.96.1
@@ -0,0 +1,27 @@
- // MIR for `dont_remove_moved_comparison` before SimplifyComparisonIntegral
+ // MIR for `dont_remove_moved_comparison` after SimplifyComparisonIntegral
fn dont_remove_moved_comparison(_1: i8) -> i32 {
let mut _0: i32;
let mut _2: bool;
let mut _3: i32;
let mut _4: i32;
bb0: {
_2 = Eq(copy _1, const 17_i8);
_3 = copy _2 as i32 (IntToInt);
- switchInt(move _2) -> [1: bb1, otherwise: bb2];
+ switchInt(copy _1) -> [17: bb1, otherwise: bb2];
}
bb1: {
_0 = copy _3;
return;
}
bb2: {
_0 = Add(copy _3, const 1_i32);
return;
}
}
@@ -11,9 +11,8 @@
StorageLive(_2);
StorageLive(_3);
_3 = copy _1;
- _2 = Eq(copy _1, const 'x');
_2 = Eq(copy _1, const 'x');
- switchInt(move _2) -> [0: bb2, otherwise: bb1];
+ nop;
+ switchInt(copy _1) -> [120: bb1, otherwise: bb2];
}
@@ -11,9 +11,8 @@
StorageLive(_2);
StorageLive(_3);
_3 = copy _1;
- _2 = Eq(copy _1, const 42_i8);
_2 = Eq(copy _1, const 42_i8);
- switchInt(move _2) -> [0: bb2, otherwise: bb1];
+ nop;
+ switchInt(copy _1) -> [42: bb1, otherwise: bb2];
}
@@ -13,9 +13,8 @@
StorageLive(_2);
StorageLive(_3);
_3 = copy _1;
- _2 = Eq(copy _1, const 42_u32);
_2 = Eq(copy _1, const 42_u32);
- switchInt(move _2) -> [0: bb2, otherwise: bb1];
+ nop;
+ switchInt(copy _1) -> [42: bb1, otherwise: bb2];
}
@@ -30,9 +29,8 @@
StorageLive(_4);
StorageLive(_5);
_5 = copy _1;
- _4 = Ne(copy _1, const 21_u32);
_4 = Ne(copy _1, const 21_u32);
- switchInt(move _4) -> [0: bb4, otherwise: bb3];
+ nop;
+ switchInt(copy _1) -> [21: bb4, otherwise: bb3];
}
@@ -11,9 +11,8 @@
StorageLive(_2);
StorageLive(_3);
_3 = copy _1;
- _2 = Eq(copy _1, const -42_i32);
_2 = Eq(copy _1, const -42_i32);
- switchInt(move _2) -> [0: bb2, otherwise: bb1];
+ nop;
+ switchInt(copy _1) -> [4294967254: bb1, otherwise: bb2];
}
@@ -11,9 +11,8 @@
StorageLive(_2);
StorageLive(_3);
_3 = copy _1;
- _2 = Eq(copy _1, const 42_u32);
_2 = Eq(copy _1, const 42_u32);
- switchInt(move _2) -> [0: bb2, otherwise: bb1];
+ nop;
+ switchInt(copy _1) -> [42: bb1, otherwise: bb2];
}
+37 -1
View File
@@ -85,7 +85,7 @@ fn opt_multiple_ifs(x: u32) -> u32 {
}
// EMIT_MIR if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff
// test that we optimize, but do not remove the b statement, as that is used later on
// the switchInt can be optimized but the b statement can't be removed as it's used later on
fn dont_remove_comparison(a: i8) -> i32 {
// CHECK-LABEL: fn dont_remove_comparison(
// CHECK: [[b:_.*]] = Eq(copy _1, const 17_i8);
@@ -103,6 +103,42 @@ fn dont_remove_comparison(a: i8) -> i32 {
}
}
// EMIT_MIR if_condition_int.dont_remove_moved_comparison.SimplifyComparisonIntegral.diff
// like dont_remove_comparison above, but with switchInt(move _N) - regression test for #158206
#[custom_mir(dialect = "runtime")]
fn dont_remove_moved_comparison(a: i8) -> i32 {
// CHECK-LABEL: fn dont_remove_moved_comparison(
// CHECK: [[b:_.*]] = Eq(copy _1, const 17_i8);
// CHECK: [[cast:_.*]] = copy [[b]] as i32 (IntToInt);
// CHECK: switchInt(copy _1) -> [17: [[BB1:bb.*]], otherwise: [[BB2:bb.*]]];
// CHECK: [[BB1]]:
// CHECK: _0 = copy [[cast]];
// CHECK: [[BB2]]:
// CHECK: _0 = Add(copy [[cast]], const 1_i32);
mir! {
let b: bool;
let c: i32;
let d: i32;
{
b = a == 17;
c = b as i32;
match Move(b) {
true => bb1,
_ => bb2,
}
}
bb1 = {
RET = c;
Return()
}
bb2 = {
RET = c + 1;
Return()
}
}
}
// EMIT_MIR if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff
// test that we do not optimize on floats
fn dont_opt_floats(a: f32) -> i32 {