From 6159c1971fba705963377f1a90824f0269fa8682 Mon Sep 17 00:00:00 2001 From: irelaxcn Date: Tue, 9 Dec 2025 21:37:53 +0800 Subject: [PATCH] Fix `if_then_some_else_none` FP when the `then` block contains `.await` --- clippy_lints/src/if_then_some_else_none.rs | 16 ++++++++++++---- tests/ui/if_then_some_else_none.fixed | 10 ++++++++++ tests/ui/if_then_some_else_none.rs | 10 ++++++++++ 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/clippy_lints/src/if_then_some_else_none.rs b/clippy_lints/src/if_then_some_else_none.rs index 7f3ef58c93d1..314c8e1dd54c 100644 --- a/clippy_lints/src/if_then_some_else_none.rs +++ b/clippy_lints/src/if_then_some_else_none.rs @@ -4,10 +4,12 @@ use clippy_utils::eager_or_lazy::switch_to_eager_eval; use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::{snippet_with_applicability, snippet_with_context, walk_span_to_context}; use clippy_utils::sugg::Sugg; +use clippy_utils::visitors::for_each_expr_without_closures; use clippy_utils::{ - as_some_expr, contains_return, expr_adjustment_requires_coercion, higher, is_else_clause, is_in_const_context, - is_none_expr, peel_blocks, sym, + as_some_expr, expr_adjustment_requires_coercion, higher, is_else_clause, is_in_const_context, is_none_expr, + peel_blocks, sym, }; +use core::ops::ControlFlow; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; @@ -76,8 +78,14 @@ impl<'tcx> LateLintPass<'tcx> for IfThenSomeElseNone { && !is_else_clause(cx.tcx, expr) && !is_in_const_context(cx) && self.msrv.meets(cx, msrvs::BOOL_THEN) - && !contains_return(then_block.stmts) - && then_block.expr.is_none_or(|expr| !contains_return(expr)) + && for_each_expr_without_closures(then_block, |e| { + if matches!(e.kind, ExprKind::Ret(..) | ExprKind::Yield(..)) { + ControlFlow::Break(()) + } else { + ControlFlow::Continue(()) + } + }) + .is_none() { let method_name = if switch_to_eager_eval(cx, expr) && self.msrv.meets(cx, msrvs::BOOL_THEN_SOME) { sym::then_some diff --git a/tests/ui/if_then_some_else_none.fixed b/tests/ui/if_then_some_else_none.fixed index 7da9401a308f..9d4cbe6baf07 100644 --- a/tests/ui/if_then_some_else_none.fixed +++ b/tests/ui/if_then_some_else_none.fixed @@ -218,3 +218,13 @@ mod issue15770 { Ok(()) } } + +mod issue16176 { + pub async fn foo() -> u32 { + todo!() + } + + pub async fn bar(cond: bool) -> Option { + if cond { Some(foo().await) } else { None } // OK + } +} diff --git a/tests/ui/if_then_some_else_none.rs b/tests/ui/if_then_some_else_none.rs index 02962f83ce8a..6b1ece61e775 100644 --- a/tests/ui/if_then_some_else_none.rs +++ b/tests/ui/if_then_some_else_none.rs @@ -274,3 +274,13 @@ mod issue15770 { Ok(()) } } + +mod issue16176 { + pub async fn foo() -> u32 { + todo!() + } + + pub async fn bar(cond: bool) -> Option { + if cond { Some(foo().await) } else { None } // OK + } +}