Skip to content

Commit 076ec87

Browse files
committed
Lint for to_radians and to_degrees
1 parent 0c8afa3 commit 076ec87

File tree

4 files changed

+104
-2
lines changed

4 files changed

+104
-2
lines changed

clippy_lints/src/floating_point_arithmetic.rs

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -350,8 +350,18 @@ fn detect_hypot(cx: &LateContext<'_>, args: &[Expr<'_>]) -> Option<String> {
350350

351351
// check if expression of the form x.powi(2) + y.powi(2)
352352
if_chain! {
353-
if let ExprKind::MethodCall(PathSegment { ident: lmethod_name, .. }, ref _lspan, ref largs, _) = add_lhs.kind;
354-
if let ExprKind::MethodCall(PathSegment { ident: rmethod_name, .. }, ref _rspan, ref rargs, _) = add_rhs.kind;
353+
if let ExprKind::MethodCall(
354+
PathSegment { ident: lmethod_name, .. },
355+
ref _lspan,
356+
ref largs,
357+
_
358+
) = add_lhs.kind;
359+
if let ExprKind::MethodCall(
360+
PathSegment { ident: rmethod_name, .. },
361+
ref _rspan,
362+
ref rargs,
363+
_
364+
) = add_rhs.kind;
355365
if lmethod_name.as_str() == "powi" && rmethod_name.as_str() == "powi";
356366
if let Some((lvalue, _)) = constant(cx, cx.tables(), &largs[1]);
357367
if let Some((rvalue, _)) = constant(cx, cx.tables(), &rargs[1]);
@@ -617,6 +627,55 @@ fn check_log_division(cx: &LateContext<'_>, expr: &Expr<'_>) {
617627
}
618628
}
619629

630+
fn check_radians(cx: &LateContext<'_>, expr: &Expr<'_>) {
631+
if_chain! {
632+
if let ExprKind::Binary(
633+
Spanned {
634+
node: BinOpKind::Div, ..
635+
},
636+
div_lhs,
637+
div_rhs,
638+
) = &expr.kind;
639+
if let ExprKind::Binary(
640+
Spanned {
641+
node: BinOpKind::Mul, ..
642+
},
643+
mul_lhs,
644+
mul_rhs,
645+
) = &div_lhs.kind;
646+
if let Some((rvalue, _)) = constant(cx, cx.tables(), div_rhs);
647+
if let Some((lvalue, _)) = constant(cx, cx.tables(), mul_rhs);
648+
then {
649+
if (F32(f32_consts::PI) == rvalue || F64(f64_consts::PI) == rvalue) &&
650+
(F32(180_f32) == lvalue || F64(180_f64) == lvalue)
651+
{
652+
span_lint_and_sugg(
653+
cx,
654+
IMPRECISE_FLOPS,
655+
expr.span,
656+
"conversion to degrees can be done more accurately",
657+
"consider using",
658+
format!("{}.to_degrees()", Sugg::hir(cx, &mul_lhs, "..")),
659+
Applicability::MachineApplicable,
660+
);
661+
} else if
662+
(F32(180_f32) == rvalue || F64(180_f64) == rvalue) &&
663+
(F32(f32_consts::PI) == lvalue || F64(f64_consts::PI) == lvalue)
664+
{
665+
span_lint_and_sugg(
666+
cx,
667+
IMPRECISE_FLOPS,
668+
expr.span,
669+
"conversion to radians can be done more accurately",
670+
"consider using",
671+
format!("{}.to_radians()", Sugg::hir(cx, &mul_lhs, "..")),
672+
Applicability::MachineApplicable,
673+
);
674+
}
675+
}
676+
}
677+
}
678+
620679
impl<'tcx> LateLintPass<'tcx> for FloatingPointArithmetic {
621680
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
622681
if let ExprKind::MethodCall(ref path, _, args, _) = &expr.kind {
@@ -637,6 +696,7 @@ impl<'tcx> LateLintPass<'tcx> for FloatingPointArithmetic {
637696
check_mul_add(cx, expr);
638697
check_custom_abs(cx, expr);
639698
check_log_division(cx, expr);
699+
check_radians(cx, expr);
640700
}
641701
}
642702
}

tests/ui/floating_point_rad.fixed

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// run-rustfix
2+
#![warn(clippy::imprecise_flops)]
3+
4+
fn main() {
5+
let x = 3f32;
6+
let _ = x.to_degrees();
7+
let _ = x.to_radians();
8+
// Cases where the lint shouldn't be applied
9+
let _ = x * 90f32 / std::f32::consts::PI;
10+
let _ = x * std::f32::consts::PI / 90f32;
11+
let _ = x * 180f32 / std::f32::consts::E;
12+
let _ = x * std::f32::consts::E / 180f32;
13+
}

tests/ui/floating_point_rad.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// run-rustfix
2+
#![warn(clippy::imprecise_flops)]
3+
4+
fn main() {
5+
let x = 3f32;
6+
let _ = x * 180f32 / std::f32::consts::PI;
7+
let _ = x * std::f32::consts::PI / 180f32;
8+
// Cases where the lint shouldn't be applied
9+
let _ = x * 90f32 / std::f32::consts::PI;
10+
let _ = x * std::f32::consts::PI / 90f32;
11+
let _ = x * 180f32 / std::f32::consts::E;
12+
let _ = x * std::f32::consts::E / 180f32;
13+
}

tests/ui/floating_point_rad.stderr

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
error: conversion to degrees can be done more accurately
2+
--> $DIR/floating_point_rad.rs:6:13
3+
|
4+
LL | let _ = x * 180f32 / std::f32::consts::PI;
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.to_degrees()`
6+
|
7+
= note: `-D clippy::imprecise-flops` implied by `-D warnings`
8+
9+
error: conversion to radians can be done more accurately
10+
--> $DIR/floating_point_rad.rs:7:13
11+
|
12+
LL | let _ = x * std::f32::consts::PI / 180f32;
13+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.to_radians()`
14+
15+
error: aborting due to 2 previous errors
16+

0 commit comments

Comments
 (0)