Skip to content

Mismatched types diagnostic for async fn return type trusts random returns over function signature #54326

Closed
@Arnavion

Description

@Arnavion

With

#![feature(async_await, futures_api)]

async fn foo() -> i32 {
    if false {
        return Ok(6);
    }

    5
}

the errors are:

error[E0308]: mismatched types
 --> src/lib.rs:8:5
  |
8 |     5
  |     ^ expected enum `std::result::Result`, found integral variable
  |
  = note: expected type `std::result::Result<{integer}, _>`
             found type `{integer}`

error[E0271]: type mismatch resolving `<impl std::future::Future as std::future::Future>::Output == i32`
 --> src/lib.rs:3:19
  |
3 | async fn foo() -> i32 {
  |                   ^^^ expected enum `std::result::Result`, found i32
  |
  = note: expected type `std::result::Result<{integer}, _>`
             found type `i32`
  = note: the return type of a function must have a statically known size

error: aborting due to 2 previous errors

It seems the compiler prefers to trust the return Ok(6) line over the function signature, so it ends up marking the function signature and the one return that matches that signature as errors.

In comparison, the diagnostic for regular non-async fns trusts the function signature and flags the return Ok(6) as the error.

fn foo() -> i32 {
    if false {
        return Ok(6);
    }

    5
}
error[E0308]: mismatched types
 --> src/lib.rs:3:16
  |
3 |         return Ok(6);
  |                ^^^^^ expected i32, found enum `std::result::Result`
  |
  = note: expected type `i32`
             found type `std::result::Result<{integer}, _>`

error: aborting due to previous error

This latter diagnostic is much better since the user presumably wrote the function signature intentionally.


I hit this while refactoring a large async fn, and it took some time to figure out why the compiler kept insisting that the function should return a Result when I had no intention for it to do that - a stray early-return in the middle of the function that was returning an Ok().

Metadata

Metadata

Assignees

Labels

A-async-awaitArea: Async & AwaitA-diagnosticsArea: Messages for errors, warnings, and lintsA-frontendArea: Compiler frontend (errors, parsing and HIR)AsyncAwait-TriagedAsync-await issues that have been triaged during a working group meeting.C-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions