Skip to content

Commit 461fcb7

Browse files
committed
Fix if_then_some_else_none FP when the then block contains await codes
1 parent 21c5ddd commit 461fcb7

File tree

3 files changed

+37
-3
lines changed

3 files changed

+37
-3
lines changed

clippy_lints/src/if_then_some_else_none.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1+
use std::ops::ControlFlow;
2+
13
use clippy_config::Conf;
24
use clippy_utils::diagnostics::span_lint_and_then;
35
use clippy_utils::eager_or_lazy::switch_to_eager_eval;
46
use clippy_utils::msrvs::{self, Msrv};
57
use clippy_utils::source::{snippet_with_applicability, snippet_with_context, walk_span_to_context};
68
use clippy_utils::sugg::Sugg;
9+
use clippy_utils::visitors::for_each_expr_without_closures;
710
use clippy_utils::{
8-
as_some_expr, contains_return, expr_adjustment_requires_coercion, higher, is_else_clause, is_in_const_context,
9-
is_none_expr, peel_blocks, sym,
11+
as_some_expr, contains_return, desugar_await, expr_adjustment_requires_coercion, higher, is_else_clause,
12+
is_in_const_context, is_none_expr, peel_blocks, sym,
1013
};
1114
use rustc_errors::Applicability;
1215
use rustc_hir::{Expr, ExprKind};
@@ -77,7 +80,18 @@ impl<'tcx> LateLintPass<'tcx> for IfThenSomeElseNone {
7780
&& !is_in_const_context(cx)
7881
&& self.msrv.meets(cx, msrvs::BOOL_THEN)
7982
&& !contains_return(then_block.stmts)
80-
&& then_block.expr.is_none_or(|expr| !contains_return(expr))
83+
&& then_block.expr.is_none_or(|expr| {
84+
!contains_return(expr)
85+
// `bool::then` doesn't work with async code
86+
&& for_each_expr_without_closures(expr, |e| {
87+
if desugar_await(e).is_some() {
88+
ControlFlow::Break(())
89+
} else {
90+
ControlFlow::Continue(())
91+
}
92+
})
93+
.is_none()
94+
})
8195
{
8296
let method_name = if switch_to_eager_eval(cx, expr) && self.msrv.meets(cx, msrvs::BOOL_THEN_SOME) {
8397
sym::then_some

tests/ui/if_then_some_else_none.fixed

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,3 +218,13 @@ mod issue15770 {
218218
Ok(())
219219
}
220220
}
221+
222+
mod issue16176 {
223+
pub async fn foo() -> u32 {
224+
todo!()
225+
}
226+
227+
pub async fn bar(cond: bool) -> Option<u32> {
228+
if cond { Some(foo().await) } else { None } // OK
229+
}
230+
}

tests/ui/if_then_some_else_none.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,3 +274,13 @@ mod issue15770 {
274274
Ok(())
275275
}
276276
}
277+
278+
mod issue16176 {
279+
pub async fn foo() -> u32 {
280+
todo!()
281+
}
282+
283+
pub async fn bar(cond: bool) -> Option<u32> {
284+
if cond { Some(foo().await) } else { None } // OK
285+
}
286+
}

0 commit comments

Comments
 (0)