lock types
This commit is contained in:
parent
ac8dd1b2f2
commit
0f9c349834
5 changed files with 58 additions and 0 deletions
|
@ -297,6 +297,7 @@
|
||||||
#![feature(maybe_uninit_slice)]
|
#![feature(maybe_uninit_slice)]
|
||||||
#![feature(maybe_uninit_uninit_array)]
|
#![feature(maybe_uninit_uninit_array)]
|
||||||
#![feature(min_specialization)]
|
#![feature(min_specialization)]
|
||||||
|
#![cfg_attr(not(bootstrap), feature(must_not_suspend))]
|
||||||
#![feature(needs_panic_runtime)]
|
#![feature(needs_panic_runtime)]
|
||||||
#![feature(negative_impls)]
|
#![feature(negative_impls)]
|
||||||
#![feature(never_type)]
|
#![feature(never_type)]
|
||||||
|
|
|
@ -188,6 +188,12 @@ unsafe impl<T: ?Sized + Send> Sync for Mutex<T> {}
|
||||||
/// [`lock`]: Mutex::lock
|
/// [`lock`]: Mutex::lock
|
||||||
/// [`try_lock`]: Mutex::try_lock
|
/// [`try_lock`]: Mutex::try_lock
|
||||||
#[must_use = "if unused the Mutex will immediately unlock"]
|
#[must_use = "if unused the Mutex will immediately unlock"]
|
||||||
|
#[cfg_attr(
|
||||||
|
not(bootstrap),
|
||||||
|
must_not_suspend = "Holding a MutexGuard across suspend \
|
||||||
|
points can cause deadlocks, delays, \
|
||||||
|
and cause Future's to not implement `Send`"
|
||||||
|
)]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub struct MutexGuard<'a, T: ?Sized + 'a> {
|
pub struct MutexGuard<'a, T: ?Sized + 'a> {
|
||||||
lock: &'a Mutex<T>,
|
lock: &'a Mutex<T>,
|
||||||
|
|
|
@ -95,6 +95,12 @@ unsafe impl<T: ?Sized + Send + Sync> Sync for RwLock<T> {}
|
||||||
/// [`read`]: RwLock::read
|
/// [`read`]: RwLock::read
|
||||||
/// [`try_read`]: RwLock::try_read
|
/// [`try_read`]: RwLock::try_read
|
||||||
#[must_use = "if unused the RwLock will immediately unlock"]
|
#[must_use = "if unused the RwLock will immediately unlock"]
|
||||||
|
#[cfg_attr(
|
||||||
|
not(bootstrap),
|
||||||
|
must_not_suspend = "Holding a RwLockReadGuard across suspend \
|
||||||
|
points can cause deadlocks, delays, \
|
||||||
|
and cause Future's to not implement `Send`"
|
||||||
|
)]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub struct RwLockReadGuard<'a, T: ?Sized + 'a> {
|
pub struct RwLockReadGuard<'a, T: ?Sized + 'a> {
|
||||||
lock: &'a RwLock<T>,
|
lock: &'a RwLock<T>,
|
||||||
|
@ -115,6 +121,12 @@ unsafe impl<T: ?Sized + Sync> Sync for RwLockReadGuard<'_, T> {}
|
||||||
/// [`write`]: RwLock::write
|
/// [`write`]: RwLock::write
|
||||||
/// [`try_write`]: RwLock::try_write
|
/// [`try_write`]: RwLock::try_write
|
||||||
#[must_use = "if unused the RwLock will immediately unlock"]
|
#[must_use = "if unused the RwLock will immediately unlock"]
|
||||||
|
#[cfg_attr(
|
||||||
|
not(bootstrap),
|
||||||
|
must_not_suspend = "Holding a RwLockWriteGuard across suspend \
|
||||||
|
points can cause deadlocks, delays, \
|
||||||
|
and cause Future's to not implement `Send`"
|
||||||
|
)]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub struct RwLockWriteGuard<'a, T: ?Sized + 'a> {
|
pub struct RwLockWriteGuard<'a, T: ?Sized + 'a> {
|
||||||
lock: &'a RwLock<T>,
|
lock: &'a RwLock<T>,
|
||||||
|
|
13
src/test/ui/lint/must_not_suspend/mutex.rs
Normal file
13
src/test/ui/lint/must_not_suspend/mutex.rs
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
// edition:2018
|
||||||
|
#![feature(must_not_suspend)]
|
||||||
|
#![deny(must_not_suspend)]
|
||||||
|
|
||||||
|
async fn other() {}
|
||||||
|
|
||||||
|
pub async fn uhoh(m: std::sync::Mutex<()>) {
|
||||||
|
let _guard = m.lock().unwrap(); //~ ERROR `MutexGuard` held across
|
||||||
|
other().await;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
}
|
26
src/test/ui/lint/must_not_suspend/mutex.stderr
Normal file
26
src/test/ui/lint/must_not_suspend/mutex.stderr
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
error: `MutexGuard` held across a suspend point, but should not be
|
||||||
|
--> $DIR/mutex.rs:8:9
|
||||||
|
|
|
||||||
|
LL | let _guard = m.lock().unwrap();
|
||||||
|
| ^^^^^^
|
||||||
|
LL | other().await;
|
||||||
|
| ------------- the value is held across this suspend point
|
||||||
|
|
|
||||||
|
note: the lint level is defined here
|
||||||
|
--> $DIR/mutex.rs:3:9
|
||||||
|
|
|
||||||
|
LL | #![deny(must_not_suspend)]
|
||||||
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
note: Holding a MutexGuard across suspend points can cause deadlocks, delays, and cause Future's to not implement `Send`
|
||||||
|
--> $DIR/mutex.rs:8:9
|
||||||
|
|
|
||||||
|
LL | let _guard = m.lock().unwrap();
|
||||||
|
| ^^^^^^
|
||||||
|
help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
|
||||||
|
--> $DIR/mutex.rs:8:9
|
||||||
|
|
|
||||||
|
LL | let _guard = m.lock().unwrap();
|
||||||
|
| ^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue