Actually lint parking_lot in await_holding_lock

This adapts the paths for the parking_lot mutex guards, so that
parking_lot mutexes and RwLocks actually get linted. This is now also
tested.
This commit is contained in:
flip1995 2022-02-12 10:32:44 +01:00
parent cdf9a28006
commit c4944fb60d
No known key found for this signature in database
GPG key ID: 1CA0DF2AF59D68A5
3 changed files with 333 additions and 149 deletions

View file

@ -105,9 +105,9 @@ pub const OS_STRING_AS_OS_STR: [&str; 5] = ["std", "ffi", "os_str", "OsString",
pub const OS_STR_TO_OS_STRING: [&str; 5] = ["std", "ffi", "os_str", "OsStr", "to_os_string"];
pub const PARKING_LOT_RAWMUTEX: [&str; 3] = ["parking_lot", "raw_mutex", "RawMutex"];
pub const PARKING_LOT_RAWRWLOCK: [&str; 3] = ["parking_lot", "raw_rwlock", "RawRwLock"];
pub const PARKING_LOT_MUTEX_GUARD: [&str; 2] = ["parking_lot", "MutexGuard"];
pub const PARKING_LOT_RWLOCK_READ_GUARD: [&str; 2] = ["parking_lot", "RwLockReadGuard"];
pub const PARKING_LOT_RWLOCK_WRITE_GUARD: [&str; 2] = ["parking_lot", "RwLockWriteGuard"];
pub const PARKING_LOT_MUTEX_GUARD: [&str; 3] = ["lock_api", "mutex", "MutexGuard"];
pub const PARKING_LOT_RWLOCK_READ_GUARD: [&str; 3] = ["lock_api", "rwlock", "RwLockReadGuard"];
pub const PARKING_LOT_RWLOCK_WRITE_GUARD: [&str; 3] = ["lock_api", "rwlock", "RwLockWriteGuard"];
pub const PATH_BUF_AS_PATH: [&str; 4] = ["std", "path", "PathBuf", "as_path"];
pub const PATH_TO_PATH_BUF: [&str; 4] = ["std", "path", "Path", "to_path_buf"];
pub const PERMISSIONS: [&str; 3] = ["std", "fs", "Permissions"];

View file

@ -1,88 +1,178 @@
#![warn(clippy::await_holding_lock)]
use std::sync::{Mutex, RwLock};
// When adding or modifying a test, please do the same for parking_lot::Mutex.
mod std_mutex {
use std::sync::{Mutex, RwLock};
async fn bad(x: &Mutex<u32>) -> u32 {
let guard = x.lock().unwrap();
baz().await
}
async fn good(x: &Mutex<u32>) -> u32 {
{
pub async fn bad(x: &Mutex<u32>) -> u32 {
let guard = x.lock().unwrap();
let y = *guard + 1;
baz().await
}
baz().await;
let guard = x.lock().unwrap();
47
}
pub async fn bad_rw(x: &RwLock<u32>) -> u32 {
let guard = x.read().unwrap();
baz().await
}
pub async fn good(x: &Mutex<u32>) -> u32 {
{
let guard = x.lock().unwrap();
let y = *guard + 1;
}
baz().await;
let guard = x.lock().unwrap();
47
}
pub async fn bad_rw_write(x: &RwLock<u32>) -> u32 {
let mut guard = x.write().unwrap();
baz().await
}
pub async fn good_rw(x: &RwLock<u32>) -> u32 {
{
pub async fn bad_rw(x: &RwLock<u32>) -> u32 {
let guard = x.read().unwrap();
let y = *guard + 1;
baz().await
}
{
pub async fn bad_rw_write(x: &RwLock<u32>) -> u32 {
let mut guard = x.write().unwrap();
*guard += 1;
baz().await
}
baz().await;
let guard = x.read().unwrap();
47
}
async fn baz() -> u32 {
42
}
pub async fn good_rw(x: &RwLock<u32>) -> u32 {
{
let guard = x.read().unwrap();
let y = *guard + 1;
}
{
let mut guard = x.write().unwrap();
*guard += 1;
}
baz().await;
let guard = x.read().unwrap();
47
}
async fn also_bad(x: &Mutex<u32>) -> u32 {
let first = baz().await;
pub async fn baz() -> u32 {
42
}
let guard = x.lock().unwrap();
pub async fn also_bad(x: &Mutex<u32>) -> u32 {
let first = baz().await;
let second = baz().await;
let third = baz().await;
first + second + third
}
async fn not_good(x: &Mutex<u32>) -> u32 {
let first = baz().await;
let second = {
let guard = x.lock().unwrap();
baz().await
};
let third = baz().await;
let second = baz().await;
first + second + third
let third = baz().await;
first + second + third
}
pub async fn not_good(x: &Mutex<u32>) -> u32 {
let first = baz().await;
let second = {
let guard = x.lock().unwrap();
baz().await
};
let third = baz().await;
first + second + third
}
#[allow(clippy::manual_async_fn)]
pub fn block_bad(x: &Mutex<u32>) -> impl std::future::Future<Output = u32> + '_ {
async move {
let guard = x.lock().unwrap();
baz().await
}
}
}
#[allow(clippy::manual_async_fn)]
fn block_bad(x: &Mutex<u32>) -> impl std::future::Future<Output = u32> + '_ {
async move {
let guard = x.lock().unwrap();
// When adding or modifying a test, please do the same for std::Mutex.
mod parking_lot_mutex {
use parking_lot::{Mutex, RwLock};
pub async fn bad(x: &Mutex<u32>) -> u32 {
let guard = x.lock();
baz().await
}
pub async fn good(x: &Mutex<u32>) -> u32 {
{
let guard = x.lock();
let y = *guard + 1;
}
baz().await;
let guard = x.lock();
47
}
pub async fn bad_rw(x: &RwLock<u32>) -> u32 {
let guard = x.read();
baz().await
}
pub async fn bad_rw_write(x: &RwLock<u32>) -> u32 {
let mut guard = x.write();
baz().await
}
pub async fn good_rw(x: &RwLock<u32>) -> u32 {
{
let guard = x.read();
let y = *guard + 1;
}
{
let mut guard = x.write();
*guard += 1;
}
baz().await;
let guard = x.read();
47
}
pub async fn baz() -> u32 {
42
}
pub async fn also_bad(x: &Mutex<u32>) -> u32 {
let first = baz().await;
let guard = x.lock();
let second = baz().await;
let third = baz().await;
first + second + third
}
pub async fn not_good(x: &Mutex<u32>) -> u32 {
let first = baz().await;
let second = {
let guard = x.lock();
baz().await
};
let third = baz().await;
first + second + third
}
#[allow(clippy::manual_async_fn)]
pub fn block_bad(x: &Mutex<u32>) -> impl std::future::Future<Output = u32> + '_ {
async move {
let guard = x.lock();
baz().await
}
}
}
fn main() {
let m = Mutex::new(100);
good(&m);
bad(&m);
also_bad(&m);
not_good(&m);
block_bad(&m);
let m = std::sync::Mutex::new(100);
std_mutex::good(&m);
std_mutex::bad(&m);
std_mutex::also_bad(&m);
std_mutex::not_good(&m);
std_mutex::block_bad(&m);
let m = parking_lot::Mutex::new(100);
parking_lot_mutex::good(&m);
parking_lot_mutex::bad(&m);
parking_lot_mutex::also_bad(&m);
parking_lot_mutex::not_good(&m);
}

View file

@ -1,97 +1,191 @@
error: this `MutexGuard` is held across an `await` point
--> $DIR/await_holding_lock.rs:6:9
--> $DIR/await_holding_lock.rs:8:13
|
LL | let guard = x.lock().unwrap();
| ^^^^^
LL | let guard = x.lock().unwrap();
| ^^^^^
|
= note: `-D clippy::await-holding-lock` implied by `-D warnings`
= 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
--> $DIR/await_holding_lock.rs:6:5
|
LL | / let guard = x.lock().unwrap();
LL | | baz().await
LL | | }
| |_^
error: this `MutexGuard` is held across an `await` point
--> $DIR/await_holding_lock.rs:21:9
|
LL | let guard = x.read().unwrap();
| ^^^^^
|
= 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
--> $DIR/await_holding_lock.rs:21:5
|
LL | / let guard = x.read().unwrap();
LL | | baz().await
LL | | }
| |_^
error: this `MutexGuard` is held across an `await` point
--> $DIR/await_holding_lock.rs:26:9
|
LL | let mut guard = x.write().unwrap();
| ^^^^^^^^^
|
= 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
--> $DIR/await_holding_lock.rs:26:5
|
LL | / let mut guard = x.write().unwrap();
LL | | baz().await
LL | | }
| |_^
error: this `MutexGuard` is held across an `await` point
--> $DIR/await_holding_lock.rs:51:9
|
LL | let guard = x.lock().unwrap();
| ^^^^^
|
= 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
--> $DIR/await_holding_lock.rs:51:5
|
LL | / let guard = x.lock().unwrap();
LL | |
LL | | let second = baz().await;
LL | |
... |
LL | | first + second + third
LL | | }
| |_^
error: this `MutexGuard` is held across an `await` point
--> $DIR/await_holding_lock.rs:64:13
|
LL | let guard = x.lock().unwrap();
| ^^^^^
|
= 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
--> $DIR/await_holding_lock.rs:64:9
|
LL | / let guard = x.lock().unwrap();
LL | | baz().await
LL | | };
| |_____^
error: this `MutexGuard` is held across an `await` point
--> $DIR/await_holding_lock.rs:76:13
|
LL | let guard = x.lock().unwrap();
| ^^^^^
|
= 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
--> $DIR/await_holding_lock.rs:76:9
--> $DIR/await_holding_lock.rs:8:9
|
LL | / let guard = x.lock().unwrap();
LL | | baz().await
LL | | }
| |_____^
error: aborting due to 6 previous errors
error: this `MutexGuard` is held across an `await` point
--> $DIR/await_holding_lock.rs:23:13
|
LL | let guard = x.read().unwrap();
| ^^^^^
|
= 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
--> $DIR/await_holding_lock.rs:23:9
|
LL | / let guard = x.read().unwrap();
LL | | baz().await
LL | | }
| |_____^
error: this `MutexGuard` is held across an `await` point
--> $DIR/await_holding_lock.rs:28:13
|
LL | let mut guard = x.write().unwrap();
| ^^^^^^^^^
|
= 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
--> $DIR/await_holding_lock.rs:28:9
|
LL | / let mut guard = x.write().unwrap();
LL | | baz().await
LL | | }
| |_____^
error: this `MutexGuard` is held across an `await` point
--> $DIR/await_holding_lock.rs:53:13
|
LL | let guard = x.lock().unwrap();
| ^^^^^
|
= 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
--> $DIR/await_holding_lock.rs:53:9
|
LL | / let guard = x.lock().unwrap();
LL | |
LL | | let second = baz().await;
LL | |
... |
LL | | first + second + third
LL | | }
| |_____^
error: this `MutexGuard` is held across an `await` point
--> $DIR/await_holding_lock.rs:66:17
|
LL | let guard = x.lock().unwrap();
| ^^^^^
|
= 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
--> $DIR/await_holding_lock.rs:66:13
|
LL | / let guard = x.lock().unwrap();
LL | | baz().await
LL | | };
| |_________^
error: this `MutexGuard` is held across an `await` point
--> $DIR/await_holding_lock.rs:78:17
|
LL | let guard = x.lock().unwrap();
| ^^^^^
|
= 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
--> $DIR/await_holding_lock.rs:78:13
|
LL | / let guard = x.lock().unwrap();
LL | | baz().await
LL | | }
| |_________^
error: this `MutexGuard` is held across an `await` point
--> $DIR/await_holding_lock.rs:89:13
|
LL | let guard = x.lock();
| ^^^^^
|
= 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
--> $DIR/await_holding_lock.rs:89:9
|
LL | / let guard = x.lock();
LL | | baz().await
LL | | }
| |_____^
error: this `MutexGuard` is held across an `await` point
--> $DIR/await_holding_lock.rs:104:13
|
LL | let guard = x.read();
| ^^^^^
|
= 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
--> $DIR/await_holding_lock.rs:104:9
|
LL | / let guard = x.read();
LL | | baz().await
LL | | }
| |_____^
error: this `MutexGuard` is held across an `await` point
--> $DIR/await_holding_lock.rs:109:13
|
LL | let mut guard = x.write();
| ^^^^^^^^^
|
= 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
--> $DIR/await_holding_lock.rs:109:9
|
LL | / let mut guard = x.write();
LL | | baz().await
LL | | }
| |_____^
error: this `MutexGuard` is held across an `await` point
--> $DIR/await_holding_lock.rs:134:13
|
LL | let guard = x.lock();
| ^^^^^
|
= 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
--> $DIR/await_holding_lock.rs:134:9
|
LL | / let guard = x.lock();
LL | |
LL | | let second = baz().await;
LL | |
... |
LL | | first + second + third
LL | | }
| |_____^
error: this `MutexGuard` is held across an `await` point
--> $DIR/await_holding_lock.rs:147:17
|
LL | let guard = x.lock();
| ^^^^^
|
= 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
--> $DIR/await_holding_lock.rs:147:13
|
LL | / let guard = x.lock();
LL | | baz().await
LL | | };
| |_________^
error: this `MutexGuard` is held across an `await` point
--> $DIR/await_holding_lock.rs:159:17
|
LL | let guard = x.lock();
| ^^^^^
|
= 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
--> $DIR/await_holding_lock.rs:159:13
|
LL | / let guard = x.lock();
LL | | baz().await
LL | | }
| |_________^
error: aborting due to 12 previous errors