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

await_holding_lock reports explicitly dropped mutex guards as if they weren't dropped

Open jazeved0 opened this issue 4 years ago • 5 comments

I tried this code:

#[deny(clippy::pedantic)]
pub async fn doesnt_work() {
    use std::collections::HashSet;
    use std::sync::Mutex;
    use std::time::Duration;

    let lock: Mutex<HashSet<u8>> = Mutex::new(HashSet::new());
    let mut set = lock.lock().unwrap();
    set.insert(0);
    drop(set);
    tokio::time::sleep(Duration::from_secs(1)).await;
}

I expected to see this happen: it should pass Clippy with no linting errors because the MutexGuard is explicitly dropped before the await point with a call to std::mem::drop.

Instead, this happened: Clippy failed the lint check because of a violation of clippy::await_holding_lock:

$ cargo clippy
...
error: this MutexGuard is held across an 'await' point. Consider using an async-aware Mutex type or ensuring the MutexGuard is dropped before calling await.
  --> src/lib.rs:8:9
   |
8  |     let mut set = lock.lock().unwrap();
   |         ^^^^^^^
   |
note: the lint level is defined here
  --> src/lib.rs:1:8
   |
1  | #[deny(clippy::pedantic)]
   |        ^^^^^^^^^^^^^^^^
   = note: `#[deny(clippy::await_holding_lock)]` implied by `#[deny(clippy::pedantic)]`
note: these are all the await points this lock is held through
  --> src/lib.rs:8:5
   |
8  | /     let mut set = lock.lock().unwrap();
9  | |     set.insert(0);
10 | |     drop(set);
11 | |     tokio::time::sleep(Duration::from_secs(1)).await;
12 | | }
   | |_^
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#await_holding_lock

error: aborting due to previous error

Running with --verbose does not provide any additional information.

Additionally, of note, the following code does pass Clippy:

#[deny(clippy::pedantic)]
pub async fn does_work() {
    use std::collections::HashSet;
    use std::sync::Mutex;
    use std::time::Duration;

    let lock: Mutex<HashSet<u8>> = Mutex::new(HashSet::new());
    {
        let mut set = lock.lock().unwrap();
        set.insert(0);
    }
    tokio::time::sleep(Duration::from_secs(1)).await;
}

Meta

  • cargo clippy -V: clippy 0.0.212 (7eac88a 2020-11-16)
  • rustc -Vv:
    rustc 1.48.0 (7eac88abb 2020-11-16)
    binary: rustc
    commit-hash: 7eac88abb2e57e752f3302f02be5f3ce3d7adfb4
    commit-date: 2020-11-16
    host: x86_64-unknown-linux-gnu
    release: 1.48.0
    LLVM version: 11.0
    
Backtrace

$ RUST_BACKTRACE=1 cargo clippy
    Checking bug_report v0.1.0 (/home/jazev/dev/architus/logs/bug_report)
error: this MutexGuard is held across an 'await' point. Consider using an async-aware Mutex type or 
ensuring the MutexGuard is dropped before calling await.
  --> src/lib.rs:8:9
   |
8  |     let mut set = lock.lock().unwrap();
   |         ^^^^^^^
   |
note: the lint level is defined here
  --> src/lib.rs:1:8
   |
1  | #[deny(clippy::pedantic)]
   |        ^^^^^^^^^^^^^^^^
   = note: `#[deny(clippy::await_holding_lock)]` implied by `#[deny(clippy::pedantic)]`
note: these are all the await points this lock is held through
  --> src/lib.rs:8:5
   |
8  | /     let mut set = lock.lock().unwrap();
9  | |     set.insert(0);
10 | |     drop(set);
11 | |     tokio::time::sleep(Duration::from_secs(1)).await;
12 | | }
   | |_^
   = help: for further information visit https://rust-lang.github.io/rust- 
clippy/master/index.html#await_holding_lock

error: aborting due to previous error

error: could not compile `bug_report`

To learn more, run the command again with --verbose.

jazeved0 avatar Dec 12 '20 18:12 jazeved0