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:
Matthias Krüger 2021-11-01 03:33:03 +01:00 committed by GitHub
commit c65400548a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 114 additions and 16 deletions

View file

@ -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
); );

View file

@ -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! {

View file

@ -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.

View file

@ -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`

View file

@ -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;

View file

@ -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`

View 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() {
}

View 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`.

View 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() {}

View file

@ -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() {}

View file

@ -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();
| ^^^^^^ | ^^^^^^

View file

@ -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 {

View file

@ -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();
| ^^^^^^ | ^^^^^^