File tree 7 files changed +68
-0
lines changed
src/test/ui/lint/must_not_suspend
7 files changed +68
-0
lines changed Original file line number Diff line number Diff line change @@ -1303,6 +1303,11 @@ impl Clone for BorrowRef<'_> {
1303
1303
///
1304
1304
/// See the [module-level documentation](self) for more.
1305
1305
#[ 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
+ ) ]
1306
1311
pub struct Ref < ' b , T : ?Sized + ' b > {
1307
1312
value : & ' b T ,
1308
1313
borrow : BorrowRef < ' b > ,
@@ -1679,6 +1684,11 @@ impl<'b> BorrowRefMut<'b> {
1679
1684
///
1680
1685
/// See the [module-level documentation](self) for more.
1681
1686
#[ 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
+ ) ]
1682
1692
pub struct RefMut < ' b , T : ?Sized + ' b > {
1683
1693
value : & ' b mut T ,
1684
1694
borrow : BorrowRefMut < ' b > ,
Original file line number Diff line number Diff line change 142
142
#![ feature( link_llvm_intrinsics) ]
143
143
#![ feature( llvm_asm) ]
144
144
#![ feature( min_specialization) ]
145
+ #![ cfg_attr( not( bootstrap) , feature( must_not_suspend) ) ]
145
146
#![ feature( negative_impls) ]
146
147
#![ feature( never_type) ]
147
148
#![ feature( no_core) ]
Original file line number Diff line number Diff line change 297
297
#![ feature( maybe_uninit_slice) ]
298
298
#![ feature( maybe_uninit_uninit_array) ]
299
299
#![ feature( min_specialization) ]
300
+ #![ cfg_attr( not( bootstrap) , feature( must_not_suspend) ) ]
300
301
#![ feature( needs_panic_runtime) ]
301
302
#![ feature( negative_impls) ]
302
303
#![ feature( never_type) ]
Original file line number Diff line number Diff line change @@ -188,6 +188,12 @@ unsafe impl<T: ?Sized + Send> Sync for Mutex<T> {}
188
188
/// [`lock`]: Mutex::lock
189
189
/// [`try_lock`]: Mutex::try_lock
190
190
#[ 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
+ ) ]
191
197
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
192
198
pub struct MutexGuard < ' a , T : ?Sized + ' a > {
193
199
lock : & ' a Mutex < T > ,
Original file line number Diff line number Diff line change @@ -95,6 +95,12 @@ unsafe impl<T: ?Sized + Send + Sync> Sync for RwLock<T> {}
95
95
/// [`read`]: RwLock::read
96
96
/// [`try_read`]: RwLock::try_read
97
97
#[ 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
+ ) ]
98
104
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
99
105
pub struct RwLockReadGuard < ' a , T : ?Sized + ' a > {
100
106
lock : & ' a RwLock < T > ,
@@ -115,6 +121,12 @@ unsafe impl<T: ?Sized + Sync> Sync for RwLockReadGuard<'_, T> {}
115
121
/// [`write`]: RwLock::write
116
122
/// [`try_write`]: RwLock::try_write
117
123
#[ 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
+ ) ]
118
130
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
119
131
pub struct RwLockWriteGuard < ' a , T : ?Sized + ' a > {
120
132
lock : & ' a RwLock < T > ,
Original file line number Diff line number Diff line change
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 number Diff line number Diff line change
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
+
You can’t perform that action at this time.
0 commit comments