rust-lang / rust-lang/rust-clippy

Incorrect suggestion by `useless_let_if_seq` lint

Open
#2,918 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

C-bug I-suggestion-causes-error L-suggestion
Dominant language
Rust
Stars
13.5k
Forks
2.2k
Avg merge
2d 10h
Merged PRs (30d)
32

Description

Hi,

Given the following code:

fn test(idx: usize) -> bool {
    idx % 2 == 0
}

fn algo(mut x: usize, y: usize, height: usize, width: usize) {
    let mut last_row_length = 0;
    let mut sx = x;

    if last_row_length != 0 && test(y * width + x) {
        loop {
            last_row_length -= 1;
            if last_row_length == 0 {
                return;
            }
            x += 1;
            if !test(y * width + x) {
                break;
            }
        }
        sx = x;
    } else {
        while x != 0 && !test(y * width + x - 1) {
            x -= 1;

            if y != 0 && !test((y - 1) * width + x) {
                algo(x, y - 1, width, height);
            }

            last_row_length += 1;
        }
    }
    
    println!("{}", sx);
}

clippy suggests the following:

warning: `if _ { .. } else { .. }` is an expression
  --> src/main.rs:7:5
   |
7  | /     let mut sx = x;
8  | |
9  | |     if last_row_length != 0 && test(y * width + x) {
10 | |         loop {
...  |
30 | |         }
31 | |     }
   | |_____^ help: it is more idiomatic to write: `let <mut> sx = if last_row_length != 0 && test(y * width + x) { ..; x } else { ..; x };`
   |
   = note: #[warn(useless_let_if_seq)] on by default
   = note: you might not need `mut` at all
   = help: for further information visit https://rust-lang-nursery.github.io/rust-clippy/v0.0.212/index.html#useless_let_if_seq

This is incorrect, since x is modified in the loop in the else path, but NOT assigned to sx.

(Playground link)

(Note: the code itself is not the most idiomatic, since I'm transcribing an algorithm from another language...)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the diagnostic using the src/main.rs example and the linked Playground, then start from the useless_let_if_seq lint entry point. Check the suggested transformation against the differing x and sx values in both branches; it is done when the lint no longer proposes a transformation that changes the program's result.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.