Repository: tokio-rs/tokio
File: tokio-macros/src/entry.rs (Rust)

Code before:
    // functions) copies we generate during compilation due to the generic
    // parameter `F` (the future to block on). This could have an impact on
    // performance, but because it's only for testing it's unlikely to be very
    // large.
    //
    // We don't do this for the main function as it should only be used once so
    // there will be no benefit.
    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 },
    };

    let body = if is_test {
        quote! {
            let body = async #body;
            #crate_path::pin!(body);
            let body: ::core::pin::Pin<&mut dyn ::core::future::Future<Output = #output_type>> = body;
        }
    } else {
        // force typecheck without runtime overhead
        let check_block = match &input.sig.output {
            syn::ReturnType::Type(_, t)
                if matches!(**t, syn::Type::Never(_) | syn::Type::ImplTrait(_)) =>
            {
                quote! {}
            }
            _ => quote! {
                if false {
                    let _: &dyn ::core::future::Future<Output = #output_type> = &body;
                }
            },
        };

        quote! {
            let body = async #body;
            // Compile-time assertion that the future's output matches the return type.
            let body = {
                #check_block
                body
            };
        }
    };

    input.into_tokens(generated_attrs, body, last_block)
}

fn token_stream_with_error(mut tokens: TokenStream, error: syn::Error) -> TokenStream {
    tokens.extend(error.into_compile_error());

Review comment (bug):
Sorry, my test case above wasn't sufficient. impl trait can also be placed inside other types, so this check isn't sufficient.
```rs
#[tokio::main]
async fn impl_trait2() -> Result<(), impl core::fmt::Debug> {
    Err(())
}
```

Code after:
            }
        })
        .collect();

    let body_ident = quote! { body };
    // This explicit `return` is intentional. See tokio-rs/tokio#4636
    let last_block = quote_spanned! {last_stmt_end_span=>
        #do_checks

        #[cfg(all(#(#checks),*))]
        #[allow(clippy::expect_used, clippy::diverging_sub_expression, clippy::needless_return, clippy::unwrap_in_result)]
        {
            return #rt
                .enable_all()
                .#build
                .expect("Failed building the Runtime")
                .block_on(#body_ident);
        }

        #[cfg(not(all(#(#checks),*)))]
        {
            panic!("fell through checks")
        }
    };

    let body = input.body();

    // For test functions pin the body to the stack and use `Pin<&mut dyn
    // Future>` to reduce the amount of `Runtime::block_on` (and related
    // functions) copies we generate during compilation due to the generic
    // parameter `F` (the future to block on). This could have an impact on
    // performance, but because it's only for testing it's unlikely to be very
    // large.
    //
    // We don't do this for the main function as it should only be used once so
    // there will be no benefit.
    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 },
    };

    let body = if is_test {
        quote! {
            let body = async #body;
            #crate_path::pin!(body);
            let body: ::core::pin::Pin<&mut dyn ::core::future::Future<Output = #output_type>> = body;
        }
    } else {