Auto merge of #118847 - eholk:for-await, r=compiler-errors
Add support for `for await` loops This adds support for `for await` loops. This includes parsing, desugaring in AST->HIR lowering, and adding some support functions to the library. Given a loop like: ```rust for await i in iter { ... } ``` this is desugared to something like: ```rust let mut iter = iter.into_async_iter(); while let Some(i) = loop { match core::pin::Pin::new(&mut iter).poll_next(cx) { Poll::Ready(i) => break i, Poll::Pending => yield, } } { ... } ``` This PR also adds a basic `IntoAsyncIterator` trait. This is partly for symmetry with the way `Iterator` and `IntoIterator` work. The other reason is that for async iterators it's helpful to have a place apart from the data structure being iterated over to store state. `IntoAsyncIterator` gives us a good place to do this. I've gated this feature behind `async_for_loop` and opened #118898 as the feature tracking issue. r? `@compiler-errors`
This commit is contained in:
commit
4ad06d1adf
@ -220,7 +220,11 @@ fn with_loop_block<F>(expr: &ast::Expr, mut func: F)
|
||||
F: FnMut(&ast::Block, Option<&ast::Label>),
|
||||
{
|
||||
if let ast::ExprKind::While(_, loop_block, label)
|
||||
| ast::ExprKind::ForLoop(_, _, loop_block, label)
|
||||
| ast::ExprKind::ForLoop {
|
||||
body: loop_block,
|
||||
label,
|
||||
..
|
||||
}
|
||||
| ast::ExprKind::Loop(loop_block, label, ..) = &expr.kind
|
||||
{
|
||||
func(loop_block, label.as_ref());
|
||||
|
@ -111,7 +111,7 @@ fn visit_expr(&mut self, expr: &'ast Expr) {
|
||||
ExprKind::If(_, ref then, Some(ref els)) => self.check_block(then) && self.check_expr(els),
|
||||
ExprKind::If(_, _, None)
|
||||
// ignore loops for simplicity
|
||||
| ExprKind::While(..) | ExprKind::ForLoop(..) | ExprKind::Loop(..) => false,
|
||||
| ExprKind::While(..) | ExprKind::ForLoop { .. } | ExprKind::Loop(..) => false,
|
||||
_ => {
|
||||
walk_expr(self, expr);
|
||||
return;
|
||||
|
@ -554,7 +554,7 @@ fn ident_difference_expr_with_base_location(
|
||||
| (Closure(_), Closure(_))
|
||||
| (Match(_, _), Match(_, _))
|
||||
| (Loop(_, _, _), Loop(_, _, _))
|
||||
| (ForLoop(_, _, _, _), ForLoop(_, _, _, _))
|
||||
| (ForLoop { .. }, ForLoop { .. })
|
||||
| (While(_, _, _), While(_, _, _))
|
||||
| (If(_, _, _), If(_, _, _))
|
||||
| (Let(_, _, _, _), Let(_, _, _, _))
|
||||
|
@ -169,9 +169,22 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool {
|
||||
(Let(lp, le, _, _), Let(rp, re, _, _)) => eq_pat(lp, rp) && eq_expr(le, re),
|
||||
(If(lc, lt, le), If(rc, rt, re)) => eq_expr(lc, rc) && eq_block(lt, rt) && eq_expr_opt(le, re),
|
||||
(While(lc, lt, ll), While(rc, rt, rl)) => eq_label(ll, rl) && eq_expr(lc, rc) && eq_block(lt, rt),
|
||||
(ForLoop(lp, li, lt, ll), ForLoop(rp, ri, rt, rl)) => {
|
||||
eq_label(ll, rl) && eq_pat(lp, rp) && eq_expr(li, ri) && eq_block(lt, rt)
|
||||
},
|
||||
(
|
||||
ForLoop {
|
||||
pat: lp,
|
||||
iter: li,
|
||||
body: lt,
|
||||
label: ll,
|
||||
kind: lk,
|
||||
},
|
||||
ForLoop {
|
||||
pat: rp,
|
||||
iter: ri,
|
||||
body: rt,
|
||||
label: rl,
|
||||
kind: rk,
|
||||
},
|
||||
) => eq_label(ll, rl) && eq_pat(lp, rp) && eq_expr(li, ri) && eq_block(lt, rt) && lk == rk,
|
||||
(Loop(lt, ll, _), Loop(rt, rl, _)) => eq_label(ll, rl) && eq_block(lt, rt),
|
||||
(Block(lb, ll), Block(rb, rl)) => eq_label(ll, rl) && eq_block(lb, rb),
|
||||
(TryBlock(l), TryBlock(r)) => eq_block(l, r),
|
||||
|
@ -197,7 +197,7 @@ pub fn ast(
|
||||
| ast::ExprKind::Continue(..)
|
||||
| ast::ExprKind::Yield(..)
|
||||
| ast::ExprKind::Field(..)
|
||||
| ast::ExprKind::ForLoop(..)
|
||||
| ast::ExprKind::ForLoop { .. }
|
||||
| ast::ExprKind::Index(..)
|
||||
| ast::ExprKind::InlineAsm(..)
|
||||
| ast::ExprKind::OffsetOf(..)
|
||||
|
Loading…
Reference in New Issue
Block a user