Skip to content

Semantics of control flow operators (return, continue, ?) in async blocks is severely underdocumented  #101444

@matklad

Description

@matklad
Member

As a novice Rust programmer, I was quite surprised that the following works:

#[tokio::main]
async fn main() {
    let f = async { return 92 };
    assert_eq!(f.await, 92);
}

I don't remeber reading that in any kind of docs, and looking at the

didn't show up any example of the syntax.

This is documented in the reference (rust-lang/reference#1262), but without an example.

Activity

added
A-docsArea: Documentation for any part of the project, including the compiler, standard library, and tools
on Sep 5, 2022
added
E-easyCall for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue.
on Mar 31, 2025
Lynnesbian

Lynnesbian commented on Apr 10, 2025

@Lynnesbian
Contributor

I'd be interested in claiming this as my first issue.

This behaviour is documented in the Async Rust Book as of this commit.


The current docs for the async keyword are fairly minimal, so I'm not sure how much they should be expanded, but so far I've come up with something like this, adding to the existing comment:

Use async in front of fn, closure, or a block to turn the marked code into a Future.
As such the code will not be run immediately, but will only be evaluated when the returned
future is .awaited.

return and ? statements within async blocks do not return from the parent function; rather, they
cause the Future returned by the block to return with that value.

For example, the following Rust function will return 5, assigning the ! value to x:

#[expect(unused_variables)]
fn example() -> i32 {
    let x = {
      return 5;
    };
}

In contrast, the following asynchronous function assigns a Future<Output = i32> to x, and only returns 5 when x is .awaited:

async fn example() -> i32 {
    let x = async {
        return 5;
    };
    
    x.await
}

Code using ? behaves similarly - it causes the async block to return a Result without affecting the parent function.
Note that you cannot use break or continue from within an async block to affect the control flow of a loop in the parent function.


@rustbot claim

added a commit that references this issue on May 2, 2025
bfb7c70
added a commit that references this issue on May 2, 2025
192fbcc
added a commit that references this issue on May 2, 2025
added a commit that references this issue on May 9, 2025
clubby789

clubby789 commented on May 13, 2025

@clubby789
Contributor

Seems like this is well documented as of #139608, closing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

A-async-awaitArea: Async & AwaitA-docsArea: Documentation for any part of the project, including the compiler, standard library, and toolsE-easyCall for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

    Development

    No branches or pull requests

      Participants

      @matklad@clubby789@lolbinarycat@Lynnesbian

      Issue actions

        Semantics of control flow operators (return, continue, `?`) in async blocks is severely underdocumented · Issue #101444 · rust-lang/rust