From 9580d74fade5e7bee2d35a5d53d4ee61f29a3623 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 23 Jun 2026 19:08:22 -0400 Subject: [PATCH 1/7] Backport timeout and retry behavior fixes This includes: * Cargo 17133: [stable] Bump patch version to 0.97.2 * Cargo 17131: [1.96] backport: Add global HTTP timeout tracking to http_async * Cargo 17046: [1.96] Bump cargo-util-schemas to 0.14.0 and cargo to 0.97.1 * Cargo 17134: [stable 1.96 backport] Backport portable-atomics to 1.96 branch --- src/tools/cargo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/cargo b/src/tools/cargo index 30a34c6821b57..d71ac4c8b4e10 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 30a34c6821b57de0aaec83a901aca39f88f6778c +Subproject commit d71ac4c8b4e106d035148bf1d34f316b2beaa3e9 From 120dec0a74653f28e440ec9fca86122284734efe Mon Sep 17 00:00:00 2001 From: Hanna Kruppe Date: Sun, 21 Jun 2026 15:07:54 +0200 Subject: [PATCH 2/7] add test case for miscompilation --- ...comparison.SimplifyComparisonIntegral.diff | 28 +++++++++++++++++++ tests/mir-opt/if_condition_int.rs | 27 ++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 tests/mir-opt/if_condition_int.dont_remove_moved_comparison.SimplifyComparisonIntegral.diff diff --git a/tests/mir-opt/if_condition_int.dont_remove_moved_comparison.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.dont_remove_moved_comparison.SimplifyComparisonIntegral.diff new file mode 100644 index 0000000000000..b3d38516dec0e --- /dev/null +++ b/tests/mir-opt/if_condition_int.dont_remove_moved_comparison.SimplifyComparisonIntegral.diff @@ -0,0 +1,28 @@ +- // 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); ++ nop; + _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; + } + } + diff --git a/tests/mir-opt/if_condition_int.rs b/tests/mir-opt/if_condition_int.rs index 5e0961da3ccea..6950faf502005 100644 --- a/tests/mir-opt/if_condition_int.rs +++ b/tests/mir-opt/if_condition_int.rs @@ -103,6 +103,33 @@ fn dont_remove_comparison(a: i8) -> i32 { } } +// EMIT_MIR if_condition_int.dont_remove_moved_comparison.SimplifyComparisonIntegral.diff +#[custom_mir(dialect = "runtime")] +fn dont_remove_moved_comparison(a: i8) -> 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 { From 81fb5b5053e44b64027cb0b3466e0ec1303a1557 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 23 Jun 2026 19:15:45 -0400 Subject: [PATCH 3/7] Prepare release notes --- RELEASES.md | 8 ++++++++ src/version | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/RELEASES.md b/RELEASES.md index 433e01088ed28..62139197f73f7 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,11 @@ +Version 1.96.1 (2026-06-25) +=========================== + + + +- [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) + Version 1.96.0 (2026-05-28) ========================== diff --git a/src/version b/src/version index 9141007a55821..024f4b4caab94 100644 --- a/src/version +++ b/src/version @@ -1 +1 @@ -1.96.0 +1.96.1 From 483648aff67efe84f5fbc6c00261605174869811 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 23 Jun 2026 22:00:05 -0400 Subject: [PATCH 4/7] don't try to remove assignments in SimplifyComparisonIntegral --- .../src/simplify_comparison_integral.rs | 46 ++++++++----------- ...comparison.SimplifyComparisonIntegral.diff | 3 +- ...t.opt_char.SimplifyComparisonIntegral.diff | 3 +- ...int.opt_i8.SimplifyComparisonIntegral.diff | 3 +- ...ltiple_ifs.SimplifyComparisonIntegral.diff | 6 +-- ...t_negative.SimplifyComparisonIntegral.diff | 3 +- ...nt.opt_u32.SimplifyComparisonIntegral.diff | 3 +- tests/mir-opt/if_condition_int.rs | 11 ++++- 8 files changed, 35 insertions(+), 43 deletions(-) diff --git a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs index 58b5e45672a2f..53ba77b01c9d4 100644 --- a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs +++ b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs @@ -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. - - // 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); - } - _ => (), + // 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(); + + 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 diff --git a/tests/mir-opt/if_condition_int.dont_remove_moved_comparison.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.dont_remove_moved_comparison.SimplifyComparisonIntegral.diff index b3d38516dec0e..e59e2fde016d2 100644 --- a/tests/mir-opt/if_condition_int.dont_remove_moved_comparison.SimplifyComparisonIntegral.diff +++ b/tests/mir-opt/if_condition_int.dont_remove_moved_comparison.SimplifyComparisonIntegral.diff @@ -8,8 +8,7 @@ let mut _4: i32; bb0: { -- _2 = Eq(copy _1, const 17_i8); -+ nop; + _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]; diff --git a/tests/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff index 22f6443a6c0f9..58c95e20975ee 100644 --- a/tests/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff +++ b/tests/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff @@ -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]; } diff --git a/tests/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff index d5c48fd04ca60..23dc079de01a0 100644 --- a/tests/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff +++ b/tests/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff @@ -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]; } diff --git a/tests/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff index 84d62b8136078..5baf481616186 100644 --- a/tests/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff +++ b/tests/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff @@ -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]; } diff --git a/tests/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff index a1cbaff796b35..79c3525663c89 100644 --- a/tests/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff +++ b/tests/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff @@ -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]; } diff --git a/tests/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff index 8101de8cbf381..3e950f053bc35 100644 --- a/tests/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff +++ b/tests/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff @@ -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]; } diff --git a/tests/mir-opt/if_condition_int.rs b/tests/mir-opt/if_condition_int.rs index 6950faf502005..6eed1191ffc57 100644 --- a/tests/mir-opt/if_condition_int.rs +++ b/tests/mir-opt/if_condition_int.rs @@ -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); @@ -104,8 +104,17 @@ 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; From d493521c8b86e6fa4c1cba7161f974b267000ba3 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Fri, 26 Jun 2026 14:42:51 -0400 Subject: [PATCH 5/7] Patch the vendored libssh2 for security fixes This includes: * Cargo 17140: [stable 1.96.0] Patch libssh2-sys - CVE-2025-15661: sftp_symlink out of bounds read on malformed packet - CVE-2026-55199: check _libssh2_get_string() return in EXT_INFO handler - CVE-2026-55200: bounds check for packet_length in REQUIRES_FULL_PACKET path --- src/tools/cargo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/cargo b/src/tools/cargo index d71ac4c8b4e10..356927216a2d7 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit d71ac4c8b4e106d035148bf1d34f316b2beaa3e9 +Subproject commit 356927216a2d746168cf76e5e88cc3f4b58e029d From ebbfeb3b066758e53cc2e4df3387a2aaac80363e Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Fri, 26 Jun 2026 14:42:52 -0400 Subject: [PATCH 6/7] Prepare release notes --- RELEASES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/RELEASES.md b/RELEASES.md index 62139197f73f7..e6b2e35e343d4 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -4,6 +4,7 @@ Version 1.96.1 (2026-06-25) - [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 unsoundness in MIR opt](https://github.com/rust-lang/rust/pull/158214) Version 1.96.0 (2026-05-28) From a4d95c653337497b305f5166d2cb172589cf30c4 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Fri, 26 Jun 2026 15:13:09 -0400 Subject: [PATCH 7/7] adjust release notes to reflect comments Co-authored-by: Mark Rousskov --- RELEASES.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index e6b2e35e343d4..a7c60f1bbe27d 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,11 +1,11 @@ -Version 1.96.1 (2026-06-25) +Version 1.96.1 (2026-06-30) =========================== - [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 unsoundness in MIR opt](https://github.com/rust-lang/rust/pull/158214) +- [rustc: fix miscompilation in MIR optimization](https://github.com/rust-lang/rust/pull/158214) Version 1.96.0 (2026-05-28) ==========================