Improve diagnostics for mismatched type in async main#3039
Closed
Aaron1011 wants to merge 1 commit intotokio-rs:masterfrom
Closed
Improve diagnostics for mismatched type in async main#3039Aaron1011 wants to merge 1 commit intotokio-rs:masterfrom
async main#3039Aaron1011 wants to merge 1 commit intotokio-rs:masterfrom
Conversation
Previously, we wrapped the body of the `async main` function in an
`async` block, which we passed to `block_on`. However, `block_on` is
generic, so an incorrect return type ends up creating a diagnostic
pointing a `block_on`, not the user's code. Since the call to `block_on`
is generated by the `#[tokio::main]` macro, it ended up with a span of
the `#[tokio::main]` attribute, producing a confusing diagnostic.
We now wrap the body of the `async main` function in a new
`async main_inner` function. This asserts a return type of `()` earlier
on, producing a diagnostic.
Given this code:
```rust
async fn main() {
Ok(())
}
```
We currently produce the error:
```
error[E0308]: mismatched types
--> src/main.rs:1:1
|
1 | #[tokio::main]
| ^^^^^^^^^^^^^^- help: try adding a semicolon: `;`
| |
| expected `()`, found enum `std::result::Result`
|
= note: expected unit type `()`
found enum `std::result::Result<(), _>`
= note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
```
With this PR, we produce:
```
error[E0308]: mismatched types
--> src/main.rs:3:5
|
3 | Ok(())
| ^^^^^^- help: try adding a semicolon: `;`
| |
| expected `()`, found enum `std::result::Result`
|
= note: expected unit type `()`
found enum `std::result::Result<(), _>`
```
d770695 to
8b060aa
Compare
Contributor
Author
|
I didn't realize that |
taiki-e
reviewed
Oct 24, 2020
Member
There was a problem hiding this comment.
Thanks for the PR. Unfortunately, this approach (split an async fn to two async or normal fns) causes a breaking change because #[tokio::main] accepts arguments. The self argument can be handled in the same way as async-trait, but we know that some regressions occur. (see dtolnay/async-trait#122 (comment))
Member
|
If macro generate code like the following, it should work. block_on(async {
let res: #return_ty = #body;
return res;
})(Note: If the return type contains impl trait, macro should omit the generation of |
Member
|
@Aaron1011 Are you interested in continuing to work on this PR? |
This was referenced Mar 29, 2024
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Previously, we wrapped the body of the
async mainfunction in anasyncblock, which we passed toblock_on. However,block_onisgeneric, so an incorrect return type ends up creating a diagnostic
pointing a
block_on, not the user's code. Since the call toblock_onis generated by the
#[tokio::main]macro, it ended up with a span ofthe
#[tokio::main]attribute, producing a confusing diagnostic.We now wrap the body of the
async mainfunction in a newasync main_innerfunction. This asserts a return type of()earlieron, producing a diagnostic.
Given this code:
We currently produce the error:
With this PR, we produce:
Tokio doesn't appear to have any kind of UI testing setup, so I'm not sure how to test the error message produced here.