Rust: Error in `async` function/block produces errors for valid unrelated expressions

Created on 22 Nov 2019  路  1Comment  路  Source: rust-lang/rust

Code (Playground)

use futures::{future::ready, join};

async fn _incorrect_error() {
    join! { ready(0) };
    // Produces cannot infer type for `{integer}` for expression above
    0.await;
}

fn main() {}

produces following errors:

Errors

error[E0277]: the trait bound `{integer}: core::future::future::Future` is not satisfied
  --> src/main.rs:6:5
   |
6  |     0.await;
   |     ^^^^^^^ the trait `core::future::future::Future` is not implemented for `{integer}`
   |
   = help: the following implementations were found:
             <&mut F as core::future::future::Future>
             <futures_channel::oneshot::Receiver<T> as core::future::future::Future>
             <futures_task::future_obj::FutureObj<'_, T> as core::future::future::Future>
             <futures_task::future_obj::LocalFutureObj<'_, T> as core::future::future::Future>
           and 84 others

error[E0698]: type inside `async fn` body must be known in this context
 --> src/main.rs:4:5
  |
4 |     join! { ready(0) };
  |     ^^^^^^^^^^^^^^^^^^^ cannot infer type for `{integer}`
  |
note: the type is part of the `async fn` body because of this `await`
 --> src/main.rs:4:5
  |
4 |     join! { ready(0) };
  |     ^^^^^^^^^^^^^^^^^^^
  = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)

error[E0698]: type inside `async fn` body must be known in this context
 --> src/main.rs:4:5
  |
4 |     join! { ready(0) };
  |     ^^^^^^^^^^^^^^^^^^^ cannot infer type for `{integer}`
  |
note: the type is part of the `async fn` body because of this `await`
 --> src/main.rs:4:5
  |
4 |     join! { ready(0) };
  |     ^^^^^^^^^^^^^^^^^^^
  = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)

error[E0698]: type inside `async fn` body must be known in this context
 --> src/main.rs:4:5
  |
4 |     join! { ready(0) };
  |     ^^^^^^^^^^^^^^^^^^^ cannot infer type for `{integer}`
  |
note: the type is part of the `async fn` body because of this `await`
 --> src/main.rs:4:5
  |
4 |     join! { ready(0) };
  |     ^^^^^^^^^^^^^^^^^^^
  = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)

error[E0698]: type inside `async fn` body must be known in this context
 --> src/main.rs:6:5
  |
6 |     0.await;
  |     ^ cannot infer type for `{integer}`
  |
note: the type is part of the `async fn` body because of this `await`
 --> src/main.rs:6:5
  |
6 |     0.await;
  |     ^^^^^^^

error[E0698]: type inside `async fn` body must be known in this context
 --> src/main.rs:6:5
  |
6 |     0.await;
  |     ^^^^^^^ cannot infer type for `{integer}`
  |
note: the type is part of the `async fn` body because of this `await`
 --> src/main.rs:6:5
  |
6 |     0.await;
  |     ^^^^^^^

However, if we remove line

0.await;

, it will become valid. Error on this line affects unrelated

join! { ready(0) };

and produces cannot infer type for {integer} error for valid expression. This behaviour could seem not so bad, but imagine large async function with many lines (you can simply copy-paste first line several times and look to the output).

A-async-await A-diagnostics A-inference AsyncAwait-Triaged C-bug T-compiler

Most helpful comment

Another example: playground

What's really weird is that I get five copies of the same error message.

use std::io::Error;

fn main() {
    let server = async {
        for _connection in 0..2 {
            futures::future::ready(Ok::<(), Error>(())).await?;
        }

        Ok::<(), Error>(())
    };

    server.await;
}

>All comments

Another example: playground

What's really weird is that I get five copies of the same error message.

use std::io::Error;

fn main() {
    let server = async {
        for _connection in 0..2 {
            futures::future::ready(Ok::<(), Error>(())).await?;
        }

        Ok::<(), Error>(())
    };

    server.await;
}
Was this page helpful?
0 / 5 - 0 ratings