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

False positive on loop variable being used to index a slice #5625

Closed
dave-andersen opened this issue May 20, 2020 · 2 comments
Closed

False positive on loop variable being used to index a slice #5625

dave-andersen opened this issue May 20, 2020 · 2 comments

Comments

@dave-andersen
Copy link

Clippy's needless range loop is false positiving on a case where the iteration may stop before the end of the loop, i.e.

   let stop_point = min( thing.len(), some_other_thing );
   for i in 0..stop_point {
     do something with thing[i]
     do something with i
   }

The code could be transformed to take a new slice of thing and then use enumerate, but it's not really clear it would be an improvement -- and it's a somewhat nontrivial change.

clippy 0.0.212 (99cb9ccb9 2020-05-11)

Clippy output:

warning: the loop variable `i` is used to index `searchkey`
   --> src/main.rs:184:18
    |
184 |         for i in 0..skl {
    |                  ^^^^^^

Code:

   fn key_compare(&self, start_pos: usize, searchkey: &[u8]) -> core::cmp::Ordering {
        let skl = std::cmp::min(searchkey.len(), self.num_digits() - start_pos);
        let default_return = if skl < searchkey.len() {
            core::cmp::Ordering::Less
        } else {
            core::cmp::Ordering::Equal
        };
        for i in 0..skl {
            let da = self.digit_at(i + start_pos);
            if da < searchkey[i] {
                return core::cmp::Ordering::Less;
            } else if da > searchkey[i] {
                return core::cmp::Ordering::Greater;
            }
        }
        default_return
    }

@flip1995
Copy link
Member

Complete message:

warning: the loop variable `i` is used to index `searchkey`
  --> src/main.rs:15:14
   |
15 |     for i in 0..skl {
   |              ^^^^^^
   |
   = note: `#[warn(clippy::needless_range_loop)]` on by default
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_range_loop
help: consider using an iterator
   |
15 |     for (i, <item>) in searchkey.iter().enumerate().take(skl) {
   |         ^^^^^^^^^^^    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The suggested code is semantically equivalent and makes use of iterators. So exactly what the lint should detect. The improvement is to have more idiomatic code, since using iterators over ranges+indexing is the rusty way.

What am I missing?

@dave-andersen
Copy link
Author

I guess it's style - which means we should probably close this bug. Because 'i' is already being used to index a different thing (but in basically the same way), it feels less clear to me, but that could just be my C brain being dumb. What I don't like about it is that by separating the values of i and the limit set by 'skl', it makes it less clear that the dereference using i :

self.digit_at(i + start_pos);

follows the bound that i < skl. But, I agree that it's not a false positive if there's stylistic consensus about the enumerate+take version being more Rusty!

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

No branches or pull requests

2 participants