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

Lint incorrectly fires when an anoymous mutex guard is used in a block inside an if..let statement #9209

Closed
peterjoel opened this issue Jul 19, 2022 · 2 comments
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

@peterjoel
Copy link

peterjoel commented Jul 19, 2022

Summary

The code below can be fixed by adding a local binding. But this looks to me like Clippy has misunderstood the flow of data.

if let Some(local_id) = {
    let ids = self.ids.read().unwrap();
    let x = ids.get(&uid).cloned();
    x
} {

Lint Name

await_holding_lock

Reproducer

I tried this code:

use std::collections::*;
use std::sync::*;

pub struct Foo {
    ids: Arc<RwLock<HashMap<u64, String>>>,
}

impl Foo {
    pub async fn convert(&self, uid: u64) -> anyhow::Result<String> {
        if let Some(local_id) = {
            let ids = self.ids.read().unwrap();
            ids.get(&uid).cloned()
        } {
            Ok(local_id)
        } else {
            let stored_id = tokio::task::spawn_blocking(move || uid.to_string()).await?;
            let mut ids = self.ids.write().unwrap();
            ids.insert(uid, stored_id.clone());
            Ok(stored_id)
        }
    }
}

I saw this happen:

warning: this `MutexGuard` is held across an `await` point
  --> src/lib.rs:12:13
   |
12 |             ids.get(&uid).cloned()
   |             ^^^
   |
   = note: `#[warn(clippy::await_holding_lock)]` on by default
   = help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling await
note: these are all the `await` points this lock is held through
  --> src/lib.rs:9:69
   |
9  |       pub async fn convert(&self, uid: u64) -> anyhow::Result<String> {
   |  _____________________________________________________________________^
10 | |         if let Some(local_id) = {
11 | |             let ids = self.ids.read().unwrap();
12 | |             ids.get(&uid).cloned()
...  |
20 | |         }
21 | |     }
   | |_____^
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#await_holding_lock

warning: `playground` (lib) generated 1 warning

I expected to see this happen:

I did not expect to see an error because the guard returned from self.ids.read() (id) is dropped at the end of the block which is part of the if statement.

Version

rustc 1.62.0 (a8314ef7d 2022-06-27)
binary: rustc
commit-hash: a8314ef7d0ec7b75c336af2c9857bfaf43002bfc
commit-date: 2022-06-27
host: x86_64-unknown-linux-gnu
release: 1.62.0
LLVM version: 14.0.5

Additional Labels

No response

@peterjoel peterjoel 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 Jul 19, 2022
@peterjoel
Copy link
Author

This may be the same issue as #9208 but it feels a little bit different so I'm logging it additionally just in case.

@peterjoel
Copy link
Author

This appears to be a duplicate of #8777.

@peterjoel peterjoel closed this as not planned Won't fix, can't repro, duplicate, stale Jul 20, 2022
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

No branches or pull requests

1 participant