Skip to content

Commit 59c0f29

Browse files
committed
Auto merge of #8519 - tysg:redundant-modulo, r=giraffate
Check if lhs < rhs in modulos in `identity_op` Fixes #8508 changelog: [`identity_op`] now checks for modulos, e.g. `1 % 3`
2 parents 8ebe766 + 52b563b commit 59c0f29

File tree

5 files changed

+90
-29
lines changed

5 files changed

+90
-29
lines changed

clippy_lints/src/identity_op.rs

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use rustc_middle::ty;
55
use rustc_session::{declare_lint_pass, declare_tool_lint};
66
use rustc_span::source_map::Span;
77

8-
use clippy_utils::consts::{constant_simple, Constant};
8+
use clippy_utils::consts::{constant_full_int, constant_simple, Constant, FullInt};
99
use clippy_utils::diagnostics::span_lint;
1010
use clippy_utils::{clip, unsext};
1111

@@ -54,6 +54,7 @@ impl<'tcx> LateLintPass<'tcx> for IdentityOp {
5454
check(cx, left, -1, e.span, right.span);
5555
check(cx, right, -1, e.span, left.span);
5656
},
57+
BinOpKind::Rem => check_remainder(cx, left, right, e.span, left.span),
5758
_ => (),
5859
}
5960
}
@@ -70,6 +71,18 @@ fn is_allowed(cx: &LateContext<'_>, cmp: BinOp, left: &Expr<'_>, right: &Expr<'_
7071
&& constant_simple(cx, cx.typeck_results(), left) == Some(Constant::Int(1)))
7172
}
7273

74+
fn check_remainder(cx: &LateContext<'_>, left: &Expr<'_>, right: &Expr<'_>, span: Span, arg: Span) {
75+
let lhs_const = constant_full_int(cx, cx.typeck_results(), left);
76+
let rhs_const = constant_full_int(cx, cx.typeck_results(), right);
77+
if match (lhs_const, rhs_const) {
78+
(Some(FullInt::S(lv)), Some(FullInt::S(rv))) => lv.abs() < rv.abs(),
79+
(Some(FullInt::U(lv)), Some(FullInt::U(rv))) => lv < rv,
80+
_ => return,
81+
} {
82+
span_ineffective_operation(cx, span, arg);
83+
}
84+
}
85+
7386
fn check(cx: &LateContext<'_>, e: &Expr<'_>, m: i8, span: Span, arg: Span) {
7487
if let Some(Constant::Int(v)) = constant_simple(cx, cx.typeck_results(), e).map(Constant::peel_refs) {
7588
let check = match *cx.typeck_results().expr_ty(e).peel_refs().kind() {
@@ -83,15 +96,19 @@ fn check(cx: &LateContext<'_>, e: &Expr<'_>, m: i8, span: Span, arg: Span) {
8396
1 => v == 1,
8497
_ => unreachable!(),
8598
} {
86-
span_lint(
87-
cx,
88-
IDENTITY_OP,
89-
span,
90-
&format!(
91-
"the operation is ineffective. Consider reducing it to `{}`",
92-
snippet(cx, arg, "..")
93-
),
94-
);
99+
span_ineffective_operation(cx, span, arg);
95100
}
96101
}
97102
}
103+
104+
fn span_ineffective_operation(cx: &LateContext<'_>, span: Span, arg: Span) {
105+
span_lint(
106+
cx,
107+
IDENTITY_OP,
108+
span,
109+
&format!(
110+
"the operation is ineffective. Consider reducing it to `{}`",
111+
snippet(cx, arg, "..")
112+
),
113+
);
114+
}

tests/ui/identity_op.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,13 @@ fn main() {
6666
let b = a << 0; // no error: non-integer
6767

6868
1 * Meter; // no error: non-integer
69+
70+
2 % 3;
71+
-2 % 3;
72+
2 % -3 + x;
73+
-2 % -3 + x;
74+
x + 1 % 3;
75+
(x + 1) % 3; // no error
76+
4 % 3; // no error
77+
4 % -3; // no error
6978
}

tests/ui/identity_op.stderr

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,5 +78,35 @@ error: the operation is ineffective. Consider reducing it to `x`
7878
LL | x >> &0;
7979
| ^^^^^^^
8080

81-
error: aborting due to 13 previous errors
81+
error: the operation is ineffective. Consider reducing it to `2`
82+
--> $DIR/identity_op.rs:70:5
83+
|
84+
LL | 2 % 3;
85+
| ^^^^^
86+
87+
error: the operation is ineffective. Consider reducing it to `-2`
88+
--> $DIR/identity_op.rs:71:5
89+
|
90+
LL | -2 % 3;
91+
| ^^^^^^
92+
93+
error: the operation is ineffective. Consider reducing it to `2`
94+
--> $DIR/identity_op.rs:72:5
95+
|
96+
LL | 2 % -3 + x;
97+
| ^^^^^^
98+
99+
error: the operation is ineffective. Consider reducing it to `-2`
100+
--> $DIR/identity_op.rs:73:5
101+
|
102+
LL | -2 % -3 + x;
103+
| ^^^^^^^
104+
105+
error: the operation is ineffective. Consider reducing it to `1`
106+
--> $DIR/identity_op.rs:74:9
107+
|
108+
LL | x + 1 % 3;
109+
| ^^^^^
110+
111+
error: aborting due to 18 previous errors
82112

tests/ui/modulo_arithmetic_integral_const.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
#![warn(clippy::modulo_arithmetic)]
2-
#![allow(clippy::no_effect, clippy::unnecessary_operation, clippy::modulo_one)]
2+
#![allow(
3+
clippy::no_effect,
4+
clippy::unnecessary_operation,
5+
clippy::modulo_one,
6+
clippy::identity_op
7+
)]
38

