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).
This commit is contained in:
Alan Egerton 2026-02-04 12:35:34 +00:00
parent 794495e2b4
commit 58292e2a53
No known key found for this signature in database
GPG key ID: 3D7EA7527916B438
2 changed files with 22 additions and 0 deletions

View file

@ -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.

View file

@ -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: FnOnce()>(f: F) {
if let Ok(true) = std::fs::exists("may_or_may_not_call_f") {
_ = std::panic::catch_unwind(std::panic::AssertUnwindSafe(f));
}
}