From 58292e2a531a42bdf0ffe3ef594caa42baba5140 Mon Sep 17 00:00:00 2001 From: Alan Egerton Date: Wed, 4 Feb 2026 12:35:34 +0000 Subject: [PATCH] Consider captures to be used by closures that unwind Assignments to a captured variable within a diverging closure should not be considered unused if the divergence is caught. This patch considers such assignments/captures to be used by diverging closures irrespective of whether the divergence is caught, but better a false negative unused lint than a false positive one (the latter having caused a stable-to-stable regression). --- compiler/rustc_mir_transform/src/liveness.rs | 1 + tests/ui/lint/unused/diverging-path.rs | 21 ++++++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 tests/ui/lint/unused/diverging-path.rs diff --git a/compiler/rustc_mir_transform/src/liveness.rs b/compiler/rustc_mir_transform/src/liveness.rs index 9bafee9f31c39..9d951f0874376 100644 --- a/compiler/rustc_mir_transform/src/liveness.rs +++ b/compiler/rustc_mir_transform/src/liveness.rs @@ -1291,6 +1291,7 @@ impl<'tcx> Visitor<'tcx> for TransferFunction<'_, 'tcx> { TerminatorKind::Return | TerminatorKind::Yield { .. } | TerminatorKind::Goto { target: START_BLOCK } // Inserted for the `FnMut` case. + | TerminatorKind::Call { target: None, .. } // unwinding could be caught if self.capture_kind != CaptureKind::None => { // All indirect captures have an effect on the environment, so we mark them as live. diff --git a/tests/ui/lint/unused/diverging-path.rs b/tests/ui/lint/unused/diverging-path.rs new file mode 100644 index 0000000000000..7f364518fe976 --- /dev/null +++ b/tests/ui/lint/unused/diverging-path.rs @@ -0,0 +1,21 @@ +//! Assignments to a captured variable within a diverging closure should not be considered unused if +//! the divergence is caught. +//! +//! Regression test for https://github.com/rust-lang/rust/issues/152079 +//@ compile-flags: -Wunused +//@ check-pass + +fn main() { + let mut x = 1; + catch(|| { + x = 2; + panic!(); + }); + dbg!(x); +} + +fn catch(f: F) { + if let Ok(true) = std::fs::exists("may_or_may_not_call_f") { + _ = std::panic::catch_unwind(std::panic::AssertUnwindSafe(f)); + } +}