Repository navigation
note_obligation_cause reporting for non-async/await not optimal #70818
Copy link
Copy link
Closed
Labels
A-async-awaitArea: Async & AwaitArea: Async & AwaitA-diagnosticsArea: Messages for errors, warnings, and lintsArea: Messages for errors, warnings, and lintsAsyncAwait-TriagedAsync-await issues that have been triaged during a working group meeting.Async-await issues that have been triaged during a working group meeting.C-enhancementCategory: An issue proposing an enhancement or a PR with one.Category: An issue proposing an enhancement or a PR with one.E-mediumCall for participation: Medium difficulty. Experience needed to fix: Intermediate.Call for participation: Medium difficulty. Experience needed to fix: Intermediate.E-mentorCall for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion.Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion.P-mediumMedium priorityMedium priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Description
Consider the following code:
fn d<T: Sized>(t: T) -> impl std::future::Future<Output = T> + Send {
async { t }
}This produces the following error message in cargo build:
error[E0277]: `T` cannot be sent between threads safely
--> src/main.rs:27:25
|
27 | fn d<T: Sized>(t: T) -> impl std::future::Future<Output = T> + Send {
| -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `T` cannot be sent between threads safely
| |
| help: consider further restricting this bound: `T: std::marker::Send +`
28 | async { t }
| ----------- this returned value is of type `impl std::future::Future`
|
= help: within `impl std::future::Future`, the trait `std::marker::Send` is not implemented for `T`
= note: required because it appears within the type `[static generator@src/main.rs:28:11: 28:16 t:T _]`
= note: required because it appears within the type `std::future::GenFuture<[static generator@src/main.rs:28:11: 28:16 t:T _]>`
= note: required because it appears within the type `impl std::future::Future`
= note: the return type of a function must have a statically known size
and the following tooltip in VS Code:
`T` cannot be sent between threads safely
`T` cannot be sent between threads safely
help: within `impl std::future::Future`, the trait `std::marker::Send` is not implemented for `T`
note: required because it appears within the type `[static generator@src/main.rs:28:11: 28:16 t:T _]`
note: required because it appears within the type `std::future::GenFuture<[static generator@src/main.rs:28:11: 28:16 t:T _]>`
note: required because it appears within the type `impl std::future::Future`
note: the return type of a function must have a statically known sizerustc(E0277)
future.rs(21, 58): within this `impl std::future::Future`
main.rs(27, 18): `T` cannot be sent between threads safely
main.rs(28, 5): this returned value is of type `impl std::future::Future`
@eddyb asked me to open this issue because the notes are mostly confusing (at least they won’t help mere mortals) and said that the message should not mention GenFuture nor [static generator ...]. He used the following code for a larger error message (playground):
async fn foo<T>(x: T) -> T {
x
}
fn assert_send(_: impl Send) {}
fn test<T>(x: T) {
assert_send(foo(x));
}Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
A-async-awaitArea: Async & AwaitArea: Async & AwaitA-diagnosticsArea: Messages for errors, warnings, and lintsArea: Messages for errors, warnings, and lintsAsyncAwait-TriagedAsync-await issues that have been triaged during a working group meeting.Async-await issues that have been triaged during a working group meeting.C-enhancementCategory: An issue proposing an enhancement or a PR with one.Category: An issue proposing an enhancement or a PR with one.E-mediumCall for participation: Medium difficulty. Experience needed to fix: Intermediate.Call for participation: Medium difficulty. Experience needed to fix: Intermediate.E-mentorCall for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion.Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion.P-mediumMedium priorityMedium priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Type
Projects
- StatusShow more project fieldsDone
Activity
nikomatsakis commentedon Apr 6, 2020
Hmm, so the error message for the second example is the following:
I think it would be helpful to try and enumerate what the "ideal" error in these two cases would look like. I see a few problems:
GenFutureand static generators) are really leaking implementation details of rustc. Maybe we should just suppress those particular types.xin both cases, we should probably underline that?async fn, we talk about animpl Futurethat the user didn't even write, which is not particularly great.eddyb commentedon Apr 6, 2020
@nikomatsakis Also, I think what happened in the past is that #64895 + #65345 improved the errors when a value is kept across an
.awaitbut not when something is just captured... maybe the suboptimal output is only shown if there is no.awaitat all in the body of theasync fn?So this might be a strawman example we've stumbled over?
tmandry commentedon Apr 8, 2020
We could fix this by outputting the nicer error messages, which does seem to happen anytime there exists an
awaitin the async fn.The reason we don't output the nice error messages is that this code doesn't create a
GeneratorInteriorTypeCausefor types which are captured from the generator's environment (as in the case of async fn args). As soon as we have an await anywhere in the function, a cause is added forTand we get the nice error message (from this code):However, this logic can still lead to bad diagnostics for captured vars. For example, when we drop
xbefore awaiting, the diagnostics claimxmay still be used after the await:So what we need is a way to express a cause for captured vars which doesn't include an await/yield point, and for the diagnostics code to handle these causes.
Rollup merge of rust-lang#71923 - csmoe:issue-70818, r=tmandry
Auto merge of rust-lang#71923 - csmoe:issue-70818, r=tmandry