External Publication
Visit Post

[Discussion] Alternative syntax for async iteration: `for async i in stream`?

Rust Internals [Unofficial] May 2, 2026
Source

Thanks for the insightful feedback! You’ve hit on the core semantic tension here.

I agree that in async fn or async {}, async acts as a "wrapper." However, I’d argue that in the context of a binding site (like for <pattern> in <stream>), async can be naturally extended to mean "this binding is resolved asynchronously."

A few counter-points to consider:

  1. Async Patterns vs. Async Wrappers : In a for loop, the i is a pattern. Just as &i in a loop destructures a reference, async i could be seen as "destructuring" (or resolving) an asynchronous value. It tells the compiler: "The source is async, and we are binding the resolved value to i."

  2. The "Wait" is implicit infor: The for keyword already implies a sequential progression. Adding await feels like describing how the engine works (imperative), whereas async describes the nature of the data being bound (declarative).

  3. Avoiding the "Future of Option" confusion : You mentioned Option<Future<...>>. My proposal doesn't change the underlying AsyncIterator trait (which remains Future<Output = Option<T>>). Instead, it’s about how we denote the suspension point.

    • for await i: "Wait, then bind."

    • for async i: "Bind the result of an async step to i."

If we eventually get let async i = ... for destructuring futures or handling async drop, for async i becomes perfectly consistent. It marks the boundary where asynchrony is handled, rather than just being a label for the await operation itself.

Discussion in the ATmosphere

Loading comments...