Skip to content

Commit 296587c

Browse files
committed
manual_midpoint: support signed integer types as well
`midpoint()` for integer types has been stabilized in Rust 1.87.
1 parent d8e4023 commit 296587c

File tree

5 files changed

+52
-15
lines changed

5 files changed

+52
-15
lines changed

clippy_lints/src/operators/manual_midpoint.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use rustc_ast::BinOpKind;
66
use rustc_errors::Applicability;
77
use rustc_hir::{Expr, ExprKind};
88
use rustc_lint::LateContext;
9-
use rustc_middle::ty;
9+
use rustc_middle::ty::{self, Ty};
1010

1111
use super::MANUAL_MIDPOINT;
1212

@@ -18,8 +18,7 @@ pub(super) fn check<'tcx>(
1818
right: &'tcx Expr<'_>,
1919
msrv: &Msrv,
2020
) {
21-
if msrv.meets(msrvs::UINT_FLOAT_MIDPOINT)
22-
&& !left.span.from_expansion()
21+
if !left.span.from_expansion()
2322
&& !right.span.from_expansion()
2423
&& op == BinOpKind::Div
2524
&& (is_integer_literal(right, 2) || is_float_literal(right, 2.0))
@@ -30,8 +29,7 @@ pub(super) fn check<'tcx>(
3029
&& left_ty == right_ty
3130
// Do not lint on `(_+1)/2` and `(1+_)/2`, it is likely a `div_ceil()` operation
3231
&& !is_integer_literal(ll_expr, 1) && !is_integer_literal(lr_expr, 1)
33-
// FIXME: Also lint on signed integers when rust-lang/rust#134340 is merged
34-
&& matches!(left_ty.kind(), ty::Uint(_) | ty::Float(_))
32+
&& is_midpoint_implemented(left_ty, msrv)
3533
{
3634
let mut app = Applicability::MachineApplicable;
3735
let left_sugg = Sugg::hir_with_context(cx, ll_expr, expr.span.ctxt(), "..", &mut app);
@@ -56,3 +54,11 @@ fn add_operands<'e, 'tcx>(expr: &'e Expr<'tcx>) -> Option<(&'e Expr<'tcx>, &'e E
5654
_ => None,
5755
}
5856
}
57+
58+
fn is_midpoint_implemented(ty: Ty<'_>, msrv: &Msrv) -> bool {
59+
match ty.kind() {
60+
ty::Uint(_) | ty::Float(_) => msrv.meets(msrvs::UINT_FLOAT_MIDPOINT),
61+
ty::Int(_) => msrv.meets(msrvs::INT_MIDPOINT),
62+
_ => false,
63+
}
64+
}

clippy_utils/src/msrvs.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ macro_rules! msrv_aliases {
1919

2020
// names may refer to stabilized feature flags or library items
2121
msrv_aliases! {
22+
1,87,0 { INT_MIDPOINT }
2223
1,85,0 { UINT_FLOAT_MIDPOINT }
2324
1,84,0 { CONST_OPTION_AS_SLICE }
2425
1,83,0 { CONST_EXTERN_FN, CONST_FLOAT_BITS_CONV, CONST_FLOAT_CLASSIFY, CONST_MUT_REFS, CONST_UNWRAP }

tests/ui/manual_midpoint.fixed

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#![warn(clippy::manual_midpoint)]
2+
#![feature(num_midpoint_signed)]
23

34
macro_rules! mac {
45
($a: expr, $b: expr) => {
@@ -61,3 +62,14 @@ fn main() {
6162
let _ = f32::midpoint(f, 1.0); //~ ERROR: manual implementation of `midpoint`
6263
let _ = f32::midpoint(1.0, f); //~ ERROR: manual implementation of `midpoint`
6364
}
65+
66+
#[clippy::msrv = "1.86"]
67+
fn older_signed_midpoint(i: i32) {
68+
// Do not lint
69+
let _ = (i + 10) / 2;
70+
}
71+
72+
#[clippy::msrv = "1.87"]
73+
fn signed_midpoint(i: i32) {
74+
let _ = i32::midpoint(i, 10); //~ ERROR: manual implementation of `midpoint`
75+
}

tests/ui/manual_midpoint.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#![warn(clippy::manual_midpoint)]
2+
#![feature(num_midpoint_signed)]
23

34
macro_rules! mac {
45
($a: expr, $b: expr) => {
@@ -61,3 +62,14 @@ fn main() {
6162
let _ = (f + 1.0) / 2.0; //~ ERROR: manual implementation of `midpoint`
6263
let _ = (1.0 + f) / 2.0; //~ ERROR: manual implementation of `midpoint`
6364
}
65+
66+
#[clippy::msrv = "1.86"]
67+
fn older_signed_midpoint(i: i32) {
68+
// Do not lint
69+
let _ = (i + 10) / 2;
70+
}
71+
72+
#[clippy::msrv = "1.87"]
73+
fn signed_midpoint(i: i32) {
74+
let _ = (i + 10) / 2; //~ ERROR: manual implementation of `midpoint`
75+
}

tests/ui/manual_midpoint.stderr

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: manual implementation of `midpoint` which can overflow
2-
--> tests/ui/manual_midpoint.rs:30:13
2+
--> tests/ui/manual_midpoint.rs:31:13
33
|
44
LL | let _ = (a + 5) / 2;
55
| ^^^^^^^^^^^ help: use `u32::midpoint` instead: `u32::midpoint(a, 5)`
@@ -8,52 +8,58 @@ LL | let _ = (a + 5) / 2;
88
= help: to override `-D warnings` add `#[allow(clippy::manual_midpoint)]`
99

1010
error: manual implementation of `midpoint` which can overflow
11-
--> tests/ui/manual_midpoint.rs:33:13
11+
--> tests/ui/manual_midpoint.rs:34:13
1212
|
1313
LL | let _ = (f + 5.0) / 2.0;
1414
| ^^^^^^^^^^^^^^^ help: use `f32::midpoint` instead: `f32::midpoint(f, 5.0)`
1515

1616
error: manual implementation of `midpoint` which can overflow
17-
--> tests/ui/manual_midpoint.rs:35:22
17+
--> tests/ui/manual_midpoint.rs:36:22
1818
|
1919
LL | let _: u32 = 5 + (8 + 8) / 2 + 2;
2020
| ^^^^^^^^^^^ help: use `u32::midpoint` instead: `u32::midpoint(8, 8)`
2121

2222
error: manual implementation of `midpoint` which can overflow
23-
--> tests/ui/manual_midpoint.rs:36:26
23+
--> tests/ui/manual_midpoint.rs:37:26
2424
|
2525
LL | let _: u32 = const { (8 + 8) / 2 };
2626
| ^^^^^^^^^^^ help: use `u32::midpoint` instead: `u32::midpoint(8, 8)`
2727

2828
error: manual implementation of `midpoint` which can overflow
29-
--> tests/ui/manual_midpoint.rs:37:26
29+
--> tests/ui/manual_midpoint.rs:38:26
3030
|
3131
LL | let _: f64 = const { (8.0f64 + 8.) / 2. };
3232
| ^^^^^^^^^^^^^^^^^^ help: use `f64::midpoint` instead: `f64::midpoint(8.0f64, 8.)`
3333

3434
error: manual implementation of `midpoint` which can overflow
35-
--> tests/ui/manual_midpoint.rs:38:18
35+
--> tests/ui/manual_midpoint.rs:39:18
3636
|
3737
LL | let _: u32 = (u32::default() + u32::default()) / 2;
3838
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `u32::midpoint` instead: `u32::midpoint(u32::default(), u32::default())`
3939

4040
error: manual implementation of `midpoint` which can overflow
41-
--> tests/ui/manual_midpoint.rs:39:18
41+
--> tests/ui/manual_midpoint.rs:40:18
4242
|
4343
LL | let _: u32 = (two!() + two!()) / 2;
4444
| ^^^^^^^^^^^^^^^^^^^^^ help: use `u32::midpoint` instead: `u32::midpoint(two!(), two!())`
4545

4646
error: manual implementation of `midpoint` which can overflow
47-
--> tests/ui/manual_midpoint.rs:61:13
47+
--> tests/ui/manual_midpoint.rs:62:13
4848
|
4949
LL | let _ = (f + 1.0) / 2.0;
5050
| ^^^^^^^^^^^^^^^ help: use `f32::midpoint` instead: `f32::midpoint(f, 1.0)`
5151

5252
error: manual implementation of `midpoint` which can overflow
53-
--> tests/ui/manual_midpoint.rs:62:13
53+
--> tests/ui/manual_midpoint.rs:63:13
5454
|
5555
LL | let _ = (1.0 + f) / 2.0;
5656
| ^^^^^^^^^^^^^^^ help: use `f32::midpoint` instead: `f32::midpoint(1.0, f)`
5757

58-
error: aborting due to 9 previous errors
58+
error: manual implementation of `midpoint` which can overflow
59+
--> tests/ui/manual_midpoint.rs:74:13
60+
|
61+
LL | let _ = (i + 10) / 2;
62+
| ^^^^^^^^^^^^ help: use `i32::midpoint` instead: `i32::midpoint(i, 10)`
63+
64+
error: aborting due to 10 previous errors
5965

0 commit comments

Comments
 (0)