Summary
I found this issue when I develop new lint in Clippy.
In function check_if_try_match of question_mark lint, the condition matches!(arm_body.kind, ExprKind::Block(..)) was true for destructuring assignments like (line_start, line) = x because Rust's HIR desugars them to blocks.
However, the source snippet is (line_start, line) = x (starts with (), not a real block starting with {. The subsequent sugg.insert_str(1, ...) was designed to insert after {, but instead injected code after (, producing the broken suggestion (let x = ...?;line_start, line) = x.
Reproducer
Code:
let mut a = 0i32;
let mut b = 0i32;
let opt: Option<(i32, i32)> = Some((1, 2));
match opt {
Some(x) => (a, b) = x,
None => return None,
}
Current output:
error: this `match` expression can be replaced with `?`
--> tests/ui/question_mark.rs:718:5
|
LL | / match opt {
LL | |
LL | | Some(x) => (a, b) = x,
LL | | None => return None,
LL | | }
| |_____^
|
help: try instead
|
LL ~ (
LL + let x = opt?;a, b) = x
|
Desired output:
{
let x = opt?;
(a, b) = x
}
Version
rustc 1.96.0-nightly (7e46c5f6f 2026-04-01)
binary: rustc
commit-hash: 7e46c5f6fb87f8cf4353e058479cef15d1d952b4
commit-date: 2026-04-01
host: aarch64-apple-darwin
release: 1.96.0-nightly
LLVM version: 22.1.2
Additional Labels
No response
Summary
I found this issue when I develop new lint in Clippy.
In function
check_if_try_matchofquestion_marklint, the conditionmatches!(arm_body.kind, ExprKind::Block(..))was true for destructuring assignments like(line_start, line) = xbecause Rust's HIR desugars them to blocks.However, the source snippet is
(line_start, line) = x(starts with(), not a real block starting with{. The subsequentsugg.insert_str(1, ...)was designed to insert after{, but instead injected code after(, producing the broken suggestion (let x = ...?;line_start, line) = x.Reproducer
Code:
Current output:
Desired output:
Version
Additional Labels
No response