clippy::if_let_some_result suggests changing while to if, resulting in code with different behaviour · Issue #7586 · rust-lang/rust-clippy (original) (raw)

Lint name: if_let_some_result

I tried this code:

struct Wat { counter: i32, }

impl Wat { fn next(&mut self) -> Result<i32, &str> { self.counter += 1; if self.counter < 5 { Ok(self.counter) } else { Err("Oh no") } } }

fn main() { let mut wat = Wat { counter: 0 }; while let Some(a) = wat.next().ok() { dbg!(&a); } }

When you run the above code, you get:

cargo run
   Compiling whilelet v0.1.0 (/home/dllu/snippets/whilelet)
    Finished dev [unoptimized + debuginfo] target(s) in 0.38s
     Running `target/debug/whilelet`
[src/main.rs:19] &a = 1
[src/main.rs:19] &a = 2
[src/main.rs:19] &a = 3
[src/main.rs:19] &a = 4

I expected to see this happen: while let Ok(a) = wat.next()

Instead, this happened: if let Ok(a) = wat.next()

cargo +nightly clippy -Z unstable-options
    Checking whilelet v0.1.0 (/home/dllu/snippets/whilelet)
warning: matching on `Some` with `ok()` is redundant
  --> src/main.rs🔞5
   |
18 |     while let Some(a) = wat.next().ok() {
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: `#[warn(clippy::if_let_some_result)]` on by default
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#if_let_some_result
help: consider matching on `Ok(a)` and removing the call to `ok` instead
   |
18 |     if let Ok(a) = wat.next() {
   |     ~~~~~~~~~~~~~~~~~~~~~~~~~

warning: `whilelet` (bin "whilelet") generated 1 warning
    Finished dev [unoptimized + debuginfo] target(s) in 0.18s

This is quite dangerous because if you run --fix, you will get code with different behaviour!!!

> cargo +nightly clippy -Z unstable-options --fix
    Checking whilelet v0.1.0 (/home/dllu/snippets/whilelet)
       Fixed src/main.rs (1 fix)
    Finished dev [unoptimized + debuginfo] target(s) in 0.29s
> cargo run
   Compiling whilelet v0.1.0 (/home/dllu/snippets/whilelet)
    Finished dev [unoptimized + debuginfo] target(s) in 0.37s
     Running `target/debug/whilelet`
[src/main.rs:19] &a = 1

Meta

rustc 1.56.0-nightly (30a0a9b69 2021-08-17)
binary: rustc
commit-hash: 30a0a9b694cde95cbab863f7ef4d554f0f46b606
commit-date: 2021-08-17
host: x86_64-unknown-linux-gnu
release: 1.56.0-nightly
LLVM version: 12.0.1