Skip to content

question_mark: wrong suggestion when match arm body is a destructuring assignment #16862

@charlieHsiuC

Description

@charlieHsiuC

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

Metadata

Metadata

Assignees

Labels

C-bugCategory: Clippy is not doing the correct thing

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions