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

#[tokio::main] allowing arbitrary return values from main #4635

Closed
monoclex opened this issue Apr 23, 2022 · 4 comments · Fixed by #4636
Closed

#[tokio::main] allowing arbitrary return values from main #4635

monoclex opened this issue Apr 23, 2022 · 4 comments · Fixed by #4636
Assignees
Labels
A-tokio-macros Area: The tokio-macros crate C-bug Category: This is a bug.

Comments

@monoclex
Copy link

monoclex commented Apr 23, 2022

Version

[dependencies]
tokio = { version = "1.17.0", features = ["macros", "rt-multi-thread"] }

Platform

Linux x86_64

Description

The following code compiles playground link

#[tokio::main]
async fn main() {
    return 1;
    ;
}

The following don't compile, as expected

#[tokio::main]
async fn main() {
    return 1;
    ()
}

#[tokio::main]
async fn main() {
    return 1;
}

#[tokio::main]
async fn main() {
    1
}
@monoclex monoclex added A-tokio Area: The main tokio crate C-bug Category: This is a bug. labels Apr 23, 2022
@Darksonn Darksonn added A-tokio-macros Area: The tokio-macros crate and removed A-tokio Area: The main tokio crate labels Apr 23, 2022
@Darksonn
Copy link
Contributor

Thoughts? @taiki-e

@taiki-e
Copy link
Member

taiki-e commented Apr 24, 2022

Good catch!

The repro will be expanded to the following:

fn main() {
    let body = async { return 1; ; };

    #[allow(clippy :: expect_used)]
    tokio::runtime::Builder::new_multi_thread().enable_all().build().expect("Failed building the Runtime").block_on(body);
}

The heuristic to analyze the last expression and emit a semicolon without return seems wrong. (all branches that return (quote! {}, quote! { ; }) in the following code)

let (tail_return, tail_semicolon) = match body.stmts.last() {
Some(syn::Stmt::Semi(syn::Expr::Return(_), _)) => (quote! { return }, quote! { ; }),
Some(syn::Stmt::Semi(..)) | Some(syn::Stmt::Local(..)) | None => {
match &input.sig.output {
syn::ReturnType::Type(_, ty) if matches!(&**ty, syn::Type::Tuple(ty) if ty.elems.is_empty()) =>
{
(quote! {}, quote! { ; }) // unit
}
syn::ReturnType::Default => (quote! {}, quote! { ; }), // unit
syn::ReturnType::Type(..) => (quote! {}, quote! {}), // ! or another
}
}
_ => (quote! {}, quote! {}),
};

@taiki-e
Copy link
Member

taiki-e commented Apr 24, 2022

The simplest fix for this is to remove all heuristics introduced in #4067 and relevant subsequent PRs.

However, it improved diagnostics, so I'm considering the approach that fixes the problem without regressions on the diagnostics.

Probably, using let () = where unit is expected to be returned should work well.

  let (tail_return, tail_semicolon) = match body.stmts.last() { 
       Some(syn::Stmt::Semi(syn::Expr::Return(_), _)) => (quote! { return }, quote! { ; }), 
       Some(syn::Stmt::Semi(..)) | Some(syn::Stmt::Local(..)) | None => { 
           match &input.sig.output { 
               syn::ReturnType::Type(_, ty) if matches!(&**ty, syn::Type::Tuple(ty) if ty.elems.is_empty()) => 
               { 
-                  (quote! {}, quote! { ; }) // unit 
+                  (quote! { let () = }, quote! { ; }) // unit 
               } 
-              syn::ReturnType::Default => (quote! {}, quote! { ; }), // unit 
+              syn::ReturnType::Default => (quote! { let () = }, quote! { ; }), // unit 
               syn::ReturnType::Type(..) => (quote! {}, quote! {}),   // ! or another 
           } 
       } 
       _ => (quote! {}, quote! {}), 
   }; 

@taiki-e
Copy link
Member

taiki-e commented Apr 24, 2022

filed #4636

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-tokio-macros Area: The tokio-macros crate C-bug Category: This is a bug.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants