Skip to content

rustc suggests awaiting on non-future type on type mismatch with future #90931

Closed
@edward-shen

Description

@edward-shen

Given the following code: playground

async fn foo() -> Result<(), ()> {
    todo!()
}

async fn bar() {
    let _unused = if true {
        foo()
    } else {
        foo().await
    };
    
    let _unused = match true {
        true => foo(),
        false => foo().await
    };
}

The current output is:

error[E0308]: `if` and `else` have incompatible types
  --> src/lib.rs:9:9
   |
6  |       let _unused = if true {
   |  ___________________-
7  | |         foo()
   | |         ----- expected because of this
8  | |     } else {
9  | |         foo().await
   | |         ^^^^^^^^^^^ expected opaque type, found enum `Result`
10 | |     };
   | |_____- `if` and `else` have incompatible types
   |
   = note: expected type `impl Future`
              found enum `Result<(), ()>`
help: consider `await`ing on the `Future`
   |
9  |         foo().await.await
   |                    ++++++

error[E0308]: `match` arms have incompatible types
  --> src/lib.rs:14:18
   |
12 |       let _unused = match true {
   |  ___________________-
13 | |         true => foo(),
   | |                 ----- this is found to be of type `impl Future`
14 | |         false => foo().await
   | |                  ^^^^^^^^^^^ expected opaque type, found enum `Result`
15 | |     };
   | |_____- `match` arms have incompatible types
   |
   = note: expected type `impl Future`
              found enum `Result<(), ()>`
help: consider `await`ing on the `Future`
   |
14 |         false => foo().await.await
   |                             ++++++

For more information about this error, try `rustc --explain E0308`.
error: could not compile `playground` due to 2 previous errors

Ideally the output should look like:

error[E0308]: `if` and `else` have incompatible types
  --> src/lib.rs:9:9
   |
6  |       let _unused = if true {
   |  ___________________-
7  | |         foo()
   | |         ----- expected because of this
8  | |     } else {
9  | |         foo().await
   | |         ^^^^^^^^^^^ expected opaque type, found enum `Result`
10 | |     };
   | |_____- `if` and `else` have incompatible types
   |
   = note: expected type `impl Future`
              found enum `Result<(), ()>`
help: consider `await`ing on the `Future`
   |
7  |         foo().await
   |              ++++++

error[E0308]: `match` arms have incompatible types
  --> src/lib.rs:14:18
   |
12 |       let _unused = match true {
   |  ___________________-
13 | |         true => foo(),
   | |                 ----- this is found to be of type `impl Future`
14 | |         false => foo().await
   | |                  ^^^^^^^^^^^ expected opaque type, found enum `Result`
15 | |     };
   | |_____- `match` arms have incompatible types
   |
   = note: expected type `impl Future`
              found enum `Result<(), ()>`
help: consider `await`ing on the `Future`
   |
13 |         false => foo().await
   |                       ++++++

For more information about this error, try `rustc --explain E0308`.
error: could not compile `playground` due to 2 previous errors

I've verified that this reproduces on Stable (1.56) and Nightly (1.58) on playground.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsT-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