Auto merge of #9031 - evantypanski:manual_rem_euclid, r=Jarcho
Add [`manual_rem_euclid`] lint Closes #8883 Adds a lint for checking manual use of `rem_euclid(n)` changelog: Add [`manual_rem_euclid`] lint
This commit is contained in:
commit
e17864e2ff
13 changed files with 325 additions and 6 deletions
|
|
@ -127,3 +127,11 @@ macro_rules! ptr_as_ptr_cast {
|
|||
$ptr as *const i32
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! manual_rem_euclid {
|
||||
() => {
|
||||
let value: i32 = 5;
|
||||
let _: i32 = ((value % 4) + 4) % 4;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
55
tests/ui/manual_rem_euclid.fixed
Normal file
55
tests/ui/manual_rem_euclid.fixed
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
// run-rustfix
|
||||
// aux-build:macro_rules.rs
|
||||
|
||||
#![warn(clippy::manual_rem_euclid)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate macro_rules;
|
||||
|
||||
macro_rules! internal_rem_euclid {
|
||||
() => {
|
||||
let value: i32 = 5;
|
||||
let _: i32 = value.rem_euclid(4);
|
||||
};
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let value: i32 = 5;
|
||||
|
||||
let _: i32 = value.rem_euclid(4);
|
||||
let _: i32 = value.rem_euclid(4);
|
||||
let _: i32 = value.rem_euclid(4);
|
||||
let _: i32 = value.rem_euclid(4);
|
||||
let _: i32 = 1 + value.rem_euclid(4);
|
||||
|
||||
let _: i32 = (3 + value % 4) % 4;
|
||||
let _: i32 = (-4 + value % -4) % -4;
|
||||
let _: i32 = ((5 % 4) + 4) % 4;
|
||||
|
||||
// Make sure the lint does not trigger if it would cause an error, like with an ambiguous
|
||||
// integer type
|
||||
let not_annotated = 24;
|
||||
let _ = ((not_annotated % 4) + 4) % 4;
|
||||
let inferred: _ = 24;
|
||||
let _ = ((inferred % 4) + 4) % 4;
|
||||
|
||||
// For lint to apply the constant must always be on the RHS of the previous value for %
|
||||
let _: i32 = 4 % ((value % 4) + 4);
|
||||
let _: i32 = ((4 % value) + 4) % 4;
|
||||
|
||||
// Lint in internal macros
|
||||
internal_rem_euclid!();
|
||||
|
||||
// Do not lint in external macros
|
||||
manual_rem_euclid!();
|
||||
}
|
||||
|
||||
// Should lint for params too
|
||||
pub fn rem_euclid_4(num: i32) -> i32 {
|
||||
num.rem_euclid(4)
|
||||
}
|
||||
|
||||
// Constant version came later, should still lint
|
||||
pub const fn const_rem_euclid_4(num: i32) -> i32 {
|
||||
num.rem_euclid(4)
|
||||
}
|
||||
55
tests/ui/manual_rem_euclid.rs
Normal file
55
tests/ui/manual_rem_euclid.rs
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
// run-rustfix
|
||||
// aux-build:macro_rules.rs
|
||||
|
||||
#![warn(clippy::manual_rem_euclid)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate macro_rules;
|
||||
|
||||
macro_rules! internal_rem_euclid {
|
||||
() => {
|
||||
let value: i32 = 5;
|
||||
let _: i32 = ((value % 4) + 4) % 4;
|
||||
};
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let value: i32 = 5;
|
||||
|
||||
let _: i32 = ((value % 4) + 4) % 4;
|
||||
let _: i32 = (4 + (value % 4)) % 4;
|
||||
let _: i32 = (value % 4 + 4) % 4;
|
||||
let _: i32 = (4 + value % 4) % 4;
|
||||
let _: i32 = 1 + (4 + value % 4) % 4;
|
||||
|
||||
let _: i32 = (3 + value % 4) % 4;
|
||||
let _: i32 = (-4 + value % -4) % -4;
|
||||
let _: i32 = ((5 % 4) + 4) % 4;
|
||||
|
||||
// Make sure the lint does not trigger if it would cause an error, like with an ambiguous
|
||||
// integer type
|
||||
let not_annotated = 24;
|
||||
let _ = ((not_annotated % 4) + 4) % 4;
|
||||
let inferred: _ = 24;
|
||||
let _ = ((inferred % 4) + 4) % 4;
|
||||
|
||||
// For lint to apply the constant must always be on the RHS of the previous value for %
|
||||
let _: i32 = 4 % ((value % 4) + 4);
|
||||
let _: i32 = ((4 % value) + 4) % 4;
|
||||
|
||||
// Lint in internal macros
|
||||
internal_rem_euclid!();
|
||||
|
||||
// Do not lint in external macros
|
||||
manual_rem_euclid!();
|
||||
}
|
||||
|
||||
// Should lint for params too
|
||||
pub fn rem_euclid_4(num: i32) -> i32 {
|
||||
((num % 4) + 4) % 4
|
||||
}
|
||||
|
||||
// Constant version came later, should still lint
|
||||
pub const fn const_rem_euclid_4(num: i32) -> i32 {
|
||||
((num % 4) + 4) % 4
|
||||
}
|
||||
57
tests/ui/manual_rem_euclid.stderr
Normal file
57
tests/ui/manual_rem_euclid.stderr
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
error: manual `rem_euclid` implementation
|
||||
--> $DIR/manual_rem_euclid.rs:19:18
|
||||
|
|
||||
LL | let _: i32 = ((value % 4) + 4) % 4;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)`
|
||||
|
|
||||
= note: `-D clippy::manual-rem-euclid` implied by `-D warnings`
|
||||
|
||||
error: manual `rem_euclid` implementation
|
||||
--> $DIR/manual_rem_euclid.rs:20:18
|
||||
|
|
||||
LL | let _: i32 = (4 + (value % 4)) % 4;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)`
|
||||
|
||||
error: manual `rem_euclid` implementation
|
||||
--> $DIR/manual_rem_euclid.rs:21:18
|
||||
|
|
||||
LL | let _: i32 = (value % 4 + 4) % 4;
|
||||
| ^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)`
|
||||
|
||||
error: manual `rem_euclid` implementation
|
||||
--> $DIR/manual_rem_euclid.rs:22:18
|
||||
|
|
||||
LL | let _: i32 = (4 + value % 4) % 4;
|
||||
| ^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)`
|
||||
|
||||
error: manual `rem_euclid` implementation
|
||||
--> $DIR/manual_rem_euclid.rs:23:22
|
||||
|
|
||||
LL | let _: i32 = 1 + (4 + value % 4) % 4;
|
||||
| ^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)`
|
||||
|
||||
error: manual `rem_euclid` implementation
|
||||
--> $DIR/manual_rem_euclid.rs:12:22
|
||||
|
|
||||
LL | let _: i32 = ((value % 4) + 4) % 4;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)`
|
||||
...
|
||||
LL | internal_rem_euclid!();
|
||||
| ---------------------- in this macro invocation
|
||||
|
|
||||
= note: this error originates in the macro `internal_rem_euclid` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: manual `rem_euclid` implementation
|
||||
--> $DIR/manual_rem_euclid.rs:49:5
|
||||
|
|
||||
LL | ((num % 4) + 4) % 4
|
||||
| ^^^^^^^^^^^^^^^^^^^ help: consider using: `num.rem_euclid(4)`
|
||||
|
||||
error: manual `rem_euclid` implementation
|
||||
--> $DIR/manual_rem_euclid.rs:54:5
|
||||
|
|
||||
LL | ((num % 4) + 4) % 4
|
||||
| ^^^^^^^^^^^^^^^^^^^ help: consider using: `num.rem_euclid(4)`
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
|
||||
|
|
@ -155,6 +155,11 @@ fn cast_abs_to_unsigned() {
|
|||
assert_eq!(10u32, x.abs() as u32);
|
||||
}
|
||||
|
||||
fn manual_rem_euclid() {
|
||||
let x: i32 = 10;
|
||||
let _: i32 = ((x % 4) + 4) % 4;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
filter_map_next();
|
||||
checked_conversion();
|
||||
|
|
@ -174,6 +179,7 @@ fn main() {
|
|||
int_from_bool();
|
||||
err_expect();
|
||||
cast_abs_to_unsigned();
|
||||
manual_rem_euclid();
|
||||
}
|
||||
|
||||
mod just_under_msrv {
|
||||
|
|
@ -211,3 +217,12 @@ mod just_above_msrv {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod const_rem_euclid {
|
||||
#![feature(custom_inner_attributes)]
|
||||
#![clippy::msrv = "1.50.0"]
|
||||
|
||||
pub const fn const_rem_euclid_4(num: i32) -> i32 {
|
||||
((num % 4) + 4) % 4
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
error: stripping a prefix manually
|
||||
--> $DIR/min_rust_version_attr.rs:198:24
|
||||
--> $DIR/min_rust_version_attr.rs:204:24
|
||||
|
|
||||
LL | assert_eq!(s["hello, ".len()..].to_uppercase(), "WORLD!");
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `-D clippy::manual-strip` implied by `-D warnings`
|
||||
note: the prefix was tested here
|
||||
--> $DIR/min_rust_version_attr.rs:197:9
|
||||
--> $DIR/min_rust_version_attr.rs:203:9
|
||||
|
|
||||
LL | if s.starts_with("hello, ") {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -17,13 +17,13 @@ LL ~ assert_eq!(<stripped>.to_uppercase(), "WORLD!");
|
|||
|
|
||||
|
||||
error: stripping a prefix manually
|
||||
--> $DIR/min_rust_version_attr.rs:210:24
|
||||
--> $DIR/min_rust_version_attr.rs:216:24
|
||||
|
|
||||
LL | assert_eq!(s["hello, ".len()..].to_uppercase(), "WORLD!");
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: the prefix was tested here
|
||||
--> $DIR/min_rust_version_attr.rs:209:9
|
||||
--> $DIR/min_rust_version_attr.rs:215:9
|
||||
|
|
||||
LL | if s.starts_with("hello, ") {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue