Skip to content

Commit

Permalink
Rollup merge of #89303 - guswynn:std_suspend, r=dtolnay
Browse files Browse the repository at this point in the history
Add `#[must_not_suspend]` to some types in std

I am not sure what else should have it? `Ref`?
  • Loading branch information
Manishearth committed Oct 1, 2021
2 parents 837ac87 + cb8e83c commit 7b40d42
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 0 deletions.
10 changes: 10 additions & 0 deletions library/core/src/cell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>,
Expand Down Expand Up @@ -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>,
Expand Down
1 change: 1 addition & 0 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,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)]
Expand Down
1 change: 1 addition & 0 deletions library/std/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
6 changes: 6 additions & 0 deletions library/std/src/sync/mutex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,12 @@ unsafe impl<T: ?Sized + Send> Sync for Mutex<T> {}
/// [`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 Futures to not implement `Send`"
)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct MutexGuard<'a, T: ?Sized + 'a> {
lock: &'a Mutex<T>,
Expand Down
12 changes: 12 additions & 0 deletions library/std/src/sync/rwlock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,12 @@ unsafe impl<T: ?Sized + Send + Sync> Sync for RwLock<T> {}
/// [`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 Futures to not implement `Send`"
)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct RwLockReadGuard<'a, T: ?Sized + 'a> {
lock: &'a RwLock<T>,
Expand All @@ -115,6 +121,12 @@ unsafe impl<T: ?Sized + Sync> 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<T>,
Expand Down
12 changes: 12 additions & 0 deletions src/test/ui/lint/must_not_suspend/mutex.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// edition:2018
#![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 changes: 26 additions & 0 deletions src/test/ui/lint/must_not_suspend/mutex.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
error: `MutexGuard` held across a suspend point, but should not be
--> $DIR/mutex.rs:7: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:2:9
|
LL | #![deny(must_not_suspend)]
| ^^^^^^^^^^^^^^^^
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();
| ^^^^^^
help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
--> $DIR/mutex.rs:7:9
|
LL | let _guard = m.lock().unwrap();
| ^^^^^^

error: aborting due to previous error

0 comments on commit 7b40d42

Please sign in to comment.