Do not remove as if it changes the type

While `expr as T` can be removed as a statement if `expr` has no
side-effect, the `as T` part alone cannot be removed if the type
of `expr` would be ambiguous without the cast.
This commit is contained in:
Samuel Tardieu 2025-06-30 20:43:45 +02:00
parent b57bf6b64d
commit 8ceb91e1c7
No known key found for this signature in database
GPG key ID: BDDC3208C6FEAFA8
3 changed files with 30 additions and 2 deletions

View file

@ -1,6 +1,6 @@
use clippy_utils::diagnostics::{span_lint_hir, span_lint_hir_and_then};
use clippy_utils::source::SpanRangeExt;
use clippy_utils::ty::has_drop;
use clippy_utils::ty::{expr_type_is_certain, has_drop};
use clippy_utils::{
in_automatically_derived, is_inside_always_const_context, is_lint_allowed, path_to_local, peel_blocks,
};
@ -340,11 +340,13 @@ fn reduce_expression<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option<Vec
},
ExprKind::Array(v) | ExprKind::Tup(v) => Some(v.iter().collect()),
ExprKind::Repeat(inner, _)
| ExprKind::Cast(inner, _)
| ExprKind::Type(inner, _)
| ExprKind::Unary(_, inner)
| ExprKind::Field(inner, _)
| ExprKind::AddrOf(_, _, inner) => reduce_expression(cx, inner).or_else(|| Some(vec![inner])),
ExprKind::Cast(inner, _) if expr_type_is_certain(cx, inner) => {
reduce_expression(cx, inner).or_else(|| Some(vec![inner]))
},
ExprKind::Struct(_, fields, ref base) => {
if has_drop(cx, cx.typeck_results().expr_ty(expr)) {
None

View file

@ -144,3 +144,16 @@ const fn foo() {
assert!([42, 55].len() > get_usize());
//~^ unnecessary_operation
}
fn issue15173() {
// No lint as `Box::new(None)` alone would be ambiguous
Box::new(None) as Box<Option<i32>>;
}
#[expect(clippy::redundant_closure_call)]
fn issue15173_original<MsU>(handler: impl FnOnce() -> MsU + Clone + 'static) {
Box::new(move |value| {
(|_| handler.clone()())(value);
None
}) as Box<dyn Fn(i32) -> Option<i32>>;
}

View file

@ -150,3 +150,16 @@ const fn foo() {
[42, 55][get_usize()];
//~^ unnecessary_operation
}
fn issue15173() {
// No lint as `Box::new(None)` alone would be ambiguous
Box::new(None) as Box<Option<i32>>;
}
#[expect(clippy::redundant_closure_call)]
fn issue15173_original<MsU>(handler: impl FnOnce() -> MsU + Clone + 'static) {
Box::new(move |value| {
(|_| handler.clone()())(value);
None
}) as Box<dyn Fn(i32) -> Option<i32>>;
}