From b434b157d99953ac4d740962b00e3f1269a03f77 Mon Sep 17 00:00:00 2001 From: durationextender Date: Thu, 16 Jul 2026 02:23:03 +0200 Subject: [PATCH] fix(needless_return_with_question_mark): skip when removing return causes a partial move error --- .../needless_return_with_question_mark.rs | 19 +++++++++++++++++-- .../needless_return_with_question_mark.fixed | 11 ++++++++++- .../ui/needless_return_with_question_mark.rs | 11 ++++++++++- .../needless_return_with_question_mark.stderr | 6 +++--- 4 files changed, 40 insertions(+), 7 deletions(-) diff --git a/clippy_lints/src/returns/needless_return_with_question_mark.rs b/clippy_lints/src/returns/needless_return_with_question_mark.rs index e37ea9800ed0..6954cf5d48c2 100644 --- a/clippy_lints/src/returns/needless_return_with_question_mark.rs +++ b/clippy_lints/src/returns/needless_return_with_question_mark.rs @@ -1,6 +1,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::res::{MaybeDef, MaybeQPath}; -use clippy_utils::{is_from_proc_macro, is_inside_let_else}; +use clippy_utils::res::{MaybeDef, MaybeQPath, MaybeResPath}; +use clippy_utils::usage::local_used_after_expr; +use clippy_utils::{higher, is_from_proc_macro, is_inside_let_else}; use rustc_errors::Applicability; use rustc_hir::LangItem::ResultErr; use rustc_hir::{Expr, ExprKind, HirId, MatchSource, Node, Stmt, StmtKind}; @@ -31,6 +32,20 @@ pub(super) fn check_stmt<'tcx>(cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) { && !is_from_proc_macro(cx, expr) && !stmt_needs_never_type(cx, stmt.hir_id) { + // get the hir id of parent of return statement + for (_hir_id, node) in cx.tcx.hir_parent_iter(expr.hir_id) { + if let Node::Expr(parent_expr) = node { + if let Some(if_let) = higher::IfLet::hir(cx, parent_expr) { + let scrutinee = if_let.let_expr; + if let Some(local_id) = scrutinee.res_local_id() + && local_used_after_expr(cx, local_id, parent_expr) + { + return; + } + } + } + } + span_lint_and_sugg( cx, NEEDLESS_RETURN_WITH_QUESTION_MARK, diff --git a/tests/ui/needless_return_with_question_mark.fixed b/tests/ui/needless_return_with_question_mark.fixed index bd6c7a18722e..aab093f52bba 100644 --- a/tests/ui/needless_return_with_question_mark.fixed +++ b/tests/ui/needless_return_with_question_mark.fixed @@ -117,7 +117,16 @@ fn issue11982_no_conversion() { Ok(()) } } - +#[allow(clippy::unnecessary_literal_unwrap)] +fn issue17421_no_lint_partial_move_after_if_let() -> Result<(), String> { + let v: Result = Err("".to_string()); + if let Err(e) = v { + return Err(e)?; + } + let v = v.unwrap(); + println!("{}", v); + Ok(()) +} fn general_return() { fn foo(ok: bool) -> Result<(), ()> { let bar = Result::Ok(Result::<(), ()>::Ok(())); diff --git a/tests/ui/needless_return_with_question_mark.rs b/tests/ui/needless_return_with_question_mark.rs index a92dd92ab0bc..2dff65270bd3 100644 --- a/tests/ui/needless_return_with_question_mark.rs +++ b/tests/ui/needless_return_with_question_mark.rs @@ -117,7 +117,16 @@ fn issue11982_no_conversion() { Ok(()) } } - +#[allow(clippy::unnecessary_literal_unwrap)] +fn issue17421_no_lint_partial_move_after_if_let() -> Result<(), String> { + let v: Result = Err("".to_string()); + if let Err(e) = v { + return Err(e)?; + } + let v = v.unwrap(); + println!("{}", v); + Ok(()) +} fn general_return() { fn foo(ok: bool) -> Result<(), ()> { let bar = Result::Ok(Result::<(), ()>::Ok(())); diff --git a/tests/ui/needless_return_with_question_mark.stderr b/tests/ui/needless_return_with_question_mark.stderr index 5aec5ec00b61..78665f10e25e 100644 --- a/tests/ui/needless_return_with_question_mark.stderr +++ b/tests/ui/needless_return_with_question_mark.stderr @@ -14,19 +14,19 @@ LL | return Err(())?; | ^^^^^^^ help: remove it error: unneeded `return` statement with `?` operator - --> tests/ui/needless_return_with_question_mark.rs:133:9 + --> tests/ui/needless_return_with_question_mark.rs:142:9 | LL | return Err(())?; | ^^^^^^^ help: remove it error: unneeded `return` statement with `?` operator - --> tests/ui/needless_return_with_question_mark.rs:142:13 + --> tests/ui/needless_return_with_question_mark.rs:151:13 | LL | return Err(())?; | ^^^^^^^ help: remove it error: unneeded `return` statement with `?` operator - --> tests/ui/needless_return_with_question_mark.rs:162:5 + --> tests/ui/needless_return_with_question_mark.rs:171:5 | LL | return Err(())?; | ^^^^^^^ help: remove it