diff options
| author | bors <bors@rust-lang.org> | 2019-12-11 19:39:06 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2019-12-11 19:39:06 +0000 |
| commit | 27d6f55f47e8875e71083a28ed84ea5a88e1b596 (patch) | |
| tree | 2f0866ff8e08df5d73b14362a3a4c0d9991dbfd5 /src/test/ui | |
| parent | 90b957a17c1abba979aa41234ce0993a61030e67 (diff) | |
| parent | 5cd9f22464a3ae2620c384094986d9549eca182e (diff) | |
Auto merge of #65345 - davidtwco:issue-64130-async-send-sync-error-improvements, r=nikomatsakis
async/await: improve not-send errors, part 2 Part of #64130. Fixes #65667. This PR improves the errors introduced in #64895 so that they have specialized messages for `Send` and `Sync`. r? @nikomatsakis
Diffstat (limited to 'src/test/ui')
| -rw-r--r-- | src/test/ui/async-await/async-fn-nonsend.rs | 8 | ||||
| -rw-r--r-- | src/test/ui/async-await/async-fn-nonsend.stderr | 91 | ||||
| -rw-r--r-- | src/test/ui/async-await/issue-64130-1-sync.rs | 23 | ||||
| -rw-r--r-- | src/test/ui/async-await/issue-64130-1-sync.stderr | 22 | ||||
| -rw-r--r-- | src/test/ui/async-await/issue-64130-2-send.rs | 23 | ||||
| -rw-r--r-- | src/test/ui/async-await/issue-64130-2-send.stderr | 22 | ||||
| -rw-r--r-- | src/test/ui/async-await/issue-64130-3-other.rs | 25 | ||||
| -rw-r--r-- | src/test/ui/async-await/issue-64130-3-other.stderr | 24 | ||||
| -rw-r--r-- | src/test/ui/async-await/issue-64130-4-async-move.rs | 28 | ||||
| -rw-r--r-- | src/test/ui/async-await/issue-64130-4-async-move.stderr | 22 | ||||
| -rw-r--r-- | src/test/ui/async-await/issue-64130-non-send-future-diags.rs | 12 | ||||
| -rw-r--r-- | src/test/ui/async-await/issue-64130-non-send-future-diags.stderr | 11 | ||||
| -rw-r--r-- | src/test/ui/generator/not-send-sync.rs | 2 | ||||
| -rw-r--r-- | src/test/ui/generator/not-send-sync.stderr | 15 |
14 files changed, 265 insertions, 63 deletions
diff --git a/src/test/ui/async-await/async-fn-nonsend.rs b/src/test/ui/async-await/async-fn-nonsend.rs index 1f1bf4250ea..645c903c6ba 100644 --- a/src/test/ui/async-await/async-fn-nonsend.rs +++ b/src/test/ui/async-await/async-fn-nonsend.rs @@ -48,10 +48,10 @@ fn assert_send(_: impl Send) {} pub fn pass_assert() { assert_send(local_dropped_before_await()); - //~^ ERROR `std::rc::Rc<()>` cannot be sent between threads safely + //~^ ERROR future cannot be sent between threads safely assert_send(non_send_temporary_in_match()); - //~^ ERROR `std::rc::Rc<()>` cannot be sent between threads safely + //~^ ERROR future cannot be sent between threads safely assert_send(non_sync_with_method_call()); - //~^ ERROR `dyn std::fmt::Write` cannot be sent between threads safely - //~^^ ERROR `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between threads safely + //~^ ERROR future cannot be sent between threads safely + //~^^ ERROR future cannot be sent between threads safely } diff --git a/src/test/ui/async-await/async-fn-nonsend.stderr b/src/test/ui/async-await/async-fn-nonsend.stderr index 6e89deb407e..5c870ca2d02 100644 --- a/src/test/ui/async-await/async-fn-nonsend.stderr +++ b/src/test/ui/async-await/async-fn-nonsend.stderr @@ -1,79 +1,88 @@ -error[E0277]: `std::rc::Rc<()>` cannot be sent between threads safely +error: future cannot be sent between threads safely --> $DIR/async-fn-nonsend.rs:50:5 | LL | fn assert_send(_: impl Send) {} | ----------- ---- required by this bound in `assert_send` ... LL | assert_send(local_dropped_before_await()); - | ^^^^^^^^^^^ `std::rc::Rc<()>` cannot be sent between threads safely + | ^^^^^^^^^^^ future returned by `local_dropped_before_await` is not `Send` | = help: within `impl std::future::Future`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<()>` - = note: required because it appears within the type `impl std::fmt::Debug` - = note: required because it appears within the type `{impl std::fmt::Debug, impl std::future::Future, impl std::future::Future, ()}` - = note: required because it appears within the type `[static generator@$DIR/async-fn-nonsend.rs:21:39: 26:2 {impl std::fmt::Debug, impl std::future::Future, impl std::future::Future, ()}]` - = note: required because it appears within the type `std::future::GenFuture<[static generator@$DIR/async-fn-nonsend.rs:21:39: 26:2 {impl std::fmt::Debug, impl std::future::Future, impl std::future::Future, ()}]>` - = note: required because it appears within the type `impl std::future::Future` - = note: required because it appears within the type `impl std::future::Future` +note: future is not `Send` as this value is used across an await + --> $DIR/async-fn-nonsend.rs:25:5 + | +LL | let x = non_send(); + | - has type `impl std::fmt::Debug` +LL | drop(x); +LL | fut().await; + | ^^^^^^^^^^^ await occurs here, with `x` maybe used later +LL | } + | - `x` is later dropped here -error[E0277]: `std::rc::Rc<()>` cannot be sent between threads safely +error: future cannot be sent between threads safely --> $DIR/async-fn-nonsend.rs:52:5 | LL | fn assert_send(_: impl Send) {} | ----------- ---- required by this bound in `assert_send` ... LL | assert_send(non_send_temporary_in_match()); - | ^^^^^^^^^^^ `std::rc::Rc<()>` cannot be sent between threads safely + | ^^^^^^^^^^^ future returned by `non_send_temporary_in_match` is not `Send` | = help: within `impl std::future::Future`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<()>` - = note: required because it appears within the type `impl std::fmt::Debug` - = note: required because it appears within the type `{impl std::fmt::Debug, std::option::Option<impl std::fmt::Debug>, impl std::future::Future, impl std::future::Future, ()}` - = note: required because it appears within the type `[static generator@$DIR/async-fn-nonsend.rs:28:40: 37:2 {impl std::fmt::Debug, std::option::Option<impl std::fmt::Debug>, impl std::future::Future, impl std::future::Future, ()}]` - = note: required because it appears within the type `std::future::GenFuture<[static generator@$DIR/async-fn-nonsend.rs:28:40: 37:2 {impl std::fmt::Debug, std::option::Option<impl std::fmt::Debug>, impl std::future::Future, impl std::future::Future, ()}]>` - = note: required because it appears within the type `impl std::future::Future` - = note: required because it appears within the type `impl std::future::Future` +note: future is not `Send` as this value is used across an await + --> $DIR/async-fn-nonsend.rs:34:20 + | +LL | match Some(non_send()) { + | ---------- has type `impl std::fmt::Debug` +LL | Some(_) => fut().await, + | ^^^^^^^^^^^ await occurs here, with `non_send()` maybe used later +... +LL | } + | - `non_send()` is later dropped here -error[E0277]: `dyn std::fmt::Write` cannot be sent between threads safely +error: future cannot be sent between threads safely --> $DIR/async-fn-nonsend.rs:54:5 | LL | fn assert_send(_: impl Send) {} | ----------- ---- required by this bound in `assert_send` ... LL | assert_send(non_sync_with_method_call()); - | ^^^^^^^^^^^ `dyn std::fmt::Write` cannot be sent between threads safely + | ^^^^^^^^^^^ future returned by `non_sync_with_method_call` is not `Send` | = help: the trait `std::marker::Send` is not implemented for `dyn std::fmt::Write` - = note: required because of the requirements on the impl of `std::marker::Send` for `&mut dyn std::fmt::Write` - = note: required because it appears within the type `std::fmt::Formatter<'_>` - = note: required because of the requirements on the impl of `std::marker::Send` for `&mut std::fmt::Formatter<'_>` - = note: required because it appears within the type `for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, bool, impl std::future::Future, impl std::future::Future, ()}` - = note: required because it appears within the type `[static generator@$DIR/async-fn-nonsend.rs:39:38: 45:2 for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, bool, impl std::future::Future, impl std::future::Future, ()}]` - = note: required because it appears within the type `std::future::GenFuture<[static generator@$DIR/async-fn-nonsend.rs:39:38: 45:2 for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, bool, impl std::future::Future, impl std::future::Future, ()}]>` - = note: required because it appears within the type `impl std::future::Future` - = note: required because it appears within the type `impl std::future::Future` +note: future is not `Send` as this value is used across an await + --> $DIR/async-fn-nonsend.rs:43:9 + | +LL | let f: &mut std::fmt::Formatter = panic!(); + | - has type `&mut std::fmt::Formatter<'_>` +LL | if non_sync().fmt(f).unwrap() == () { +LL | fut().await; + | ^^^^^^^^^^^ await occurs here, with `f` maybe used later +LL | } +LL | } + | - `f` is later dropped here -error[E0277]: `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between threads safely +error: future cannot be sent between threads safely --> $DIR/async-fn-nonsend.rs:54:5 | LL | fn assert_send(_: impl Send) {} | ----------- ---- required by this bound in `assert_send` ... LL | assert_send(non_sync_with_method_call()); - | ^^^^^^^^^^^ `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between threads safely + | ^^^^^^^^^^^ future returned by `non_sync_with_method_call` is not `Send` | = help: within `std::fmt::ArgumentV1<'_>`, the trait `std::marker::Sync` is not implemented for `*mut (dyn std::ops::Fn() + 'static)` - = note: required because it appears within the type `std::marker::PhantomData<*mut (dyn std::ops::Fn() + 'static)>` - = note: required because it appears within the type `core::fmt::Void` - = note: required because it appears within the type `&core::fmt::Void` - = note: required because it appears within the type `std::fmt::ArgumentV1<'_>` - = note: required because of the requirements on the impl of `std::marker::Send` for `std::slice::Iter<'_, std::fmt::ArgumentV1<'_>>` - = note: required because it appears within the type `std::fmt::Formatter<'_>` - = note: required because of the requirements on the impl of `std::marker::Send` for `&mut std::fmt::Formatter<'_>` - = note: required because it appears within the type `for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, bool, impl std::future::Future, impl std::future::Future, ()}` - = note: required because it appears within the type `[static generator@$DIR/async-fn-nonsend.rs:39:38: 45:2 for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, bool, impl std::future::Future, impl std::future::Future, ()}]` - = note: required because it appears within the type `std::future::GenFuture<[static generator@$DIR/async-fn-nonsend.rs:39:38: 45:2 for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, bool, impl std::future::Future, impl std::future::Future, ()}]>` - = note: required because it appears within the type `impl std::future::Future` - = note: required because it appears within the type `impl std::future::Future` +note: future is not `Send` as this value is used across an await + --> $DIR/async-fn-nonsend.rs:43:9 + | +LL | let f: &mut std::fmt::Formatter = panic!(); + | - has type `&mut std::fmt::Formatter<'_>` +LL | if non_sync().fmt(f).unwrap() == () { +LL | fut().await; + | ^^^^^^^^^^^ await occurs here, with `f` maybe used later +LL | } +LL | } + | - `f` is later dropped here error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/async-await/issue-64130-1-sync.rs b/src/test/ui/async-await/issue-64130-1-sync.rs new file mode 100644 index 00000000000..cc5ca89f03a --- /dev/null +++ b/src/test/ui/async-await/issue-64130-1-sync.rs @@ -0,0 +1,23 @@ +#![feature(optin_builtin_traits)] +// edition:2018 + +// This tests the the specialized async-await-specific error when futures don't implement an +// auto trait (which is specifically Sync) due to some type that was captured. + +struct Foo; + +impl !Sync for Foo {} + +fn is_sync<T: Sync>(t: T) { } + +async fn bar() { + let x = Foo; + baz().await; +} + +async fn baz() { } + +fn main() { + is_sync(bar()); + //~^ ERROR future cannot be shared between threads safely +} diff --git a/src/test/ui/async-await/issue-64130-1-sync.stderr b/src/test/ui/async-await/issue-64130-1-sync.stderr new file mode 100644 index 00000000000..8beb31f152a --- /dev/null +++ b/src/test/ui/async-await/issue-64130-1-sync.stderr @@ -0,0 +1,22 @@ +error: future cannot be shared between threads safely + --> $DIR/issue-64130-1-sync.rs:21:5 + | +LL | fn is_sync<T: Sync>(t: T) { } + | ------- ---- required by this bound in `is_sync` +... +LL | is_sync(bar()); + | ^^^^^^^ future returned by `bar` is not `Sync` + | + = help: within `impl std::future::Future`, the trait `std::marker::Sync` is not implemented for `Foo` +note: future is not `Sync` as this value is used across an await + --> $DIR/issue-64130-1-sync.rs:15:5 + | +LL | let x = Foo; + | - has type `Foo` +LL | baz().await; + | ^^^^^^^^^^^ await occurs here, with `x` maybe used later +LL | } + | - `x` is later dropped here + +error: aborting due to previous error + diff --git a/src/test/ui/async-await/issue-64130-2-send.rs b/src/test/ui/async-await/issue-64130-2-send.rs new file mode 100644 index 00000000000..1efe2ab3f85 --- /dev/null +++ b/src/test/ui/async-await/issue-64130-2-send.rs @@ -0,0 +1,23 @@ +#![feature(optin_builtin_traits)] +// edition:2018 + +// This tests the the specialized async-await-specific error when futures don't implement an +// auto trait (which is specifically Send) due to some type that was captured. + +struct Foo; + +impl !Send for Foo {} + +fn is_send<T: Send>(t: T) { } + +async fn bar() { + let x = Foo; + baz().await; +} + +async fn baz() { } + +fn main() { + is_send(bar()); + //~^ ERROR future cannot be sent between threads safely +} diff --git a/src/test/ui/async-await/issue-64130-2-send.stderr b/src/test/ui/async-await/issue-64130-2-send.stderr new file mode 100644 index 00000000000..823b88e18c5 --- /dev/null +++ b/src/test/ui/async-await/issue-64130-2-send.stderr @@ -0,0 +1,22 @@ +error: future cannot be sent between threads safely + --> $DIR/issue-64130-2-send.rs:21:5 + | +LL | fn is_send<T: Send>(t: T) { } + | ------- ---- required by this bound in `is_send` +... +LL | is_send(bar()); + | ^^^^^^^ future returned by `bar` is not `Send` + | + = help: within `impl std::future::Future`, the trait `std::marker::Send` is not implemented for `Foo` +note: future is not `Send` as this value is used across an await + --> $DIR/issue-64130-2-send.rs:15:5 + | +LL | let x = Foo; + | - has type `Foo` +LL | baz().await; + | ^^^^^^^^^^^ await occurs here, with `x` maybe used later +LL | } + | - `x` is later dropped here + +error: aborting due to previous error + diff --git a/src/test/ui/async-await/issue-64130-3-other.rs b/src/test/ui/async-await/issue-64130-3-other.rs new file mode 100644 index 00000000000..901544edba1 --- /dev/null +++ b/src/test/ui/async-await/issue-64130-3-other.rs @@ -0,0 +1,25 @@ +#![feature(optin_builtin_traits)] +// edition:2018 + +// This tests the the unspecialized async-await-specific error when futures don't implement an +// auto trait (which is not Send or Sync) due to some type that was captured. + +auto trait Qux { } + +struct Foo; + +impl !Qux for Foo {} + +fn is_qux<T: Qux>(t: T) { } + +async fn bar() { + let x = Foo; + baz().await; +} + +async fn baz() { } + +fn main() { + is_qux(bar()); + //~^ ERROR the trait bound `Foo: Qux` is not satisfied in `impl std::future::Future` +} diff --git a/src/test/ui/async-await/issue-64130-3-other.stderr b/src/test/ui/async-await/issue-64130-3-other.stderr new file mode 100644 index 00000000000..155c5cc8ea1 --- /dev/null +++ b/src/test/ui/async-await/issue-64130-3-other.stderr @@ -0,0 +1,24 @@ +error[E0277]: the trait bound `Foo: Qux` is not satisfied in `impl std::future::Future` + --> $DIR/issue-64130-3-other.rs:23:5 + | +LL | fn is_qux<T: Qux>(t: T) { } + | ------ --- required by this bound in `is_qux` +... +LL | is_qux(bar()); + | ^^^^^^ within `impl std::future::Future`, the trait `Qux` is not implemented for `Foo` + | + = help: the following implementations were found: + <Foo as Qux> +note: future does not implement `Qux` as this value is used across an await + --> $DIR/issue-64130-3-other.rs:17:5 + | +LL | let x = Foo; + | - has type `Foo` +LL | baz().await; + | ^^^^^^^^^^^ await occurs here, with `x` maybe used later +LL | } + | - `x` is later dropped here + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/async-await/issue-64130-4-async-move.rs b/src/test/ui/async-await/issue-64130-4-async-move.rs new file mode 100644 index 00000000000..2538f34351e --- /dev/null +++ b/src/test/ui/async-await/issue-64130-4-async-move.rs @@ -0,0 +1,28 @@ +// edition:2018 +use std::any::Any; +use std::future::Future; + +struct Client(Box<dyn Any + Send>); + +impl Client { + fn status(&self) -> u16 { + 200 + } +} + +async fn get() { } + +pub fn foo() -> impl Future + Send { + //~^ ERROR future cannot be sent between threads safely + let client = Client(Box::new(true)); + async move { + match client.status() { + 200 => { + let _x = get().await; + }, + _ => (), + } + } +} + +fn main() {} diff --git a/src/test/ui/async-await/issue-64130-4-async-move.stderr b/src/test/ui/async-await/issue-64130-4-async-move.stderr new file mode 100644 index 00000000000..ddbb469b99c --- /dev/null +++ b/src/test/ui/async-await/issue-64130-4-async-move.stderr @@ -0,0 +1,22 @@ +error: future cannot be sent between threads safely + --> $DIR/issue-64130-4-async-move.rs:15:17 + | +LL | pub fn foo() -> impl Future + Send { + | ^^^^^^^^^^^^^^^^^^ future returned by `foo` is not `Send` + | + = help: the trait `std::marker::Sync` is not implemented for `(dyn std::any::Any + std::marker::Send + 'static)` +note: future is not `Send` as this value is used across an await + --> $DIR/issue-64130-4-async-move.rs:21:26 + | +LL | match client.status() { + | ------ has type `&Client` +LL | 200 => { +LL | let _x = get().await; + | ^^^^^^^^^^^ await occurs here, with `client` maybe used later +... +LL | } + | - `client` is later dropped here + = note: the return type of a function must have a statically known size + +error: aborting due to previous error + diff --git a/src/test/ui/async-await/issue-64130-non-send-future-diags.rs b/src/test/ui/async-await/issue-64130-non-send-future-diags.rs index 1936d1a2ed5..656ade67c71 100644 --- a/src/test/ui/async-await/issue-64130-non-send-future-diags.rs +++ b/src/test/ui/async-await/issue-64130-non-send-future-diags.rs @@ -1,10 +1,10 @@ // edition:2018 -use std::sync::Mutex; +// This tests the basic example case for the async-await-specific error. -fn is_send<T: Send>(t: T) { +use std::sync::Mutex; -} +fn is_send<T: Send>(t: T) { } async fn foo() { bar(&Mutex::new(22)).await; @@ -15,11 +15,9 @@ async fn bar(x: &Mutex<u32>) { baz().await; } -async fn baz() { - -} +async fn baz() { } fn main() { is_send(foo()); - //~^ ERROR `std::sync::MutexGuard<'_, u32>` cannot be sent between threads safely [E0277] + //~^ ERROR future cannot be sent between threads safely } diff --git a/src/test/ui/async-await/issue-64130-non-send-future-diags.stderr b/src/test/ui/async-await/issue-64130-non-send-future-diags.stderr index 9e9fc52e30b..662407f7017 100644 --- a/src/test/ui/async-await/issue-64130-non-send-future-diags.stderr +++ b/src/test/ui/async-await/issue-64130-non-send-future-diags.stderr @@ -1,14 +1,14 @@ -error[E0277]: `std::sync::MutexGuard<'_, u32>` cannot be sent between threads safely - --> $DIR/issue-64130-non-send-future-diags.rs:23:5 +error: future cannot be sent between threads safely + --> $DIR/issue-64130-non-send-future-diags.rs:21:5 | -LL | fn is_send<T: Send>(t: T) { +LL | fn is_send<T: Send>(t: T) { } | ------- ---- required by this bound in `is_send` ... LL | is_send(foo()); - | ^^^^^^^ `std::sync::MutexGuard<'_, u32>` cannot be sent between threads safely + | ^^^^^^^ future returned by `foo` is not `Send` | = help: within `impl std::future::Future`, the trait `std::marker::Send` is not implemented for `std::sync::MutexGuard<'_, u32>` -note: future does not implement `std::marker::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 | LL | let g = x.lock().unwrap(); @@ -20,4 +20,3 @@ LL | } error: aborting due to previous error -For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/generator/not-send-sync.rs b/src/test/ui/generator/not-send-sync.rs index ae0a288bbb4..0db01c6f756 100644 --- a/src/test/ui/generator/not-send-sync.rs +++ b/src/test/ui/generator/not-send-sync.rs @@ -7,7 +7,7 @@ fn main() { fn assert_send<T: Send>(_: T) {} assert_sync(|| { - //~^ ERROR: E0277 + //~^ ERROR: future cannot be shared between threads safely let a = Cell::new(2); yield; }); diff --git a/src/test/ui/generator/not-send-sync.stderr b/src/test/ui/generator/not-send-sync.stderr index 620db245d3e..0ac1d189b79 100644 --- a/src/test/ui/generator/not-send-sync.stderr +++ b/src/test/ui/generator/not-send-sync.stderr @@ -11,18 +11,25 @@ LL | assert_send(|| { = note: required because of the requirements on the impl of `std::marker::Send` for `&std::cell::Cell<i32>` = note: required because it appears within the type `[generator@$DIR/not-send-sync.rs:16:17: 20:6 a:&std::cell::Cell<i32> _]` -error[E0277]: `std::cell::Cell<i32>` cannot be shared between threads safely +error: future cannot be shared between threads safely --> $DIR/not-send-sync.rs:9:5 | LL | fn assert_sync<T: Sync>(_: T) {} | ----------- ---- required by this bound in `main::assert_sync` ... LL | assert_sync(|| { - | ^^^^^^^^^^^ `std::cell::Cell<i32>` cannot be shared between threads safely + | ^^^^^^^^^^^ future returned by `main` is not `Sync` | = help: within `[generator@$DIR/not-send-sync.rs:9:17: 13:6 {std::cell::Cell<i32>, ()}]`, the trait `std::marker::Sync` is not implemented for `std::cell::Cell<i32>` - = note: required because it appears within the type `{std::cell::Cell<i32>, ()}` - = note: required because it appears within the type `[generator@$DIR/not-send-sync.rs:9:17: 13:6 {std::cell::Cell<i32>, ()}]` +note: future is not `Sync` as this value is used across an yield + --> $DIR/not-send-sync.rs:12:9 + | +LL | let a = Cell::new(2); + | - has type `std::cell::Cell<i32>` +LL | yield; + | ^^^^^ yield occurs here, with `a` maybe used later +LL | }); + | - `a` is later dropped here error: aborting due to 2 previous errors |
