Rollup merge of #89826 - guswynn:feature_gate_must_not_suspend, r=Mark-Simulacrum
Feature gate + make must_not_suspend allow-by-default Fixes #89798 and patches over #89562 (not a true fix, since we're just disabling the lint for now).
This commit is contained in:
commit
c65400548a
|
@ -300,7 +300,6 @@ fn register_builtins(store: &mut LintStore, no_interleave_lints: bool) {
|
||||||
UNUSED_LABELS,
|
UNUSED_LABELS,
|
||||||
UNUSED_PARENS,
|
UNUSED_PARENS,
|
||||||
UNUSED_BRACES,
|
UNUSED_BRACES,
|
||||||
MUST_NOT_SUSPEND,
|
|
||||||
REDUNDANT_SEMICOLONS
|
REDUNDANT_SEMICOLONS
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -323,6 +323,7 @@ declare_lint! {
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// #![feature(must_not_suspend)]
|
/// #![feature(must_not_suspend)]
|
||||||
|
/// #![warn(must_not_suspend)]
|
||||||
///
|
///
|
||||||
/// #[must_not_suspend]
|
/// #[must_not_suspend]
|
||||||
/// struct SyncThing {}
|
/// struct SyncThing {}
|
||||||
|
@ -349,8 +350,9 @@ declare_lint! {
|
||||||
/// `MutexGuard`'s)
|
/// `MutexGuard`'s)
|
||||||
///
|
///
|
||||||
pub MUST_NOT_SUSPEND,
|
pub MUST_NOT_SUSPEND,
|
||||||
Warn,
|
Allow,
|
||||||
"use of a `#[must_not_suspend]` value across a yield point",
|
"use of a `#[must_not_suspend]` value across a yield point",
|
||||||
|
@feature_gate = rustc_span::symbol::sym::must_not_suspend;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
// edition:2018
|
// edition:2018
|
||||||
|
#![feature(must_not_suspend)]
|
||||||
|
#![allow(must_not_suspend)]
|
||||||
|
|
||||||
// This tests the basic example case for the async-await-specific error.
|
// This tests the basic example case for the async-await-specific error.
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
error: future cannot be sent between threads safely
|
error: future cannot be sent between threads safely
|
||||||
--> $DIR/issue-64130-non-send-future-diags.rs:21:13
|
--> $DIR/issue-64130-non-send-future-diags.rs:23:13
|
||||||
|
|
|
|
||||||
LL | is_send(foo());
|
LL | is_send(foo());
|
||||||
| ^^^^^ future returned by `foo` is not `Send`
|
| ^^^^^ future returned by `foo` is not `Send`
|
||||||
|
|
|
|
||||||
= help: within `impl Future`, the trait `Send` is not implemented for `MutexGuard<'_, u32>`
|
= help: within `impl Future`, the trait `Send` is not implemented for `MutexGuard<'_, u32>`
|
||||||
note: future is not `Send` as this value is used across an await
|
note: future is not `Send` as this value is used across an await
|
||||||
--> $DIR/issue-64130-non-send-future-diags.rs:15:5
|
--> $DIR/issue-64130-non-send-future-diags.rs:17:5
|
||||||
|
|
|
|
||||||
LL | let g = x.lock().unwrap();
|
LL | let g = x.lock().unwrap();
|
||||||
| - has type `MutexGuard<'_, u32>` which is not `Send`
|
| - has type `MutexGuard<'_, u32>` which is not `Send`
|
||||||
|
@ -15,7 +15,7 @@ LL | baz().await;
|
||||||
LL | }
|
LL | }
|
||||||
| - `g` is later dropped here
|
| - `g` is later dropped here
|
||||||
note: required by a bound in `is_send`
|
note: required by a bound in `is_send`
|
||||||
--> $DIR/issue-64130-non-send-future-diags.rs:7:15
|
--> $DIR/issue-64130-non-send-future-diags.rs:9:15
|
||||||
|
|
|
|
||||||
LL | fn is_send<T: Send>(t: T) { }
|
LL | fn is_send<T: Send>(t: T) { }
|
||||||
| ^^^^ required by this bound in `is_send`
|
| ^^^^ required by this bound in `is_send`
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
// edition:2018
|
// edition:2018
|
||||||
|
#![feature(must_not_suspend)]
|
||||||
|
#![allow(must_not_suspend)]
|
||||||
|
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
error: future cannot be sent between threads safely
|
error: future cannot be sent between threads safely
|
||||||
--> $DIR/issue-71137.rs:20:14
|
--> $DIR/issue-71137.rs:22:14
|
||||||
|
|
|
|
||||||
LL | fake_spawn(wrong_mutex());
|
LL | fake_spawn(wrong_mutex());
|
||||||
| ^^^^^^^^^^^^^ future returned by `wrong_mutex` is not `Send`
|
| ^^^^^^^^^^^^^ future returned by `wrong_mutex` is not `Send`
|
||||||
|
|
|
|
||||||
= help: within `impl Future`, the trait `Send` is not implemented for `MutexGuard<'_, i32>`
|
= help: within `impl Future`, the trait `Send` is not implemented for `MutexGuard<'_, i32>`
|
||||||
note: future is not `Send` as this value is used across an await
|
note: future is not `Send` as this value is used across an await
|
||||||
--> $DIR/issue-71137.rs:12:5
|
--> $DIR/issue-71137.rs:14:5
|
||||||
|
|
|
|
||||||
LL | let mut guard = m.lock().unwrap();
|
LL | let mut guard = m.lock().unwrap();
|
||||||
| --------- has type `MutexGuard<'_, i32>` which is not `Send`
|
| --------- has type `MutexGuard<'_, i32>` which is not `Send`
|
||||||
|
@ -16,7 +16,7 @@ LL | *guard += 1;
|
||||||
LL | }
|
LL | }
|
||||||
| - `mut guard` is later dropped here
|
| - `mut guard` is later dropped here
|
||||||
note: required by a bound in `fake_spawn`
|
note: required by a bound in `fake_spawn`
|
||||||
--> $DIR/issue-71137.rs:6:27
|
--> $DIR/issue-71137.rs:8:27
|
||||||
|
|
|
|
||||||
LL | fn fake_spawn<F: Future + Send + 'static>(f: F) { }
|
LL | fn fake_spawn<F: Future + Send + 'static>(f: F) { }
|
||||||
| ^^^^ required by this bound in `fake_spawn`
|
| ^^^^ required by this bound in `fake_spawn`
|
||||||
|
|
14
src/test/ui/lint/must_not_suspend/gated.rs
Normal file
14
src/test/ui/lint/must_not_suspend/gated.rs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
// edition:2018
|
||||||
|
#![deny(must_not_suspend)] //~ ERROR the `must_not_suspend`
|
||||||
|
//~| ERROR the `must_not_suspend`
|
||||||
|
//~| ERROR the `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() {
|
||||||
|
}
|
54
src/test/ui/lint/must_not_suspend/gated.stderr
Normal file
54
src/test/ui/lint/must_not_suspend/gated.stderr
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
error[E0658]: the `must_not_suspend` lint is unstable
|
||||||
|
--> $DIR/gated.rs:2:1
|
||||||
|
|
|
||||||
|
LL | #![deny(must_not_suspend)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #83310 <https://github.com/rust-lang/rust/issues/83310> for more information
|
||||||
|
= help: add `#![feature(must_not_suspend)]` to the crate attributes to enable
|
||||||
|
|
||||||
|
error[E0658]: the `must_not_suspend` lint is unstable
|
||||||
|
--> $DIR/gated.rs:2:1
|
||||||
|
|
|
||||||
|
LL | #![deny(must_not_suspend)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #83310 <https://github.com/rust-lang/rust/issues/83310> for more information
|
||||||
|
= help: add `#![feature(must_not_suspend)]` to the crate attributes to enable
|
||||||
|
|
||||||
|
error[E0658]: the `must_not_suspend` lint is unstable
|
||||||
|
--> $DIR/gated.rs:2:1
|
||||||
|
|
|
||||||
|
LL | #![deny(must_not_suspend)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #83310 <https://github.com/rust-lang/rust/issues/83310> for more information
|
||||||
|
= help: add `#![feature(must_not_suspend)]` to the crate attributes to enable
|
||||||
|
|
||||||
|
error: `MutexGuard` held across a suspend point, but should not be
|
||||||
|
--> $DIR/gated.rs:9: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/gated.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/gated.rs:9:9
|
||||||
|
|
|
||||||
|
LL | let _guard = m.lock().unwrap();
|
||||||
|
| ^^^^^^
|
||||||
|
help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
|
||||||
|
--> $DIR/gated.rs:9:9
|
||||||
|
|
|
||||||
|
LL | let _guard = m.lock().unwrap();
|
||||||
|
| ^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0658`.
|
19
src/test/ui/lint/must_not_suspend/issue-89562.rs
Normal file
19
src/test/ui/lint/must_not_suspend/issue-89562.rs
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
// edition:2018
|
||||||
|
// run-pass
|
||||||
|
|
||||||
|
use std::sync::Mutex;
|
||||||
|
|
||||||
|
// Copied from the issue. Allow-by-default for now, so run-pass
|
||||||
|
pub async fn foo() {
|
||||||
|
let foo = Mutex::new(1);
|
||||||
|
let lock = foo.lock().unwrap();
|
||||||
|
|
||||||
|
// Prevent mutex lock being held across `.await` point.
|
||||||
|
drop(lock);
|
||||||
|
|
||||||
|
bar().await;
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn bar() {}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -1,4 +1,5 @@
|
||||||
// edition:2018
|
// edition:2018
|
||||||
|
#![feature(must_not_suspend)]
|
||||||
#![deny(must_not_suspend)]
|
#![deny(must_not_suspend)]
|
||||||
|
|
||||||
async fn other() {}
|
async fn other() {}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error: `MutexGuard` held across a suspend point, but should not be
|
error: `MutexGuard` held across a suspend point, but should not be
|
||||||
--> $DIR/mutex.rs:7:9
|
--> $DIR/mutex.rs:8:9
|
||||||
|
|
|
|
||||||
LL | let _guard = m.lock().unwrap();
|
LL | let _guard = m.lock().unwrap();
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
|
@ -7,17 +7,17 @@ LL | other().await;
|
||||||
| ------------- the value is held across this suspend point
|
| ------------- the value is held across this suspend point
|
||||||
|
|
|
|
||||||
note: the lint level is defined here
|
note: the lint level is defined here
|
||||||
--> $DIR/mutex.rs:2:9
|
--> $DIR/mutex.rs:3:9
|
||||||
|
|
|
|
||||||
LL | #![deny(must_not_suspend)]
|
LL | #![deny(must_not_suspend)]
|
||||||
| ^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^
|
||||||
note: holding a MutexGuard across suspend points can cause deadlocks, delays, and cause Futures 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
|
--> $DIR/mutex.rs:8:9
|
||||||
|
|
|
|
||||||
LL | let _guard = m.lock().unwrap();
|
LL | let _guard = m.lock().unwrap();
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
|
help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
|
||||||
--> $DIR/mutex.rs:7:9
|
--> $DIR/mutex.rs:8:9
|
||||||
|
|
|
|
||||||
LL | let _guard = m.lock().unwrap();
|
LL | let _guard = m.lock().unwrap();
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
// edition:2018
|
// edition:2018
|
||||||
// run-pass
|
// run-pass
|
||||||
#![feature(must_not_suspend)]
|
#![feature(must_not_suspend)]
|
||||||
|
#![warn(must_not_suspend)]
|
||||||
|
|
||||||
#[must_not_suspend = "You gotta use Umm's, ya know?"]
|
#[must_not_suspend = "You gotta use Umm's, ya know?"]
|
||||||
struct Umm {
|
struct Umm {
|
||||||
|
|
|
@ -1,19 +1,23 @@
|
||||||
warning: `Umm` held across a suspend point, but should not be
|
warning: `Umm` held across a suspend point, but should not be
|
||||||
--> $DIR/warn.rs:20:9
|
--> $DIR/warn.rs:21:9
|
||||||
|
|
|
|
||||||
LL | let _guard = bar();
|
LL | let _guard = bar();
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
LL | other().await;
|
LL | other().await;
|
||||||
| ------------- the value is held across this suspend point
|
| ------------- the value is held across this suspend point
|
||||||
|
|
|
|
||||||
= note: `#[warn(must_not_suspend)]` on by default
|
note: the lint level is defined here
|
||||||
|
--> $DIR/warn.rs:4:9
|
||||||
|
|
|
||||||
|
LL | #![warn(must_not_suspend)]
|
||||||
|
| ^^^^^^^^^^^^^^^^
|
||||||
note: You gotta use Umm's, ya know?
|
note: You gotta use Umm's, ya know?
|
||||||
--> $DIR/warn.rs:20:9
|
--> $DIR/warn.rs:21:9
|
||||||
|
|
|
|
||||||
LL | let _guard = bar();
|
LL | let _guard = bar();
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
|
help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
|
||||||
--> $DIR/warn.rs:20:9
|
--> $DIR/warn.rs:21:9
|
||||||
|
|
|
|
||||||
LL | let _guard = bar();
|
LL | let _guard = bar();
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
|
|
Loading…
Reference in a new issue