-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement basic lint detecting manual slice copy #1937
Implement basic lint detecting manual slice copy #1937
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an absolutely awesome lint. Could you also add some nearly slice copies to the tests that should not be linted about? Just to make sure we don't have any false positives or introduce any in the future.
clippy_lints/src/loops.rs
Outdated
/// **Why is this bad?** It is not as fast as a memcpy. | ||
/// | ||
/// **Known problems:** The lint assumes the data structure being indexed is | ||
/// slice-like and will produce false positives when it is not. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What properties of slice are required? Can we simply check whether one of the following is true
- The type impls
Deref<Target=[T]>
- The type impls
Index<usize>
and has alen
method
@@ -83,7 +103,8 @@ declare_lint! { | |||
/// implements `IntoIterator`, so that possibly one value will be iterated, | |||
/// leading to some hard to find bugs. No one will want to write such code | |||
/// [except to win an Underhanded Rust | |||
/// Contest](https://www.reddit.com/r/rust/comments/3hb0wm/underhanded_rust_contest/cu5yuhr). | |||
/// Contest](https://www.reddit. | |||
/// com/r/rust/comments/3hb0wm/underhanded_rust_contest/cu5yuhr). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I ran rustfmt on master, so you can just rebase over master in order to separate the rustfmt changes from your actual changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you sure this affected the clippy_lints
directory as well? In my experience, cargo fmt
does not touch these by default..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have a script which runs recursively
tests/ui/for_loop.stderr
Outdated
408 | / for i in 11..src.len() { | ||
409 | | dst[i] = src[i - 10]; | ||
410 | | } | ||
| |_____^ help: try replacing the loop by: `dst[11..].clone_from_slice(&src[(11 + -10)..(src.len() + -10)])` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should not produce output like a + -b
, can you try to detect this situation, as it seems to be rather common.
tests/ui/for_loop.stderr
Outdated
427 | | dst[i] = src[i - 5]; | ||
428 | | dst2[i + 500] = src[i] | ||
429 | | } | ||
| |_____^ help: try replacing the loop by: `dst[10..].clone_from_slice(&src[(10 + -5)..(256 + -5)])` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as above.
2b18964
to
e9991c7
Compare
Updated the PR! |
d397075
to
3eec23b
Compare
clippy_lints/src/loops.rs
Outdated
let is_slice = match ty.sty { | ||
ty::TyRef(_, ref subty) => is_slice_like(cx, subty.ty), | ||
ty::TySlice(..) => true, | ||
ty::TyArray(..) => true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rewrite as
ty::TySlice(..) | ty::TyArray(..) => true,
(this was caught by travis. You can check such things yourself by running cargo test dogfood
)
clippy_lints/src/loops.rs
Outdated
// "try replacing the loop by", | ||
// format!("{}.clone_from_slice(&{}[{}..{}])", dst, src_var.var_name, | ||
// src_offset, src_limit), | ||
// ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove the commented out code.
clippy_lints/src/loops.rs
Outdated
}) | ||
.join("\n "); | ||
|
||
if big_sugg.len() > 0 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you create a test that shows this with multiple suggestions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also, replace it with !big_sugg.is_empty()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is such a test already :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh... why didn't a test change after your changes then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was in there from the start. The test output did change, though.
This should make it play more nicely with tools like rustfix.
3eec23b
to
748e8c6
Compare
| | ||
help: try replacing the loop by | ||
| | ||
426 | dst[10..].clone_from_slice(&src[(10 - 5)..(256 - 5)]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the test I was referring to.
Thanks for the review @oli-obk! After a more detailed inspection of the documentation on I'll update this PR shortly. |
I screwed up even more (I forgot to push the changes!). Please rebase over master now. If you want I can do the rebase, just ping me. Sorry about the trouble. |
Fix verbose_bit_mask off by one error
This should make it play more nicely with tools like rustfix.
Hey @oli-obk - I'm still getting many style conflicts :-( What command are you using to do the reformat? |
@marcusklaas you seem to have included my commits in your PR now. I'm not sure how that happened. Try rebasing over the master branch.
|
Note that there may be differences between "stable" rustfmt and rustfmt-nightly. |
Our current code base is formatted with stable rustfmt. We could move to rustfmt-nighty. It's not like anyone building clippy doesn't have a nightly lying around somewhere |
This PR is a mess. #2021 is a clean new PR. |
This lint detects manual sequential memory copies between slices.
Should address #1831.