Skip to content
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

Simplify manual_memcpy suggestion in some cases #3323

Merged
merged 1 commit into from
Oct 18, 2018

Conversation

pengowen123
Copy link
Contributor

Checking whether the entire source slice is copied is difficult, but this should catch common cases.
Fixes #3004

if let BinOpKind::Add = op.node;
then {
if let Some(left) = sugg::Sugg::hir_opt(cx, left) {
if left.to_string() == offset.value {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not too happy about the to_string() + comparison.

The other changes in this PR are great, but I'd prefer to postpone this entire if_chain until we have a proper expression minifier/optimizer

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed it, but this makes the 0..src.len() check below useless until the expression minifier is implemented. Should I remove that as well?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh... I guess, no need to keep around currently dead code

let mut dst = [0, 0, 0, 0, 0, 0];
let from = 1;

for i in from..from + src.len() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also add a test for values other than src.len(). I think your PR will also improve the suggestion in that case

@pengowen123
Copy link
Contributor Author

@oli-obk Sorry, I forgot to notify you that I removed the dead code. The PR should be good to go unless you have more comments.

@oli-obk oli-obk merged commit 1264bb6 into rust-lang:master Oct 18, 2018
@oli-obk
Copy link
Contributor

oli-obk commented Oct 18, 2018

Thanks!

@pengowen123 pengowen123 deleted the fix_manual_memcpy branch October 18, 2018 14:22
bors added a commit that referenced this pull request May 2, 2020
Fix the bugs of `manual_memcpy`, simplify the suggestion and refactor it

While I’m working on the long procrastinated work to expand `manual_memcpy`(#1670), I found a few minor bugs and probably unidiomatic or old coding style. There is a brief explanation of changes to the behaviour this PR will make below. And, I have a questoin: do I need to add tests for the first and second fixed bugs? I thought it might be too rare cases to include the tests for those. I added for the last one though.

* Bug fix
  * It negates resulted offsets (`src/dst_offset`) when `offset` is subtraction by 0. This PR will remove any subtraction by 0 as a part of minification.

    ```rust
    for i in 0..5 {
        dst[i - 0] = src[i];
    }
    ```

    ```diff
     warning: it looks like you're manually copying between slices
       --> src/main.rs:2:14
        |
    LL  |     for i in 0..5 {
    -   |              ^^^^ help: try replacing the loop by: `dst[..-5].clone_from_slice(&src[..5])`
    +   |              ^^^^ help: try replacing the loop by: `dst[..5].clone_from_slice(&src[..5])`
        |
    ```
  * It prints `RangeTo` or `RangeFull` when both of `end` and `offset` are 0, which have different meaning. This PR will print 0. I could reject the cases `end` is 0, but I thought I won’t catch other cases `reverse_range_loop` will trigger, and it’s over to catch every such cases.

    ```rust
    for i in 0..0 {
        dst[i] = src[i];
    }
    ```

    ```diff
     warning: it looks like you're manually copying between slices
       --> src/main.rs:2:14
        |
     LL |     for i in 0..0 {
    -   |              ^^^^ help: try replacing the loop by: `dst.clone_from_slice(&src[..])`
    +   |              ^^^^ help: try replacing the loop by: `dst[..0].clone_from_slice(&src[..0])`
        |
    ```
  * it prints four dots when `end` is `None`. This PR will ignore any `for` loops without `end` because a `for` loop that takes `RangeFrom` as its argument and contains indexing without the statements or the expressions that end loops such as `break` will definitely panic, and `manual_memcpy` should ignore the loops with such control flow.

    ```rust
    fn manual_copy(src: &[u32], dst: &mut [u32]) {
        for i in 0.. {
            dst[i] = src[i];
        }
    }
    ```

    ```diff
    -warning: it looks like you're manually copying between slices
    -  --> src/main.rs:2:14
    -   |
    -LL |     for i in 0.. {
    -   |              ^^^ help: try replacing the loop by: `dst[....].clone_from_slice(&src[....])`
    -   |
    ```
* Simplification of the suggestion

  * It prints 0 when `start` or `end` and `offset` are same (from #3323). This PR will use `RangeTo`

changelog: fixed the bugs of `manual_memcpy` and also simplify the suggestion.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants