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

clippy::if_let_some_result suggests changing while to if, resulting in code with different behaviour #7586

Closed
dllu opened this issue Aug 18, 2021 · 6 comments · Fixed by rust-lang/rust#88163
Assignees
Labels
C-bug Category: Clippy is not doing the correct thing I-false-positive Issue: The lint was triggered on code it shouldn't have

Comments

@dllu
Copy link

dllu commented Aug 18, 2021

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:18: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

  • cargo clippy -V: clippy 0.1.56 (30a0a9b 2021-08-17)
  • rustc -Vv:
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
@dllu dllu added C-bug Category: Clippy is not doing the correct thing I-false-positive Issue: The lint was triggered on code it shouldn't have labels Aug 18, 2021
@dllu
Copy link
Author

dllu commented Aug 18, 2021

haha @JohnTitor I guess you were right when you said #5032 that

This approach may be fragile though...

@dswij
Copy link
Member

dswij commented Aug 19, 2021

I suppose the name of the lint should be changed then? Something like let_some_result?

@xFrednet
Copy link
Member

xFrednet commented Aug 19, 2021

@camsteffen Do you think that this is also a regression bug from rust-lang/rust#80357? It looks similar to #7575 that you're fixing in rust-lang/rust#88163

@camsteffen
Copy link
Contributor

Indeed. Let me see if I can throw in a fix for that too. I think we can check for desugaring in higher::IfLet.

camsteffen added a commit to camsteffen/rust that referenced this issue Aug 19, 2021
…=Manishearth

Fix clippy::collapsible_match with let expressions

This fixes rust-lang/rust-clippy#7575 which is a regression from rust-lang#80357. I am fixing the bug here instead of in the clippy repo (if that's okay) because a) the regression has not been synced yet and b) I would like to land the fix on nightly asap.

The fix is basically to re-generalize `match` and `if let` for the lint implementation (they were split because `if let` no longer desugars to `match` in the HIR).

Also fixes rust-lang/rust-clippy#7586
cc `@rust-lang/clippy`
`@xFrednet` do you want to review this?
@dllu
Copy link
Author

dllu commented Aug 23, 2021

Thanks for fixing. However I was hoping that Clippy would correct

    while let Some(a) = wat.next().ok() {

to

    while let Ok(a) = wat.next() {

but now it seems that it simply does not raise any warnings for this code. Would it be possible to add that, or is that out of the scope of if_let_some_result? Should there be a while_let_some_result?

@camsteffen
Copy link
Contributor

I think that could be an enhancement to if_let_some_result. Do you mind opening another issue for that?

flip1995 pushed a commit to flip1995/rust-clippy that referenced this issue Aug 26, 2021
Fix clippy::collapsible_match with let expressions

This fixes rust-lang#7575 which is a regression from #80357. I am fixing the bug here instead of in the clippy repo (if that's okay) because a) the regression has not been synced yet and b) I would like to land the fix on nightly asap.

The fix is basically to re-generalize `match` and `if let` for the lint implementation (they were split because `if let` no longer desugars to `match` in the HIR).

Also fixes rust-lang#7586 and fixes rust-lang#7591
cc `@rust-lang/clippy`
`@xFrednet` do you want to review this?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: Clippy is not doing the correct thing I-false-positive Issue: The lint was triggered on code it shouldn't have
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants