From b6c0d63082e73299088fce71a83d807d7c6c3fd8 Mon Sep 17 00:00:00 2001 From: yanglsh Date: Sun, 13 Jul 2025 21:53:34 +0800 Subject: [PATCH] fix: `if_then_some_else_none` FP when require type coercion --- clippy_lints/src/if_then_some_else_none.rs | 4 +++- tests/ui/if_then_some_else_none.fixed | 16 ++++++++++++++++ tests/ui/if_then_some_else_none.rs | 16 ++++++++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/clippy_lints/src/if_then_some_else_none.rs b/clippy_lints/src/if_then_some_else_none.rs index 9e94280fc074..7d76c4d4a3c7 100644 --- a/clippy_lints/src/if_then_some_else_none.rs +++ b/clippy_lints/src/if_then_some_else_none.rs @@ -5,7 +5,8 @@ use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_with_context; use clippy_utils::sugg::Sugg; use clippy_utils::{ - contains_return, higher, is_else_clause, is_in_const_context, is_res_lang_ctor, path_res, peel_blocks, + contains_return, expr_requires_coercion, higher, is_else_clause, is_in_const_context, is_res_lang_ctor, path_res, + peel_blocks, }; use rustc_errors::Applicability; use rustc_hir::LangItem::{OptionNone, OptionSome}; @@ -79,6 +80,7 @@ impl<'tcx> LateLintPass<'tcx> for IfThenSomeElseNone { && !expr.span.in_external_macro(cx.sess().source_map()) && self.msrv.meets(cx, msrvs::BOOL_THEN) && !contains_return(then_block.stmts) + && !expr_requires_coercion(cx, then_expr) { let method_name = if switch_to_eager_eval(cx, expr) && self.msrv.meets(cx, msrvs::BOOL_THEN_SOME) { "then_some" diff --git a/tests/ui/if_then_some_else_none.fixed b/tests/ui/if_then_some_else_none.fixed index f774608712d1..0458923d24e9 100644 --- a/tests/ui/if_then_some_else_none.fixed +++ b/tests/ui/if_then_some_else_none.fixed @@ -122,3 +122,19 @@ const fn issue12103(x: u32) -> Option { // Should not issue an error in `const` context if x > 42 { Some(150) } else { None } } + +mod issue15257 { + #[derive(Default)] + pub struct Foo {} + pub trait Bar {} + impl Bar for Foo {} + + #[allow(clippy::manual_is_multiple_of)] + fn maybe_get_bar(i: u32) -> Option> { + if i % 2 == 0 { + Some(Box::new(Foo::default())) + } else { + None + } + } +} diff --git a/tests/ui/if_then_some_else_none.rs b/tests/ui/if_then_some_else_none.rs index 8b8ff0a6ea00..5bef83838b81 100644 --- a/tests/ui/if_then_some_else_none.rs +++ b/tests/ui/if_then_some_else_none.rs @@ -143,3 +143,19 @@ const fn issue12103(x: u32) -> Option { // Should not issue an error in `const` context if x > 42 { Some(150) } else { None } } + +mod issue15257 { + #[derive(Default)] + pub struct Foo {} + pub trait Bar {} + impl Bar for Foo {} + + #[allow(clippy::manual_is_multiple_of)] + fn maybe_get_bar(i: u32) -> Option> { + if i % 2 == 0 { + Some(Box::new(Foo::default())) + } else { + None + } + } +}