What it does
If the scrutinee of a match, if let, or while let statement is a block containing an expression without any statements, then warn unless the edition is 2024 or newer.
Advantage
As of the 2024 edition, wrapping the scrutinee in a block will ensure that temporaries created in the expression are dropped before the body executes. However, prior to the 2024 edition, this was not the case.
Drawbacks
None. If the block only contains a tail expression (no statements), then removing the block never changes behavior prior to the 2024 edition.
- If the user meant to drop the temporaries, they have to change the code.
- If the user did not mean to drop the temporaries, then removing the block makes the code less confusing without changing behavior.
Example
This code will deadlock:
if let Some(x) = self.inner.lock().unwrap().my_function() {
self.inner.lock(); // <-- deadlocks on all editions
}
Someone might attempt to fix the above deadlock like this:
// OK on 2024 edition
// Should emit warning on 2021 edition.
if let Some(x) = { self.inner.lock().unwrap().my_function() } {
self.inner.lock(); // <-- deadlocks on 2021 edition, but not on 2024 edition
}
However this fix only works due to a change to the lifetime of temporaries in the tail expression of blocks, so if the code is using the 2021 edition, then the fix does not work. The code must instead be written like this:
let value = self.inner.lock().unwrap().my_function();
if let Some(x) = value {
self.inner.lock(); // <-- no deadlock
}
Comparison with existing lints
Although it's currently missing (see this bug: rust-lang/rust#155010), there is supposed to be an edition migration lint that would catch this. But I think we should have a version of this lint that is not an edition migration lint, as it catches real bugs and has no false positives.
Additional Context
This would have caught a real bug in the Rust Binder driver. See the fix here.
What it does
If the scrutinee of a match, if let, or while let statement is a block containing an expression without any statements, then warn unless the edition is 2024 or newer.
Advantage
As of the 2024 edition, wrapping the scrutinee in a block will ensure that temporaries created in the expression are dropped before the body executes. However, prior to the 2024 edition, this was not the case.
Drawbacks
None. If the block only contains a tail expression (no statements), then removing the block never changes behavior prior to the 2024 edition.
Example
This code will deadlock:
Someone might attempt to fix the above deadlock like this:
However this fix only works due to a change to the lifetime of temporaries in the tail expression of blocks, so if the code is using the 2021 edition, then the fix does not work. The code must instead be written like this:
Comparison with existing lints
Although it's currently missing (see this bug: rust-lang/rust#155010), there is supposed to be an edition migration lint that would catch this. But I think we should have a version of this lint that is not an edition migration lint, as it catches real bugs and has no false positives.
Additional Context
This would have caught a real bug in the Rust Binder driver. See the fix here.