Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
matklad opened this issue Sep 5, 2022 · 1 comment
Assignees
Labels
A-async-await Area: Async & Await A-docs Area: Documentation for any part of the project, including the compiler, standard library, and tools E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue.

Comments

@matklad
Copy link
Member

matklad commented Sep 5, 2022

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.

@matklad matklad added the A-docs Area: Documentation for any part of the project, including the compiler, standard library, and tools label Sep 5, 2022
@lolbinarycat lolbinarycat added E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. A-async-await Area: Async & Await labels Mar 31, 2025
@Lynnesbian
Copy link
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

VlaDexa added a commit to VlaDexa/rust that referenced this issue May 2, 2025
…s, r=ibraheemdev

Clarify `async` block behaviour

Adds some documentation for control flow behaviour pertaining to `return` and `?` within `async` blocks. Fixes (or at least improves) rust-lang#101444.

r? rust-lang/docs
Zalathar added a commit to Zalathar/rust that referenced this issue May 2, 2025
…s, r=ibraheemdev

Clarify `async` block behaviour

Adds some documentation for control flow behaviour pertaining to `return` and `?` within `async` blocks. Fixes (or at least improves) rust-lang#101444.

r? rust-lang/docs
rust-timer added a commit to rust-lang-ci/rust that referenced this issue May 2, 2025
Rollup merge of rust-lang#139608 - Lynnesbian:improve-async-block-docs, r=ibraheemdev

Clarify `async` block behaviour

Adds some documentation for control flow behaviour pertaining to `return` and `?` within `async` blocks. Fixes (or at least improves) rust-lang#101444.

r? rust-lang/docs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-async-await Area: Async & Await A-docs Area: Documentation for any part of the project, including the compiler, standard library, and tools E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue.
Projects
None yet
Development

No branches or pull requests

3 participants