-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of #5727 - rail-rain:manual_memcpy_with_counter, r=flip1995
Expands `manual_memcpy` to lint ones with loop counters Closes #1670 This PR expands `manual_memcpy` to lint ones with loop counters as described in #1670 (comment) Although the current code is working, I have a couple of questions and concerns. ~~Firstly, I manually implemented `Clone` for `Sugg` because `AssocOp` lacks `Clone`. As `AssocOp` only holds an enum, which is `Copy`, as a value, it seems `AssocOp` can be `Clone`; but, I was not sure where to ask it. Should I make a PR to `rustc`?~~ The [PR]( rust-lang/rust#73629) was made. Secondly, manual copying with loop counters are likely to trigger `needless_range_loop` and `explicit_counter_loop` along with `manual_memcpy`; in fact, I explicitly allowed them in the tests. Is there any way to disable these two lints when a code triggers `manual_memcpy`? And, another thing I'd like to note is that `Sugg` adds unnecessary parentheses when expressions with parentheses passed to its `hir` function, as seen here: ``` error: it looks like you're manually copying between slices --> $DIR/manual_memcpy.rs:145:14 | LL | for i in 3..(3 + src.len()) { | ^^^^^^^^^^^^^^^^^^ help: try replacing the loop by: `dst[3..((3 + src.len()))].clone_from_slice(&src[..((3 + src.len()) - 3)]) ``` However, using the `hir` function is needed to prevent the suggestion causing errors when users use bitwise operations; and also this have already existed, for example: `verbose_bit_mask`. Thus, I think this is fine. changelog: Expands `manual_memcpy` to lint ones with loop counters
- Loading branch information
Showing
8 changed files
with
804 additions
and
297 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
#![warn(clippy::needless_range_loop, clippy::manual_memcpy)] | ||
|
||
pub fn manual_copy_with_counters(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) { | ||
let mut count = 0; | ||
for i in 3..src.len() { | ||
dst[i] = src[count]; | ||
count += 1; | ||
} | ||
|
||
let mut count = 0; | ||
for i in 3..src.len() { | ||
dst[count] = src[i]; | ||
count += 1; | ||
} | ||
|
||
let mut count = 3; | ||
for i in 0..src.len() { | ||
dst[count] = src[i]; | ||
count += 1; | ||
} | ||
|
||
let mut count = 3; | ||
for i in 0..src.len() { | ||
dst[i] = src[count]; | ||
count += 1; | ||
} | ||
|
||
let mut count = 0; | ||
for i in 3..(3 + src.len()) { | ||
dst[i] = src[count]; | ||
count += 1; | ||
} | ||
|
||
let mut count = 3; | ||
for i in 5..src.len() { | ||
dst[i] = src[count - 2]; | ||
count += 1; | ||
} | ||
|
||
let mut count = 2; | ||
for i in 0..dst.len() { | ||
dst[i] = src[count]; | ||
count += 1; | ||
} | ||
|
||
let mut count = 5; | ||
for i in 3..10 { | ||
dst[i] = src[count]; | ||
count += 1; | ||
} | ||
|
||
let mut count = 3; | ||
let mut count2 = 30; | ||
for i in 0..src.len() { | ||
dst[count] = src[i]; | ||
dst2[count2] = src[i]; | ||
count += 1; | ||
count2 += 1; | ||
} | ||
|
||
// make sure parentheses are added properly to bitwise operators, which have lower precedence than | ||
// arithmetric ones | ||
let mut count = 0 << 1; | ||
for i in 0..1 << 1 { | ||
dst[count] = src[i + 2]; | ||
count += 1; | ||
} | ||
|
||
// make sure incrementing expressions without semicolons at the end of loops are handled correctly. | ||
let mut count = 0; | ||
for i in 3..src.len() { | ||
dst[i] = src[count]; | ||
count += 1 | ||
} | ||
|
||
// make sure ones where the increment is not at the end of the loop. | ||
// As a possible enhancement, one could adjust the offset in the suggestion according to | ||
// the position. For example, if the increment is at the top of the loop; | ||
// treating the loop counter as if it were initialized 1 greater than the original value. | ||
let mut count = 0; | ||
#[allow(clippy::needless_range_loop)] | ||
for i in 0..src.len() { | ||
count += 1; | ||
dst[i] = src[count]; | ||
} | ||
} | ||
|
||
fn main() {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
error: it looks like you're manually copying between slices | ||
--> $DIR/with_loop_counters.rs:5:5 | ||
| | ||
LL | / for i in 3..src.len() { | ||
LL | | dst[i] = src[count]; | ||
LL | | count += 1; | ||
LL | | } | ||
| |_____^ help: try replacing the loop by: `dst[3..src.len()].clone_from_slice(&src[..(src.len() - 3)]);` | ||
| | ||
= note: `-D clippy::manual-memcpy` implied by `-D warnings` | ||
|
||
error: it looks like you're manually copying between slices | ||
--> $DIR/with_loop_counters.rs:11:5 | ||
| | ||
LL | / for i in 3..src.len() { | ||
LL | | dst[count] = src[i]; | ||
LL | | count += 1; | ||
LL | | } | ||
| |_____^ help: try replacing the loop by: `dst[..(src.len() - 3)].clone_from_slice(&src[3..]);` | ||
|
||
error: it looks like you're manually copying between slices | ||
--> $DIR/with_loop_counters.rs:17:5 | ||
| | ||
LL | / for i in 0..src.len() { | ||
LL | | dst[count] = src[i]; | ||
LL | | count += 1; | ||
LL | | } | ||
| |_____^ help: try replacing the loop by: `dst[3..(src.len() + 3)].clone_from_slice(&src[..]);` | ||
|
||
error: it looks like you're manually copying between slices | ||
--> $DIR/with_loop_counters.rs:23:5 | ||
| | ||
LL | / for i in 0..src.len() { | ||
LL | | dst[i] = src[count]; | ||
LL | | count += 1; | ||
LL | | } | ||
| |_____^ help: try replacing the loop by: `dst[..src.len()].clone_from_slice(&src[3..(src.len() + 3)]);` | ||
|
||
error: it looks like you're manually copying between slices | ||
--> $DIR/with_loop_counters.rs:29:5 | ||
| | ||
LL | / for i in 3..(3 + src.len()) { | ||
LL | | dst[i] = src[count]; | ||
LL | | count += 1; | ||
LL | | } | ||
| |_____^ help: try replacing the loop by: `dst[3..((3 + src.len()))].clone_from_slice(&src[..((3 + src.len()) - 3)]);` | ||
|
||
error: it looks like you're manually copying between slices | ||
--> $DIR/with_loop_counters.rs:35:5 | ||
| | ||
LL | / for i in 5..src.len() { | ||
LL | | dst[i] = src[count - 2]; | ||
LL | | count += 1; | ||
LL | | } | ||
| |_____^ help: try replacing the loop by: `dst[5..src.len()].clone_from_slice(&src[(3 - 2)..((src.len() - 2) + 3 - 5)]);` | ||
|
||
error: it looks like you're manually copying between slices | ||
--> $DIR/with_loop_counters.rs:41:5 | ||
| | ||
LL | / for i in 0..dst.len() { | ||
LL | | dst[i] = src[count]; | ||
LL | | count += 1; | ||
LL | | } | ||
| |_____^ help: try replacing the loop by: `dst.clone_from_slice(&src[2..(dst.len() + 2)]);` | ||
|
||
error: it looks like you're manually copying between slices | ||
--> $DIR/with_loop_counters.rs:47:5 | ||
| | ||
LL | / for i in 3..10 { | ||
LL | | dst[i] = src[count]; | ||
LL | | count += 1; | ||
LL | | } | ||
| |_____^ help: try replacing the loop by: `dst[3..10].clone_from_slice(&src[5..(10 + 5 - 3)]);` | ||
|
||
error: it looks like you're manually copying between slices | ||
--> $DIR/with_loop_counters.rs:54:5 | ||
| | ||
LL | / for i in 0..src.len() { | ||
LL | | dst[count] = src[i]; | ||
LL | | dst2[count2] = src[i]; | ||
LL | | count += 1; | ||
LL | | count2 += 1; | ||
LL | | } | ||
| |_____^ | ||
| | ||
help: try replacing the loop by | ||
| | ||
LL | dst[3..(src.len() + 3)].clone_from_slice(&src[..]); | ||
LL | dst2[30..(src.len() + 30)].clone_from_slice(&src[..]); | ||
| | ||
|
||
error: it looks like you're manually copying between slices | ||
--> $DIR/with_loop_counters.rs:64:5 | ||
| | ||
LL | / for i in 0..1 << 1 { | ||
LL | | dst[count] = src[i + 2]; | ||
LL | | count += 1; | ||
LL | | } | ||
| |_____^ help: try replacing the loop by: `dst[(0 << 1)..((1 << 1) + (0 << 1))].clone_from_slice(&src[2..((1 << 1) + 2)]);` | ||
|
||
error: it looks like you're manually copying between slices | ||
--> $DIR/with_loop_counters.rs:71:5 | ||
| | ||
LL | / for i in 3..src.len() { | ||
LL | | dst[i] = src[count]; | ||
LL | | count += 1 | ||
LL | | } | ||
| |_____^ help: try replacing the loop by: `dst[3..src.len()].clone_from_slice(&src[..(src.len() - 3)]);` | ||
|
||
error: aborting due to 11 previous errors | ||
|
File renamed without changes.
Oops, something went wrong.