Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: better spans in #[tokio::main] output #5619

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 23 additions & 24 deletions tests-build/tests/fail/macros_type_mismatch.stderr
Original file line number Diff line number Diff line change
@@ -1,47 +1,46 @@
error[E0308]: mismatched types
--> $DIR/macros_type_mismatch.rs:5:5
|
4 | async fn missing_semicolon_or_return_type() {
| - help: a return type might be missing here: `-> _`
5 | Ok(())
| ^^^^^^ expected `()`, found enum `Result`
| ^^^^^^- help: consider using a semicolon here: `;`
| |
| expected `()`, found enum `Result`
|
= note: expected unit type `()`
found enum `Result<(), _>`

error[E0308]: mismatched types
--> $DIR/macros_type_mismatch.rs:10:5
|
9 | async fn missing_return_type() {
| - help: a return type might be missing here: `-> _`
10 | return Ok(());
| ^^^^^^^^^^^^^^ expected `()`, found enum `Result`
|
= note: expected unit type `()`
found enum `Result<(), _>`
--> $DIR/macros_type_mismatch.rs:8:1
|
8 | #[tokio::main]
| ^^^^^^^^^^^^^^ expected `()`, found enum `Result`
9 | async fn missing_return_type() {
| - help: a return type might be missing here: `-> _`
|
= note: expected unit type `()`
found enum `Result<(), _>`
= note: this error originates in the attribute macro `tokio::main` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0308]: mismatched types
--> $DIR/macros_type_mismatch.rs:23:5
--> $DIR/macros_type_mismatch.rs:14:31
|
14 | async fn extra_semicolon() -> Result<(), ()> {
| -------------- expected `Result<(), ()>` because of return type
| --------------- ^^^^^^^^^^^^^^ expected enum `Result`, found `()`
| |
| implicitly returns `()` as its body has no tail or `return` expression
...
23 | Ok(());
| ^^^^^^^ expected enum `Result`, found `()`
| - help: remove this semicolon to return this value
|
= note: expected enum `Result<(), ()>`
found unit type `()`
help: try adding an expression at the end of the block
|
23 ~ Ok(());;
24 + Ok(())
|

error[E0308]: mismatched types
--> $DIR/macros_type_mismatch.rs:32:5
--> $DIR/macros_type_mismatch.rs:29:1
|
29 | #[tokio::main]
| ^^^^^^^^^^^^^^ expected `()`, found integer
30 | async fn issue_4635() {
| - help: try adding a return type: `-> i32`
31 | return 1;
32 | ;
| ^ expected `()`, found integer
|
= note: this error originates in the attribute macro `tokio::main` (in Nightly builds, run with -Z macro-backtrace for more info)
50 changes: 38 additions & 12 deletions tokio-macros/src/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ fn parse_knobs(mut input: syn::ItemFn, is_test: bool, config: FinalConfig) -> To
let body = &input.block;
let brace_token = input.block.brace_token;
let body_ident = quote! { body };
let block_expr = quote_spanned! {last_stmt_end_span=>
let block_expr = quote_spanned! {Span::call_site()=>
#[allow(clippy::expect_used, clippy::diverging_sub_expression)]
{
return #rt
Expand All @@ -396,22 +396,48 @@ fn parse_knobs(mut input: syn::ItemFn, is_test: bool, config: FinalConfig) -> To
//
// We don't do this for the main function as it should only be used once so
// there will be no benefit.

// FIXME: this is ... rather repetitive
let (output_type, body_cast) = match &input.sig.output {
// For functions with no return value syn doesn't print anything,
// but that doesn't work as `Output` for our boxed `Future`, so
// default to `()` (the same type as the function output).
syn::ReturnType::Default => {
let t = quote! { () };
let b = quote! {
async {
#[allow(unreachable_code)]
{
let _body_cast: () = #body;
_body_cast;
}
}
};
(t, b)
}
syn::ReturnType::Type(_, ret_type) => {
let t = quote! { #ret_type };
let b = quote! {
async {
#[allow(unreachable_code)]
{
let _body_cast: #ret_type = #body;
_body_cast
}
}
};
(t, b)
}
};
let body = if is_test {
let output_type = match &input.sig.output {
// For functions with no return value syn doesn't print anything,
// but that doesn't work as `Output` for our boxed `Future`, so
// default to `()` (the same type as the function output).
syn::ReturnType::Default => quote! { () },
syn::ReturnType::Type(_, ret_type) => quote! { #ret_type },
};
quote! {
let body = async #body;
quote_spanned! {last_stmt_end_span=>
let body = #body_cast;
#crate_path::pin!(body);
let body: ::std::pin::Pin<&mut dyn ::std::future::Future<Output = #output_type>> = body;
}
} else {
quote! {
let body = async #body;
quote_spanned! {last_stmt_end_span=>
let body = #body_cast;
}
};

Expand Down