diff --git a/clippy_lints/src/question_mark.rs b/clippy_lints/src/question_mark.rs index 4bd6b1696b35..f07cc10cbced 100644 --- a/clippy_lints/src/question_mark.rs +++ b/clippy_lints/src/question_mark.rs @@ -495,7 +495,7 @@ fn check_if_try_match<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) { let mut sugg = reindent_multiline(&arm_body_snippet, true, Some(indent)); let binding_snippet = snippet_with_applicability(cx, binding_span, "..", &mut applicability); let inner_indent = " ".repeat(indent + 4); - if matches!(arm_body.kind, ExprKind::Block(..)) { + if matches!(arm_body.kind, ExprKind::Block(..)) && sugg.starts_with('{') { sugg.insert_str( 1, &format!("\n{inner_indent}let {binding_snippet} = {scrutinee_snippet}?;"), diff --git a/tests/ui/question_mark.fixed b/tests/ui/question_mark.fixed index bf4b4ff0a21e..786431bc1f53 100644 --- a/tests/ui/question_mark.fixed +++ b/tests/ui/question_mark.fixed @@ -564,3 +564,14 @@ fn issue16751(mut v: Option) -> Option { if n > 10 { Some(42) } else { None } } } + +fn issue_destructuring_assignment() -> Option<(i32, i32)> { + let mut a = 0i32; + let mut b = 0i32; + let opt: Option<(i32, i32)> = Some((1, 2)); + { + let x = opt?; + (a, b) = x + } + Some((a, b)) +} diff --git a/tests/ui/question_mark.rs b/tests/ui/question_mark.rs index 93f76f16576c..7cbcc604eb59 100644 --- a/tests/ui/question_mark.rs +++ b/tests/ui/question_mark.rs @@ -710,3 +710,15 @@ fn issue16751(mut v: Option) -> Option { None => return None, } } + +fn issue_destructuring_assignment() -> Option<(i32, i32)> { + let mut a = 0i32; + let mut b = 0i32; + let opt: Option<(i32, i32)> = Some((1, 2)); + match opt { + //~^ question_mark + Some(x) => (a, b) = x, + None => return None, + } + Some((a, b)) +} diff --git a/tests/ui/question_mark.stderr b/tests/ui/question_mark.stderr index 9d7cfc205764..74fb2c45a254 100644 --- a/tests/ui/question_mark.stderr +++ b/tests/ui/question_mark.stderr @@ -498,5 +498,23 @@ LL + if n > 10 { Some(42) } else { None } LL + } | -error: aborting due to 46 previous errors +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?; +LL + (a, b) = x +LL + } + | + +error: aborting due to 47 previous errors