From 0f9c349834622fa337c8dab886af4041bcdad5bb Mon Sep 17 00:00:00 2001 From: Gus Wynn Date: Mon, 27 Sep 2021 08:43:30 -0700 Subject: [PATCH 1/3] lock types --- library/std/src/lib.rs | 1 + library/std/src/sync/mutex.rs | 6 +++++ library/std/src/sync/rwlock.rs | 12 +++++++++ src/test/ui/lint/must_not_suspend/mutex.rs | 13 ++++++++++ .../ui/lint/must_not_suspend/mutex.stderr | 26 +++++++++++++++++++ 5 files changed, 58 insertions(+) create mode 100644 src/test/ui/lint/must_not_suspend/mutex.rs create mode 100644 src/test/ui/lint/must_not_suspend/mutex.stderr diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index f69baba9e733f..9d150b69f6a6d 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -297,6 +297,7 @@ #![feature(maybe_uninit_slice)] #![feature(maybe_uninit_uninit_array)] #![feature(min_specialization)] +#![cfg_attr(not(bootstrap), feature(must_not_suspend))] #![feature(needs_panic_runtime)] #![feature(negative_impls)] #![feature(never_type)] diff --git a/library/std/src/sync/mutex.rs b/library/std/src/sync/mutex.rs index e1d6324c17e33..9abd4b547c77e 100644 --- a/library/std/src/sync/mutex.rs +++ b/library/std/src/sync/mutex.rs @@ -188,6 +188,12 @@ unsafe impl Sync for Mutex {} /// [`lock`]: Mutex::lock /// [`try_lock`]: Mutex::try_lock #[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")] pub struct MutexGuard<'a, T: ?Sized + 'a> { lock: &'a Mutex, diff --git a/library/std/src/sync/rwlock.rs b/library/std/src/sync/rwlock.rs index e50d62d817376..1523d36323fd9 100644 --- a/library/std/src/sync/rwlock.rs +++ b/library/std/src/sync/rwlock.rs @@ -95,6 +95,12 @@ unsafe impl Sync for RwLock {} /// [`read`]: RwLock::read /// [`try_read`]: RwLock::try_read #[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")] pub struct RwLockReadGuard<'a, T: ?Sized + 'a> { lock: &'a RwLock, @@ -115,6 +121,12 @@ unsafe impl Sync for RwLockReadGuard<'_, T> {} /// [`write`]: RwLock::write /// [`try_write`]: RwLock::try_write #[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")] pub struct RwLockWriteGuard<'a, T: ?Sized + 'a> { lock: &'a RwLock, diff --git a/src/test/ui/lint/must_not_suspend/mutex.rs b/src/test/ui/lint/must_not_suspend/mutex.rs new file mode 100644 index 0000000000000..7bb895e7d3643 --- /dev/null +++ b/src/test/ui/lint/must_not_suspend/mutex.rs @@ -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() { +} diff --git a/src/test/ui/lint/must_not_suspend/mutex.stderr b/src/test/ui/lint/must_not_suspend/mutex.stderr new file mode 100644 index 0000000000000..69638fc20107c --- /dev/null +++ b/src/test/ui/lint/must_not_suspend/mutex.stderr @@ -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 + From 4cc3297dc403e9d4d2106b26418efe35d4bb1af2 Mon Sep 17 00:00:00 2001 From: Gus Wynn Date: Mon, 27 Sep 2021 08:49:36 -0700 Subject: [PATCH 2/3] #[feature] not required for lint result --- src/test/ui/lint/must_not_suspend/mutex.rs | 1 - src/test/ui/lint/must_not_suspend/mutex.stderr | 8 ++++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/test/ui/lint/must_not_suspend/mutex.rs b/src/test/ui/lint/must_not_suspend/mutex.rs index 7bb895e7d3643..596249b2e4e4f 100644 --- a/src/test/ui/lint/must_not_suspend/mutex.rs +++ b/src/test/ui/lint/must_not_suspend/mutex.rs @@ -1,5 +1,4 @@ // edition:2018 -#![feature(must_not_suspend)] #![deny(must_not_suspend)] async fn other() {} diff --git a/src/test/ui/lint/must_not_suspend/mutex.stderr b/src/test/ui/lint/must_not_suspend/mutex.stderr index 69638fc20107c..47a84fdbc5731 100644 --- a/src/test/ui/lint/must_not_suspend/mutex.stderr +++ b/src/test/ui/lint/must_not_suspend/mutex.stderr @@ -1,5 +1,5 @@ error: `MutexGuard` held across a suspend point, but should not be - --> $DIR/mutex.rs:8:9 + --> $DIR/mutex.rs:7:9 | LL | let _guard = m.lock().unwrap(); | ^^^^^^ @@ -7,17 +7,17 @@ LL | other().await; | ------------- the value is held across this suspend point | note: the lint level is defined here - --> $DIR/mutex.rs:3:9 + --> $DIR/mutex.rs:2: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 + --> $DIR/mutex.rs:7: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 + --> $DIR/mutex.rs:7:9 | LL | let _guard = m.lock().unwrap(); | ^^^^^^ From cb8e83caeba7268ebb3515468d348aea7af9fdae Mon Sep 17 00:00:00 2001 From: Gus Wynn Date: Tue, 28 Sep 2021 17:57:08 -0700 Subject: [PATCH 3/3] ref/refmut --- library/core/src/cell.rs | 10 ++++++++++ library/core/src/lib.rs | 1 + library/std/src/sync/mutex.rs | 2 +- library/std/src/sync/rwlock.rs | 2 +- src/test/ui/lint/must_not_suspend/mutex.stderr | 2 +- 5 files changed, 14 insertions(+), 3 deletions(-) diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index e56b631dbaf8d..c0121eebb7fef 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -1303,6 +1303,11 @@ impl Clone for BorrowRef<'_> { /// /// See the [module-level documentation](self) for more. #[stable(feature = "rust1", since = "1.0.0")] +#[cfg_attr( + not(bootstrap), + must_not_suspend = "Holding a Ref across suspend \ + points can cause BorrowErrors" +)] pub struct Ref<'b, T: ?Sized + 'b> { value: &'b T, borrow: BorrowRef<'b>, @@ -1679,6 +1684,11 @@ impl<'b> BorrowRefMut<'b> { /// /// See the [module-level documentation](self) for more. #[stable(feature = "rust1", since = "1.0.0")] +#[cfg_attr( + not(bootstrap), + must_not_suspend = "Holding a RefMut across suspend \ + points can cause BorrowErrors" +)] pub struct RefMut<'b, T: ?Sized + 'b> { value: &'b mut T, borrow: BorrowRefMut<'b>, diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 265ba9f1bb91b..2230461b5f4b5 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -141,6 +141,7 @@ #![feature(link_llvm_intrinsics)] #![feature(llvm_asm)] #![feature(min_specialization)] +#![cfg_attr(not(bootstrap), feature(must_not_suspend))] #![feature(negative_impls)] #![feature(never_type)] #![feature(no_core)] diff --git a/library/std/src/sync/mutex.rs b/library/std/src/sync/mutex.rs index 9abd4b547c77e..06a97fd3f7610 100644 --- a/library/std/src/sync/mutex.rs +++ b/library/std/src/sync/mutex.rs @@ -192,7 +192,7 @@ unsafe impl Sync for Mutex {} not(bootstrap), must_not_suspend = "Holding a MutexGuard across suspend \ points can cause deadlocks, delays, \ - and cause Future's to not implement `Send`" + and cause Futures to not implement `Send`" )] #[stable(feature = "rust1", since = "1.0.0")] pub struct MutexGuard<'a, T: ?Sized + 'a> { diff --git a/library/std/src/sync/rwlock.rs b/library/std/src/sync/rwlock.rs index 1523d36323fd9..aa1ce82d96799 100644 --- a/library/std/src/sync/rwlock.rs +++ b/library/std/src/sync/rwlock.rs @@ -99,7 +99,7 @@ unsafe impl Sync for RwLock {} not(bootstrap), must_not_suspend = "Holding a RwLockReadGuard across suspend \ points can cause deadlocks, delays, \ - and cause Future's to not implement `Send`" + and cause Futures to not implement `Send`" )] #[stable(feature = "rust1", since = "1.0.0")] pub struct RwLockReadGuard<'a, T: ?Sized + 'a> { diff --git a/src/test/ui/lint/must_not_suspend/mutex.stderr b/src/test/ui/lint/must_not_suspend/mutex.stderr index 47a84fdbc5731..4e0d9343c2c71 100644 --- a/src/test/ui/lint/must_not_suspend/mutex.stderr +++ b/src/test/ui/lint/must_not_suspend/mutex.stderr @@ -11,7 +11,7 @@ note: the lint level is defined here | LL | #![deny(must_not_suspend)] | ^^^^^^^^^^^^^^^^ -note: Holding a MutexGuard across suspend points can cause deadlocks, delays, and cause Future's to not implement `Send` +note: Holding a MutexGuard across suspend points can cause deadlocks, delays, and cause Futures to not implement `Send` --> $DIR/mutex.rs:7:9 | LL | let _guard = m.lock().unwrap();