lotsoftools

Understanding Rust Error E0728: Await Used Outside of Async Context

Rust Error E0728

Rust error E0728 occurs when the 'await' keyword is used outside of an async function or async block. The 'await' keyword is used to suspend the execution of a computation until a future is ready to produce a value. Therefore, it is only valid within an async context, such as an async function or an async block.

Erroneous Code Example

#![allow(unused)]
fn main() {
use std::pin::Pin;
use std::future::Future;
use std::task::{Context, Poll};

struct WakeOnceThenComplete(bool);

fn wake_and_yield_once() -> WakeOnceThenComplete {
    WakeOnceThenComplete(false)
}

impl Future for WakeOnceThenComplete {
    type Output = ();
    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
        if self.0 {
            Poll::Ready(())
        } else {
            cx.waker().wake_by_ref();
            self.0 = true;
            Poll::Pending
        }
    }
}

fn foo() {
    wake_and_yield_once().await // `await` is used outside `async` context
}
}

In the code example above, the usage of 'await' outside an async function or async block triggers Rust error E0728.

How to Fix Rust Error E0728

To fix Rust error E0728, move the 'await' keyword usage inside an async function or async block. Consider the following corrected code example:

#![allow(unused)]
fn main() {
use std::pin::Pin;
use std::future::Future;
use std::task::{Context, Poll};

struct WakeOnceThenComplete(bool);

fn wake_and_yield_once() -> WakeOnceThenComplete {
    WakeOnceThenComplete(false)
}

impl Future for WakeOnceThenComplete {
    type Output = ();
    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
        if self.0 {
            Poll::Ready(())
        } else {
            cx.waker().wake_by_ref();
            self.0 = true;
            Poll::Pending
        }
    }
}

async fn foo() {
    wake_and_yield_once().await // `await` is used within `async` function
}

fn bar(x: u8) -> impl Future<Output = u8> {
    async move {
        wake_and_yield_once().await; // `await` is used within `async` block
        x
    }
}
}

In the corrected code example, the 'await' keyword is placed within an async function 'foo()' and an async block within the 'bar()' function. This resolves the error and allows the code to compile without any issues.