Skip to content

Commit ac12011

Browse files
committed
Auto merge of #9577 - kraktus:unnecessary_cast, r=llogiq
[`unnecessary_cast`] add parenthesis when negative number uses a method fix #9563 The issue was probably introduced by 90fe3be changelog: [`unnecessary_cast`] add parenthesis when negative number uses a method r? llogiq
2 parents d6d5ecd + 90b446f commit ac12011

File tree

4 files changed

+50
-9
lines changed

4 files changed

+50
-9
lines changed

clippy_lints/src/casts/unnecessary_cast.rs

+25-8
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use clippy_utils::diagnostics::span_lint_and_sugg;
2+
use clippy_utils::get_parent_expr;
23
use clippy_utils::numeric_literal::NumericLiteral;
34
use clippy_utils::source::snippet_opt;
45
use if_chain::if_chain;
@@ -85,22 +86,38 @@ pub(super) fn check<'tcx>(
8586
false
8687
}
8788

88-
fn lint_unnecessary_cast(cx: &LateContext<'_>, expr: &Expr<'_>, literal_str: &str, cast_from: Ty<'_>, cast_to: Ty<'_>) {
89+
fn lint_unnecessary_cast(
90+
cx: &LateContext<'_>,
91+
expr: &Expr<'_>,
92+
raw_literal_str: &str,
93+
cast_from: Ty<'_>,
94+
cast_to: Ty<'_>,
95+
) {
8996
let literal_kind_name = if cast_from.is_integral() { "integer" } else { "float" };
90-
let replaced_literal;
91-
let matchless = if literal_str.contains(['(', ')']) {
92-
replaced_literal = literal_str.replace(['(', ')'], "");
93-
&replaced_literal
94-
} else {
95-
literal_str
97+
// first we remove all matches so `-(1)` become `-1`, and remove trailing dots, so `1.` become `1`
98+
let literal_str = raw_literal_str
99+
.replace(['(', ')'], "")
100+
.trim_end_matches('.')
101+
.to_string();
102+
// we know need to check if the parent is a method call, to add parenthesis accordingly (eg:
103+
// (-1).foo() instead of -1.foo())
104+
let sugg = if let Some(parent_expr) = get_parent_expr(cx, expr)
105+
&& let ExprKind::MethodCall(..) = parent_expr.kind
106+
&& literal_str.starts_with('-')
107+
{
108+
format!("({literal_str}_{cast_to})")
109+
110+
} else {
111+
format!("{literal_str}_{cast_to}")
96112
};
113+
97114
span_lint_and_sugg(
98115
cx,
99116
UNNECESSARY_CAST,
100117
expr.span,
101118
&format!("casting {literal_kind_name} literal to `{cast_to}` is unnecessary"),
102119
"try",
103-
format!("{}_{cast_to}", matchless.trim_end_matches('.')),
120+
sugg,
104121
Applicability::MachineApplicable,
105122
);
106123
}

tests/ui/unnecessary_cast.fixed

+6
Original file line numberDiff line numberDiff line change
@@ -97,4 +97,10 @@ mod fixable {
9797

9898
let _ = -(1 + 1) as i64;
9999
}
100+
101+
fn issue_9563() {
102+
let _: f64 = (-8.0_f64).exp();
103+
#[allow(clippy::precedence)]
104+
let _: f64 = -8.0_f64.exp(); // should suggest `-8.0_f64.exp()` here not to change code behavior
105+
}
100106
}

tests/ui/unnecessary_cast.rs

+6
Original file line numberDiff line numberDiff line change
@@ -97,4 +97,10 @@ mod fixable {
9797

9898
let _ = -(1 + 1) as i64;
9999
}
100+
101+
fn issue_9563() {
102+
let _: f64 = (-8.0 as f64).exp();
103+
#[allow(clippy::precedence)]
104+
let _: f64 = -(8.0 as f64).exp(); // should suggest `-8.0_f64.exp()` here not to change code behavior
105+
}
100106
}

tests/ui/unnecessary_cast.stderr

+13-1
Original file line numberDiff line numberDiff line change
@@ -162,5 +162,17 @@ error: casting integer literal to `i64` is unnecessary
162162
LL | let _: i64 = -(1) as i64;
163163
| ^^^^^^^^^^^ help: try: `-1_i64`
164164

165-
error: aborting due to 27 previous errors
165+
error: casting float literal to `f64` is unnecessary
166+
--> $DIR/unnecessary_cast.rs:102:22
167+
|
168+
LL | let _: f64 = (-8.0 as f64).exp();
169+
| ^^^^^^^^^^^^^ help: try: `(-8.0_f64)`
170+
171+
error: casting float literal to `f64` is unnecessary
172+
--> $DIR/unnecessary_cast.rs:104:23
173+
|
174+
LL | let _: f64 = -(8.0 as f64).exp(); // should suggest `-8.0_f64.exp()` here not to change code behavior
175+
| ^^^^^^^^^^^^ help: try: `8.0_f64`
176+
177+
error: aborting due to 29 previous errors
166178

0 commit comments

Comments
 (0)