diff options
| author | Joshua Nelson <jnelson@cloudflare.com> | 2022-06-19 13:59:36 -0500 |
|---|---|---|
| committer | Joshua Nelson <jnelson@cloudflare.com> | 2022-06-19 15:31:22 -0500 |
| commit | 1deca0425db3e74a61cb732e729c0777904e549c (patch) | |
| tree | 0243373760ee6aa41c578a4d3a17dc9f026beb53 /src/test/ui/async-await | |
| parent | cdcc53b7dc002ea4a7a28105010c5a1126ee31b7 (diff) | |
| download | rust-1deca0425db3e74a61cb732e729c0777904e549c.tar.gz rust-1deca0425db3e74a61cb732e729c0777904e549c.zip | |
Greatly improve error reporting for futures and generators in `note_obligation_cause_code`
Most futures don't go through this code path, because they're caught by `maybe_note_obligation_cause_for_async_await`. But all generators do, and `maybe_note` is imperfect and doesn't catch all futures. Improve the error message for those it misses. At some point, we may want to consider unifying this with the code for `maybe_note_async_await`, so that `async_await` notes all parent constraints, and `note_obligation` can point to yield points. But both functions are quite complicated, and it's not clear to me how to combine them; this seems like a good incremental improvement.
Diffstat (limited to 'src/test/ui/async-await')
| -rw-r--r-- | src/test/ui/async-await/issue-68112.stderr | 30 | ||||
| -rw-r--r-- | src/test/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr | 40 | ||||
| -rw-r--r-- | src/test/ui/async-await/issue-70935-complex-spans.normal.stderr (renamed from src/test/ui/async-await/issue-70935-complex-spans.stderr) | 8 | ||||
| -rw-r--r-- | src/test/ui/async-await/issue-70935-complex-spans.rs | 16 | ||||
| -rw-r--r-- | src/test/ui/async-await/partial-drop-partial-reinit.rs | 8 | ||||
| -rw-r--r-- | src/test/ui/async-await/partial-drop-partial-reinit.stderr | 20 |
6 files changed, 101 insertions, 21 deletions
diff --git a/src/test/ui/async-await/issue-68112.stderr b/src/test/ui/async-await/issue-68112.stderr index 28d94b14ac9..b8d3e1540d8 100644 --- a/src/test/ui/async-await/issue-68112.stderr +++ b/src/test/ui/async-await/issue-68112.stderr @@ -42,15 +42,27 @@ LL | require_send(send_fut); | = help: the trait `Sync` is not implemented for `RefCell<i32>` = note: required because of the requirements on the impl of `Send` for `Arc<RefCell<i32>>` - = note: required because it appears within the type `[static generator@$DIR/issue-68112.rs:47:31: 47:36]` - = note: required because it appears within the type `std::future::from_generator::GenFuture<[static generator@$DIR/issue-68112.rs:47:31: 47:36]>` - = note: required because it appears within the type `impl Future<Output = Arc<RefCell<i32>>>` - = note: required because it appears within the type `impl Future<Output = Arc<RefCell<i32>>>` - = note: required because it appears within the type `impl Future<Output = Arc<RefCell<i32>>>` - = note: required because it appears within the type `{ResumeTy, impl Future<Output = Arc<RefCell<i32>>>, (), i32, Ready<i32>}` - = note: required because it appears within the type `[static generator@$DIR/issue-68112.rs:55:26: 59:6]` - = note: required because it appears within the type `std::future::from_generator::GenFuture<[static generator@$DIR/issue-68112.rs:55:26: 59:6]>` - = note: required because it appears within the type `impl Future<Output = ()>` +note: required because it's used within this async block + --> $DIR/issue-68112.rs:47:31 + | +LL | async fn ready2<T>(t: T) -> T { t } + | ^^^^^ +note: required because it appears within the type `impl Future<Output = Arc<RefCell<i32>>>` + --> $DIR/issue-68112.rs:48:31 + | +LL | fn make_non_send_future2() -> impl Future<Output = Arc<RefCell<i32>>> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: required because it captures the following types: `ResumeTy`, `impl Future<Output = Arc<RefCell<i32>>>`, `()`, `i32`, `Ready<i32>` +note: required because it's used within this async block + --> $DIR/issue-68112.rs:55:26 + | +LL | let send_fut = async { + | __________________________^ +LL | | let non_send_fut = make_non_send_future2(); +LL | | let _ = non_send_fut.await; +LL | | ready(0).await; +LL | | }; + | |_____^ note: required by a bound in `require_send` --> $DIR/issue-68112.rs:11:25 | diff --git a/src/test/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr b/src/test/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr new file mode 100644 index 00000000000..19fd5eb7c73 --- /dev/null +++ b/src/test/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr @@ -0,0 +1,40 @@ +error[E0277]: `Sender<i32>` cannot be shared between threads safely + --> $DIR/issue-70935-complex-spans.rs:13:45 + | +LL | fn foo(tx: std::sync::mpsc::Sender<i32>) -> impl Future + Send { + | ^^^^^^^^^^^^^^^^^^ `Sender<i32>` cannot be shared between threads safely + | + = help: the trait `Sync` is not implemented for `Sender<i32>` + = note: required because of the requirements on the impl of `Send` for `&Sender<i32>` +note: required because it's used within this closure + --> $DIR/issue-70935-complex-spans.rs:25:13 + | +LL | baz(|| async{ + | _____________^ +LL | | foo(tx.clone()); +LL | | }).await; + | |_________^ +note: required because it's used within this async block + --> $DIR/issue-70935-complex-spans.rs:9:67 + | +LL | async fn baz<T>(_c: impl FnMut() -> T) where T: Future<Output=()> { + | ___________________________________________________________________^ +LL | | +LL | | } + | |_^ + = note: required because it captures the following types: `ResumeTy`, `impl Future<Output = ()>`, `()` +note: required because it's used within this async block + --> $DIR/issue-70935-complex-spans.rs:23:16 + | +LL | async move { + | ________________^ +LL | | +LL | | baz(|| async{ +LL | | foo(tx.clone()); +LL | | }).await; +LL | | } + | |_____^ + +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-70935-complex-spans.stderr b/src/test/ui/async-await/issue-70935-complex-spans.normal.stderr index db309938119..2174f260a71 100644 --- a/src/test/ui/async-await/issue-70935-complex-spans.stderr +++ b/src/test/ui/async-await/issue-70935-complex-spans.normal.stderr @@ -1,12 +1,12 @@ error: future cannot be sent between threads safely - --> $DIR/issue-70935-complex-spans.rs:10:45 + --> $DIR/issue-70935-complex-spans.rs:13:45 | LL | fn foo(tx: std::sync::mpsc::Sender<i32>) -> impl Future + Send { | ^^^^^^^^^^^^^^^^^^ future created by async block is not `Send` | = help: the trait `Sync` is not implemented for `Sender<i32>` note: future is not `Send` as this value is used across an await - --> $DIR/issue-70935-complex-spans.rs:15:11 + --> $DIR/issue-70935-complex-spans.rs:27:11 | LL | baz(|| async{ | _____________- @@ -14,9 +14,9 @@ LL | | foo(tx.clone()); LL | | }).await; | | - ^^^^^^ await occurs here, with the value maybe used later | |_________| - | has type `[closure@$DIR/issue-70935-complex-spans.rs:13:13: 15:10]` which is not `Send` + | has type `[closure@$DIR/issue-70935-complex-spans.rs:25:13: 27:10]` which is not `Send` note: the value is later dropped here - --> $DIR/issue-70935-complex-spans.rs:15:17 + --> $DIR/issue-70935-complex-spans.rs:27:17 | LL | }).await; | ^ diff --git a/src/test/ui/async-await/issue-70935-complex-spans.rs b/src/test/ui/async-await/issue-70935-complex-spans.rs index 2965a7e0654..4bf94fe342c 100644 --- a/src/test/ui/async-await/issue-70935-complex-spans.rs +++ b/src/test/ui/async-await/issue-70935-complex-spans.rs @@ -1,16 +1,28 @@ // edition:2018 +// revisions: normal drop_tracking +// [drop_tracking]compile-flags:-Zdrop-tracking // #70935: Check if we do not emit snippet // with newlines which lead complex diagnostics. use std::future::Future; async fn baz<T>(_c: impl FnMut() -> T) where T: Future<Output=()> { +//[drop_tracking]~^ within this async block } fn foo(tx: std::sync::mpsc::Sender<i32>) -> impl Future + Send { - //~^ ERROR: future cannot be sent between threads safely + //[normal]~^ ERROR: future cannot be sent between threads safely + //[drop_tracking]~^^ ERROR: `Sender<i32>` cannot be shared + //[drop_tracking]~| NOTE: cannot be shared + //[drop_tracking]~| NOTE: requirements on the impl of `Send` + //[drop_tracking]~| NOTE: captures the following types + //[drop_tracking]~| NOTE: in this expansion + //[drop_tracking]~| NOTE: in this expansion + //[drop_tracking]~| NOTE: in this expansion + //[drop_tracking]~| NOTE: in this expansion async move { - baz(|| async{ + //[drop_tracking]~^ within this async block + baz(|| async{ //[drop_tracking]~ NOTE: used within this closure foo(tx.clone()); }).await; } diff --git a/src/test/ui/async-await/partial-drop-partial-reinit.rs b/src/test/ui/async-await/partial-drop-partial-reinit.rs index 73f0ca8153c..4fcfacea3f8 100644 --- a/src/test/ui/async-await/partial-drop-partial-reinit.rs +++ b/src/test/ui/async-await/partial-drop-partial-reinit.rs @@ -5,9 +5,15 @@ fn main() { gimme_send(foo()); //~^ ERROR cannot be sent between threads safely + //~| NOTE cannot be sent + //~| NOTE bound introduced by + //~| NOTE appears within the type + //~| NOTE captures the following types } fn gimme_send<T: Send>(t: T) { +//~^ NOTE required by this bound +//~| NOTE required by a bound drop(t); } @@ -20,6 +26,8 @@ impl Drop for NotSend { impl !Send for NotSend {} async fn foo() { +//~^ NOTE used within this async block +//~| NOTE within this `impl Future let mut x = (NotSend {},); drop(x.0); x.0 = NotSend {}; diff --git a/src/test/ui/async-await/partial-drop-partial-reinit.stderr b/src/test/ui/async-await/partial-drop-partial-reinit.stderr index a1c4957e984..96d0c71f103 100644 --- a/src/test/ui/async-await/partial-drop-partial-reinit.stderr +++ b/src/test/ui/async-await/partial-drop-partial-reinit.stderr @@ -11,13 +11,21 @@ LL | async fn foo() { | = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `NotSend` = note: required because it appears within the type `(NotSend,)` - = note: required because it appears within the type `{ResumeTy, (NotSend,), impl Future<Output = ()>, ()}` - = note: required because it appears within the type `[static generator@$DIR/partial-drop-partial-reinit.rs:22:16: 27:2]` - = note: required because it appears within the type `std::future::from_generator::GenFuture<[static generator@$DIR/partial-drop-partial-reinit.rs:22:16: 27:2]>` - = note: required because it appears within the type `impl Future<Output = ()>` - = note: required because it appears within the type `impl Future<Output = ()>` + = note: required because it captures the following types: `ResumeTy`, `(NotSend,)`, `impl Future<Output = ()>`, `()` +note: required because it's used within this async block + --> $DIR/partial-drop-partial-reinit.rs:28:16 + | +LL | async fn foo() { + | ________________^ +LL | | +LL | | +LL | | let mut x = (NotSend {},); +... | +LL | | bar().await; +LL | | } + | |_^ note: required by a bound in `gimme_send` - --> $DIR/partial-drop-partial-reinit.rs:10:18 + --> $DIR/partial-drop-partial-reinit.rs:14:18 | LL | fn gimme_send<T: Send>(t: T) { | ^^^^ required by this bound in `gimme_send` |
