rustasync / runtime

Empowering everyone to build asynchronous software
https://docs.rs/runtime
Apache License 2.0
862 stars 28 forks source link

Bad error message when return from main doesn't match declared signature #75

Closed Nemo157 closed 4 years ago

Nemo157 commented 5 years ago

Using this example

#![feature(async_await)]

#[runtime::main]
async fn main() -> std::io::Result<()> {
    println!("Hello, world!");
}

the error message is

error[E0271]: type mismatch resolving `<impl std::future::Future as std::future::Future>::Output == std::result::Result<(), std::io::Error>`
 --> src/main.rs:4:20
  |
4 | async fn main() -> std::io::Result<()> {
  |                    ^^^^^^^^^^^^^^^^^^^ expected (), found enum `std::result::Result`
  |
  = note: expected type `()`
             found type `std::result::Result<(), std::io::Error>`
  = note: the return type of a function must have a statically known size

This is backwards to the error generated with a non-async main for the same code

error[E0308]: mismatched types
 --> src/main.rs:1:14
  |
1 | fn main() -> std::io::Result<()> {
  |              ^^^^^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found ()
  |
  = note: expected type `std::result::Result<(), std::io::Error>`
             found type `()`

The current expansion is approximately

#![feature(async_await)]

fn main() -> std::io::Result<()> {
    async fn main() -> std::io::Result<()> {
        println!("Hello, world!");
    }

    runtime::raw::enter(runtime::native::Native, async {
        main().await
    })
}

this runs into https://github.com/rust-lang/rust/issues/54326, as a workaround till that is fixed the expansion could be changed to something like

#![feature(async_await)]

fn main() -> std::io::Result<()> {
    async fn main() -> std::io::Result<()> {
        let result: std::io::Result<()> = {
            println!("Hello, world!");
        };
        result
    }

    runtime::raw::enter(runtime::native::Native, async {
        main().await
    })
}

forcing an intermediate type check of the implicit return (this won't fix cases where the code does an early return of the wrong type, but it will fix the relatively common forgetting of Ok(()) at the end of error returning functions).

yoshuawuyts commented 5 years ago

@Nemo157 oh yeah, I've run into this at least once before. I'd be very :+1: on a patch (if you'd like to submit one). Though #73 is also working on this exact code right now, and maybe we could merge it into that patchset.