Skip to content

Commit 8d688c6

Browse files
authored
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 #15173
2 parents 7c39d37 + 8ceb91e commit 8d688c6

File tree

3 files changed

+30
-2
lines changed

3 files changed

+30
-2
lines changed

clippy_lints/src/no_effect.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use clippy_utils::diagnostics::{span_lint_hir, span_lint_hir_and_then};
22
use clippy_utils::source::SpanRangeExt;
3-
use clippy_utils::ty::has_drop;
3+
use clippy_utils::ty::{expr_type_is_certain, has_drop};
44
use clippy_utils::{
55
in_automatically_derived, is_inside_always_const_context, is_lint_allowed, path_to_local, peel_blocks,
66
};
@@ -340,11 +340,13 @@ fn reduce_expression<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option<Vec
340340
},
341341
ExprKind::Array(v) | ExprKind::Tup(v) => Some(v.iter().collect()),
342342
ExprKind::Repeat(inner, _)
343-
| ExprKind::Cast(inner, _)
344343
| ExprKind::Type(inner, _)
345344
| ExprKind::Unary(_, inner)
346345
| ExprKind::Field(inner, _)
347346
| ExprKind::AddrOf(_, _, inner) => reduce_expression(cx, inner).or_else(|| Some(vec![inner])),
347+
ExprKind::Cast(inner, _) if expr_type_is_certain(cx, inner) => {
348+
reduce_expression(cx, inner).or_else(|| Some(vec![inner]))
349+
},
348350
ExprKind::Struct(_, fields, ref base) => {
349351
if has_drop(cx, cx.typeck_results().expr_ty(expr)) {
350352
None

tests/ui/unnecessary_operation.fixed

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,3 +144,16 @@ const fn foo() {
144144
assert!([42, 55].len() > get_usize());
145145
//~^ unnecessary_operation
146146
}
147+
148+
fn issue15173() {
149+
// No lint as `Box::new(None)` alone would be ambiguous
150+
Box::new(None) as Box<Option<i32>>;
151+
}
152+
153+
#[expect(clippy::redundant_closure_call)]
154+
fn issue15173_original<MsU>(handler: impl FnOnce() -> MsU + Clone + 'static) {
155+
Box::new(move |value| {
156+
(|_| handler.clone()())(value);
157+
None
158+
}) as Box<dyn Fn(i32) -> Option<i32>>;
159+
}

tests/ui/unnecessary_operation.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,3 +150,16 @@ const fn foo() {
150150
[42, 55][get_usize()];
151151
//~^ unnecessary_operation
152152
}
153+
154+
fn issue15173() {
155+
// No lint as `Box::new(None)` alone would be ambiguous
156+
Box::new(None) as Box<Option<i32>>;
157+
}
158+
159+
#[expect(clippy::redundant_closure_call)]
160+
fn issue15173_original<MsU>(handler: impl FnOnce() -> MsU + Clone + 'static) {
161+
Box::new(move |value| {
162+
(|_| handler.clone()())(value);
163+
None
164+
}) as Box<dyn Fn(i32) -> Option<i32>>;
165+
}

0 commit comments

Comments
 (0)