49
fn main() {
510
// Lint when both sides are const and of the opposite sign

tests/ui/modulo_arithmetic_integral_const.stderr

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: you are using modulo operator on constants with different signs: `-1 % 2`
2-
--> $DIR/modulo_arithmetic_integral_const.rs:6:5
2+
--> $DIR/modulo_arithmetic_integral_const.rs:11:5
33
|
44
LL | -1 % 2;
55
| ^^^^^^
@@ -9,7 +9,7 @@ LL | -1 % 2;
99
= note: or consider using `rem_euclid` or similar function
1010

1111
error: you are using modulo operator on constants with different signs: `1 % -2`
12-
--> $DIR/modulo_arithmetic_integral_const.rs:7:5
12+
--> $DIR/modulo_arithmetic_integral_const.rs:12:5
1313
|
1414
LL | 1 % -2;
1515
| ^^^^^^
@@ -18,7 +18,7 @@ LL | 1 % -2;
1818
= note: or consider using `rem_euclid` or similar function
1919

2020
error: you are using modulo operator on constants with different signs: `-1 % 3`
21-
--> $DIR/modulo_arithmetic_integral_const.rs:8:5
21+
--> $DIR/modulo_arithmetic_integral_const.rs:13:5
2222
|
2323
LL | (1 - 2) % (1 + 2);
2424
| ^^^^^^^^^^^^^^^^^
@@ -27,7 +27,7 @@ LL | (1 - 2) % (1 + 2);
2727
= note: or consider using `rem_euclid` or similar function
2828

2929
error: you are using modulo operator on constants with different signs: `3 % -1`
30-
--> $DIR/modulo_arithmetic_integral_const.rs:9:5
30+
--> $DIR/modulo_arithmetic_integral_const.rs:14:5
3131
|
3232
LL | (1 + 2) % (1 - 2);
3333
| ^^^^^^^^^^^^^^^^^
@@ -36,7 +36,7 @@ LL | (1 + 2) % (1 - 2);
3636
= note: or consider using `rem_euclid` or similar function
3737

3838
error: you are using modulo operator on constants with different signs: `-35 % 300000`
39-
--> $DIR/modulo_arithmetic_integral_const.rs:10:5
39+
--> $DIR/modulo_arithmetic_integral_const.rs:15:5
4040
|
4141
LL | 35 * (7 - 4 * 2) % (-500 * -600);
4242
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -45,7 +45,7 @@ LL | 35 * (7 - 4 * 2) % (-500 * -600);
4545
= note: or consider using `rem_euclid` or similar function
4646

4747
error: you are using modulo operator on constants with different signs: `-1 % 2`
48-
--> $DIR/modulo_arithmetic_integral_const.rs:12:5
48+
--> $DIR/modulo_arithmetic_integral_const.rs:17:5
4949
|
5050
LL | -1i8 % 2i8;
5151
| ^^^^^^^^^^
@@ -54,7 +54,7 @@ LL | -1i8 % 2i8;
5454
= note: or consider using `rem_euclid` or similar function
5555

5656
error: you are using modulo operator on constants with different signs: `1 % -2`
57-
--> $DIR/modulo_arithmetic_integral_const.rs:13:5
57+
--> $DIR/modulo_arithmetic_integral_const.rs:18:5
5858
|
5959
LL | 1i8 % -2i8;
6060
| ^^^^^^^^^^
@@ -63,7 +63,7 @@ LL | 1i8 % -2i8;
6363
= note: or consider using `rem_euclid` or similar function
6464

6565
error: you are using modulo operator on constants with different signs: `-1 % 2`
66-
--> $DIR/modulo_arithmetic_integral_const.rs:14:5
66+
--> $DIR/modulo_arithmetic_integral_const.rs:19:5
6767
|
6868
LL | -1i16 % 2i16;
6969
| ^^^^^^^^^^^^
@@ -72,7 +72,7 @@ LL | -1i16 % 2i16;
7272
= note: or consider using `rem_euclid` or similar function
7373

7474
error: you are using modulo operator on constants with different signs: `1 % -2`
75-
--> $DIR/modulo_arithmetic_integral_const.rs:15:5
75+
--> $DIR/modulo_arithmetic_integral_const.rs:20:5
7676
|
7777
LL | 1i16 % -2i16;
7878
| ^^^^^^^^^^^^
@@ -81,7 +81,7 @@ LL | 1i16 % -2i16;
8181
= note: or consider using `rem_euclid` or similar function
8282

8383
error: you are using modulo operator on constants with different signs: `-1 % 2`
84-
--> $DIR/modulo_arithmetic_integral_const.rs:16:5
84+
--> $DIR/modulo_arithmetic_integral_const.rs:21:5
8585
|
8686
LL | -1i32 % 2i32;
8787
| ^^^^^^^^^^^^
@@ -90,7 +90,7 @@ LL | -1i32 % 2i32;
9090
= note: or consider using `rem_euclid` or similar function
9191

9292
error: you are using modulo operator on constants with different signs: `1 % -2`
93-
--> $DIR/modulo_arithmetic_integral_const.rs:17:5
93+
--> $DIR/modulo_arithmetic_integral_const.rs:22:5
9494
|
9595
LL | 1i32 % -2i32;
9696
| ^^^^^^^^^^^^
@@ -99,7 +99,7 @@ LL | 1i32 % -2i32;
9999
= note: or consider using `rem_euclid` or similar function
100100

101101
error: you are using modulo operator on constants with different signs: `-1 % 2`
102-
--> $DIR/modulo_arithmetic_integral_const.rs:18:5
102+
--> $DIR/modulo_arithmetic_integral_const.rs:23:5
103103
|
104104
LL | -1i64 % 2i64;
105105
| ^^^^^^^^^^^^
@@ -108,7 +108,7 @@ LL | -1i64 % 2i64;
108108
= note: or consider using `rem_euclid` or similar function
109109

110110
error: you are using modulo operator on constants with different signs: `1 % -2`
111-
--> $DIR/modulo_arithmetic_integral_const.rs:19:5
111+
--> $DIR/modulo_arithmetic_integral_const.rs:24:5
112112
|
113113
LL | 1i64 % -2i64;
114114
| ^^^^^^^^^^^^
@@ -117,7 +117,7 @@ LL | 1i64 % -2i64;
117117
= note: or consider using `rem_euclid` or similar function
118118

119119
error: you are using modulo operator on constants with different signs: `-1 % 2`
120-
--> $DIR/modulo_arithmetic_integral_const.rs:20:5
120+
--> $DIR/modulo_arithmetic_integral_const.rs:25:5
121121
|
122122
LL | -1i128 % 2i128;
123123
| ^^^^^^^^^^^^^^
@@ -126,7 +126,7 @@ LL | -1i128 % 2i128;
126126
= note: or consider using `rem_euclid` or similar function
127127

128128
error: you are using modulo operator on constants with different signs: `1 % -2`
129-
--> $DIR/modulo_arithmetic_integral_const.rs:21:5
129+
--> $DIR/modulo_arithmetic_integral_const.rs:26:5
130130
|
131131
LL | 1i128 % -2i128;
132132
| ^^^^^^^^^^^^^^
@@ -135,7 +135,7 @@ LL | 1i128 % -2i128;
135135
= note: or consider using `rem_euclid` or similar function
136136

137137
error: you are using modulo operator on constants with different signs: `-1 % 2`
138-
--> $DIR/modulo_arithmetic_integral_const.rs:22:5
138+
--> $DIR/modulo_arithmetic_integral_const.rs:27:5
139139
|
140140
LL | -1isize % 2isize;
141141
| ^^^^^^^^^^^^^^^^
@@ -144,7 +144,7 @@ LL | -1isize % 2isize;
144144
= note: or consider using `rem_euclid` or similar function
145145

146146
error: you are using modulo operator on constants with different signs: `1 % -2`
147-
--> $DIR/modulo_arithmetic_integral_const.rs:23:5
147+
--> $DIR/modulo_arithmetic_integral_const.rs:28:5
148148
|
149149
LL | 1isize % -2isize;
150150
| ^^^^^^^^^^^^^^^^

0 commit comments

Comments
 (0)