rust-clippy icon indicating copy to clipboard operation
rust-clippy copied to clipboard

`needless_range_loop` False positive when double indexing

Open MarkusSvedberg opened this issue 2 years ago • 5 comments

Summary

When using the a range to index twice into a slice, clippy detects a needless_range_loop, even though the alternative is more verbose and less readable.

Lint Name

needless_range_loop

Reproducer

I tried this code:

let mut matrix = [[0; 5]; 5];           
for i in 0..5 {
        matrix[i][i] = 1;
}

Clippy suggests the following solution:

let mut matrix = [[0; 5]; 5];           
for (i, row) in matrix.iter_mut().enumerate() {
        row[i] = 1;
}

I expected to see this happen: No lint, since the clippy suggested solution is more verbose and decreases readability

Version

rustc 1.71.0 (8ede3aae2 2023-07-12)
binary: rustc
commit-hash: 8ede3aae28fe6e4d52b38157d7bfe0d3bceef225
commit-date: 2023-07-12
host: x86_64-apple-darwin
release: 1.71.0
LLVM version: 16.0.5

Additional Labels

No response

MarkusSvedberg avatar Sep 18 '23 09:09 MarkusSvedberg

@rustbot claim

granddaifuku avatar Dec 28 '23 07:12 granddaifuku

I have 1 more example of wrong clippy for this. When I need only same column values.

let values = [[0; 4]; 4];
let col = 2;
for i in 0..4 {
    values[i][col];
}

clippy suggests me to do

for i in values.iter().take(4) {
....

This is wrong cause using iter I don't get correct values.

chetankhilosiya avatar Dec 30 '23 20:12 chetankhilosiya

From image we have on more example that started to produce this lint:

let mut colors = [[0; 3]; 4];

// …

for i in 0..3 {                                                                                          
    colors[2][i] = ((u16::from(colors[0][i]) * 2 + u16::from(colors[1][i]) + 1) / 3) as u8;
    colors[3][i] = ((u16::from(colors[0][i]) + u16::from(colors[1][i]) * 2 + 1) / 3) as u8;
}                                                                                                       
    |
222 -         for i in 0..3 {
222 +         for <item> in colors.iter_mut().take(3) {

This obviously won't work, we're indexing into colors[0] and colors[1] separately.

197g avatar Sep 10 '25 12:09 197g

I'm getting this lint error with the following code:

for j in 0..color_bytes {
    pixels[i][j] = pixels[prev][j];
}

This definitely seems like a false positive. I can't see any better way to write this myself.

andrews05 avatar Sep 19 '25 21:09 andrews05

This lint is triggering on this code:

        for i in 0..66 {
            self.data[0x0f8c + i] = snes_data[5][i];
        }

Clippy seems to think this is going to work:

warning: the loop variable `i` is used to index `snes_data`
    --> src/autosplitters/supermetroid.rs:1752:18
     |
1752 |         for i in 0..66 {
     |                  ^^^^^
     |
     = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.91.0/index.html#needless_range_loop
help: consider using an iterator and enumerate()
     |
1752 -         for i in 0..66 {
1752 +         for (i, <item>) in snes_data.iter().enumerate().take(66) {
     |

The code would have to look like this:

        for (i, snes_data) in snes_data[5].iter().enumerate().take(66) {
            self.data[0x0f8c + i] = *snes_data;
        }

Notice I'm indexing snes_data before the call to iter().

dagit avatar Dec 02 '25 22:12 dagit