diff options
| author | dswij <dharmasw@outlook.com> | 2025-07-06 09:58:44 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-07-06 09:58:44 +0000 |
| commit | 8d688c6f6059e9bb736b01e011137b760d692fda (patch) | |
| tree | 4b722197b0d0b682f5c6f44b4394503ab3e561d1 | |
| parent | 7c39d378e55331f2f181974a3740e9ade45790c4 (diff) | |
| parent | 8ceb91e1c7f3d644ca26f45ae63dac2216f98a4e (diff) | |
| download | rust-8d688c6f6059e9bb736b01e011137b760d692fda.tar.gz rust-8d688c6f6059e9bb736b01e011137b760d692fda.zip | |
Do not remove `as` if it changes the type (#15182)
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. changelog: [`unnecessary_operation`]: do not remove casts if they are useful to type the expression Fixes rust-lang/rust-clippy#15173
| -rw-r--r-- | clippy_lints/src/no_effect.rs | 6 | ||||
| -rw-r--r-- | tests/ui/unnecessary_operation.fixed | 13 | ||||
| -rw-r--r-- | tests/ui/unnecessary_operation.rs | 13 |
3 files changed, 30 insertions, 2 deletions
diff --git a/clippy_lints/src/no_effect.rs b/clippy_lints/src/no_effect.rs index 02c48166131..72e6503e7e4 100644 --- a/clippy_lints/src/no_effect.rs +++ b/clippy_lints/src/no_effect.rs @@ -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 diff --git a/tests/ui/unnecessary_operation.fixed b/tests/ui/unnecessary_operation.fixed index 645b56fe95e..ac9fa4de20a 100644 --- a/tests/ui/unnecessary_operation.fixed +++ b/tests/ui/unnecessary_operation.fixed @@ -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>>; +} diff --git a/tests/ui/unnecessary_operation.rs b/tests/ui/unnecessary_operation.rs index 97e90269c5c..a3e6c6288ad 100644 --- a/tests/ui/unnecessary_operation.rs +++ b/tests/ui/unnecessary_operation.rs @@ -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>>; +} |
