diff options
| author | flip1995 <philipp.krones@embecosm.com> | 2022-02-12 10:32:44 +0100 |
|---|---|---|
| committer | flip1995 <philipp.krones@embecosm.com> | 2022-02-17 18:02:31 +0100 |
| commit | c4944fb60d102a4a4e0cb5f3f86379bea2338ed0 (patch) | |
| tree | 5d6aaa69f1c22049ecc53711b0e8cf068606e598 | |
| parent | cdf9a28006b1216653eac1bdc45a83e436fac9ba (diff) | |
| download | rust-c4944fb60d102a4a4e0cb5f3f86379bea2338ed0.tar.gz rust-c4944fb60d102a4a4e0cb5f3f86379bea2338ed0.zip | |
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.
| -rw-r--r-- | clippy_utils/src/paths.rs | 6 | ||||
| -rw-r--r-- | tests/ui/await_holding_lock.rs | 204 | ||||
| -rw-r--r-- | tests/ui/await_holding_lock.stderr | 180 |
3 files changed, 287 insertions, 103 deletions
diff --git a/clippy_utils/src/paths.rs b/clippy_utils/src/paths.rs index 48c0e89e4d2..b54bd3a4fef 100644 --- a/clippy_utils/src/paths.rs +++ b/clippy_utils/src/paths.rs @@ -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"]; diff --git a/tests/ui/await_holding_lock.rs b/tests/ui/await_holding_lock.rs index f03356d83df..1a57db91ab5 100644 --- a/tests/ui/await_holding_lock.rs +++ b/tests/ui/await_holding_lock.rs @@ -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 -} + pub async fn bad(x: &Mutex<u32>) -> u32 { + let guard = x.lock().unwrap(); + baz().await + } -async fn good(x: &Mutex<u32>) -> u32 { - { + pub async fn good(x: &Mutex<u32>) -> u32 { + { + let guard = x.lock().unwrap(); + let y = *guard + 1; + } + baz().await; let guard = x.lock().unwrap(); - let y = *guard + 1; + 47 } - 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 bad_rw(x: &RwLock<u32>) -> u32 { + let guard = x.read().unwrap(); + baz().await + } -pub async fn bad_rw_write(x: &RwLock<u32>) -> u32 { - let mut guard = x.write().unwrap(); - baz().await -} + 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 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(); - let y = *guard + 1; + 47 } - { - let mut guard = x.write().unwrap(); - *guard += 1; + + pub async fn baz() -> u32 { + 42 } - baz().await; - let guard = x.read().unwrap(); - 47 -} -async fn baz() -> u32 { - 42 -} + pub async fn also_bad(x: &Mutex<u32>) -> u32 { + let first = baz().await; + + let guard = x.lock().unwrap(); -async fn also_bad(x: &Mutex<u32>) -> u32 { - let first = baz().await; + let second = baz().await; - let guard = x.lock().unwrap(); + let third = baz().await; - let second = 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; + let third = baz().await; - first + second + third + 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 + } + } } -async fn not_good(x: &Mutex<u32>) -> u32 { - let first = baz().await; +// When adding or modifying a test, please do the same for std::Mutex. +mod parking_lot_mutex { + use parking_lot::{Mutex, RwLock}; - let second = { - let guard = x.lock().unwrap(); + pub async fn bad(x: &Mutex<u32>) -> u32 { + let guard = x.lock(); baz().await - }; + } - let third = 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 + } - first + second + third -} + pub async fn bad_rw(x: &RwLock<u32>) -> u32 { + let guard = x.read(); + 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(); + 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); } diff --git a/tests/ui/await_holding_lock.stderr b/tests/ui/await_holding_lock.stderr index 3a501acbb67..a6c1dd228e4 100644 --- a/tests/ui/await_holding_lock.stderr +++ b/tests/ui/await_holding_lock.stderr @@ -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 + --> $DIR/await_holding_lock.rs:8:9 | -LL | / let guard = x.lock().unwrap(); -LL | | baz().await -LL | | } - | |_^ +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 + --> $DIR/await_holding_lock.rs:23:13 | -LL | let guard = x.read().unwrap(); - | ^^^^^ +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 + --> $DIR/await_holding_lock.rs:23:9 | -LL | / let guard = x.read().unwrap(); -LL | | baz().await -LL | | } - | |_^ +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 + --> $DIR/await_holding_lock.rs:28:13 | -LL | let mut guard = x.write().unwrap(); - | ^^^^^^^^^ +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 + --> $DIR/await_holding_lock.rs:28:9 | -LL | / let mut guard = x.write().unwrap(); -LL | | baz().await -LL | | } - | |_^ +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 + --> $DIR/await_holding_lock.rs:53:13 | -LL | let guard = x.lock().unwrap(); - | ^^^^^ +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 + --> $DIR/await_holding_lock.rs:53:9 | -LL | / let guard = x.lock().unwrap(); +LL | / let guard = x.lock().unwrap(); LL | | -LL | | let second = baz().await; +LL | | let second = baz().await; LL | | ... | -LL | | first + second + third -LL | | } - | |_^ +LL | | first + second + third +LL | | } + | |_____^ error: this `MutexGuard` is held across an `await` point - --> $DIR/await_holding_lock.rs:64:13 + --> $DIR/await_holding_lock.rs:66:17 | -LL | let guard = x.lock().unwrap(); +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:64:9 + --> $DIR/await_holding_lock.rs:89:9 | -LL | / let guard = x.lock().unwrap(); +LL | / let guard = x.lock(); LL | | baz().await -LL | | }; +LL | | } | |_____^ error: this `MutexGuard` is held across an `await` point - --> $DIR/await_holding_lock.rs:76:13 + --> $DIR/await_holding_lock.rs:104:13 | -LL | let guard = x.lock().unwrap(); +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:76:9 + --> $DIR/await_holding_lock.rs:104:9 | -LL | / let guard = x.lock().unwrap(); +LL | / let guard = x.read(); 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: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 |
