Skip to content

Commit 3806cc0

Browse files
authored
Rollup merge of rust-lang#89303 - guswynn:std_suspend, r=dtolnay
Add `#[must_not_suspend]` to some types in std I am not sure what else should have it? `Ref`?
2 parents 36bea20 + cb8e83c commit 3806cc0

File tree

7 files changed

+68
-0
lines changed

7 files changed

+68
-0
lines changed

library/core/src/cell.rs

+10
Original file line numberDiff line numberDiff line change
@@ -1303,6 +1303,11 @@ impl Clone for BorrowRef<'_> {
13031303
///
13041304
/// See the [module-level documentation](self) for more.
13051305
#[stable(feature = "rust1", since = "1.0.0")]
1306+
#[cfg_attr(
1307+
not(bootstrap),
1308+
must_not_suspend = "Holding a Ref across suspend \
1309+
points can cause BorrowErrors"
1310+
)]
13061311
pub struct Ref<'b, T: ?Sized + 'b> {
13071312
value: &'b T,
13081313
borrow: BorrowRef<'b>,
@@ -1679,6 +1684,11 @@ impl<'b> BorrowRefMut<'b> {
16791684
///
16801685
/// See the [module-level documentation](self) for more.
16811686
#[stable(feature = "rust1", since = "1.0.0")]
1687+
#[cfg_attr(
1688+
not(bootstrap),
1689+
must_not_suspend = "Holding a RefMut across suspend \
1690+
points can cause BorrowErrors"
1691+
)]
16821692
pub struct RefMut<'b, T: ?Sized + 'b> {
16831693
value: &'b mut T,
16841694
borrow: BorrowRefMut<'b>,

library/core/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@
142142
#![feature(link_llvm_intrinsics)]
143143
#![feature(llvm_asm)]
144144
#![feature(min_specialization)]
145+
#![cfg_attr(not(bootstrap), feature(must_not_suspend))]
145146
#![feature(negative_impls)]
146147
#![feature(never_type)]
147148
#![feature(no_core)]

library/std/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,7 @@
297297
#![feature(maybe_uninit_slice)]
298298
#![feature(maybe_uninit_uninit_array)]
299299
#![feature(min_specialization)]
300+
#![cfg_attr(not(bootstrap), feature(must_not_suspend))]
300301
#![feature(needs_panic_runtime)]
301302
#![feature(negative_impls)]
302303
#![feature(never_type)]

library/std/src/sync/mutex.rs

+6
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,12 @@ unsafe impl<T: ?Sized + Send> Sync for Mutex<T> {}
188188
/// [`lock`]: Mutex::lock
189189
/// [`try_lock`]: Mutex::try_lock
190190
#[must_use = "if unused the Mutex will immediately unlock"]
191+
#[cfg_attr(
192+
not(bootstrap),
193+
must_not_suspend = "Holding a MutexGuard across suspend \
194+
points can cause deadlocks, delays, \
195+
and cause Futures to not implement `Send`"
196+
)]
191197
#[stable(feature = "rust1", since = "1.0.0")]
192198
pub struct MutexGuard<'a, T: ?Sized + 'a> {
193199
lock: &'a Mutex<T>,

library/std/src/sync/rwlock.rs

+12
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,12 @@ unsafe impl<T: ?Sized + Send + Sync> Sync for RwLock<T> {}
9595
/// [`read`]: RwLock::read
9696
/// [`try_read`]: RwLock::try_read
9797
#[must_use = "if unused the RwLock will immediately unlock"]
98+
#[cfg_attr(
99+
not(bootstrap),
100+
must_not_suspend = "Holding a RwLockReadGuard across suspend \
101+
points can cause deadlocks, delays, \
102+
and cause Futures to not implement `Send`"
103+
)]
98104
#[stable(feature = "rust1", since = "1.0.0")]
99105
pub struct RwLockReadGuard<'a, T: ?Sized + 'a> {
100106
lock: &'a RwLock<T>,
@@ -115,6 +121,12 @@ unsafe impl<T: ?Sized + Sync> Sync for RwLockReadGuard<'_, T> {}
115121
/// [`write`]: RwLock::write
116122
/// [`try_write`]: RwLock::try_write
117123
#[must_use = "if unused the RwLock will immediately unlock"]
124+
#[cfg_attr(
125+
not(bootstrap),
126+
must_not_suspend = "Holding a RwLockWriteGuard across suspend \
127+
points can cause deadlocks, delays, \
128+
and cause Future's to not implement `Send`"
129+
)]
118130
#[stable(feature = "rust1", since = "1.0.0")]
119131
pub struct RwLockWriteGuard<'a, T: ?Sized + 'a> {
120132
lock: &'a RwLock<T>,
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// edition:2018
2+
#![deny(must_not_suspend)]
3+
4+
async fn other() {}
5+
6+
pub async fn uhoh(m: std::sync::Mutex<()>) {
7+
let _guard = m.lock().unwrap(); //~ ERROR `MutexGuard` held across
8+
other().await;
9+
}
10+
11+
fn main() {
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
error: `MutexGuard` held across a suspend point, but should not be
2+
--> $DIR/mutex.rs:7:9
3+
|
4+
LL | let _guard = m.lock().unwrap();
5+
| ^^^^^^
6+
LL | other().await;
7+
| ------------- the value is held across this suspend point
8+
|
9+
note: the lint level is defined here
10+
--> $DIR/mutex.rs:2:9
11+
|
12+
LL | #![deny(must_not_suspend)]
13+
| ^^^^^^^^^^^^^^^^
14+
note: Holding a MutexGuard across suspend points can cause deadlocks, delays, and cause Futures to not implement `Send`
15+
--> $DIR/mutex.rs:7:9
16+
|
17+
LL | let _guard = m.lock().unwrap();
18+
| ^^^^^^
19+
help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
20+
--> $DIR/mutex.rs:7:9
21+
|
22+
LL | let _guard = m.lock().unwrap();
23+
| ^^^^^^
24+
25+
error: aborting due to previous error
26+

0 commit comments

Comments
 (0)