diff options
| author | bors <bors@rust-lang.org> | 2023-12-22 14:17:10 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-12-22 14:17:10 +0000 |
| commit | 4ad06d1adf1d4afe1ded4c09ad2bb3dc782680d7 (patch) | |
| tree | 7d3fe1a5744eb5c16e4d6f650a0ceeaf809ea4b5 | |
| parent | 062845421b8a678f2807f0682db429025dd18ebe (diff) | |
| parent | 212ea0359c52f63cf05cdd73cf5c30f42aae2aa8 (diff) | |
| download | rust-4ad06d1adf1d4afe1ded4c09ad2bb3dc782680d7.tar.gz rust-4ad06d1adf1d4afe1ded4c09ad2bb3dc782680d7.zip | |
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`
| -rw-r--r-- | clippy_lints/src/needless_continue.rs | 6 | ||||
| -rw-r--r-- | clippy_lints/src/redundant_else.rs | 2 | ||||
| -rw-r--r-- | clippy_lints/src/suspicious_operation_groupings.rs | 2 | ||||
| -rw-r--r-- | clippy_utils/src/ast_utils.rs | 19 | ||||
| -rw-r--r-- | clippy_utils/src/sugg.rs | 2 |
5 files changed, 24 insertions, 7 deletions
diff --git a/clippy_lints/src/needless_continue.rs b/clippy_lints/src/needless_continue.rs index 4b9ab50e4fd..ff72b5e69ef 100644 --- a/clippy_lints/src/needless_continue.rs +++ b/clippy_lints/src/needless_continue.rs @@ -220,7 +220,11 @@ where 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()); diff --git a/clippy_lints/src/redundant_else.rs b/clippy_lints/src/redundant_else.rs index 001686c84f8..fb434fb7450 100644 --- a/clippy_lints/src/redundant_else.rs +++ b/clippy_lints/src/redundant_else.rs @@ -111,7 +111,7 @@ impl<'ast> Visitor<'ast> for BreakVisitor { 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; diff --git a/clippy_lints/src/suspicious_operation_groupings.rs b/clippy_lints/src/suspicious_operation_groupings.rs index 8b9d9bade91..60e9d262e7e 100644 --- a/clippy_lints/src/suspicious_operation_groupings.rs +++ b/clippy_lints/src/suspicious_operation_groupings.rs @@ -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(_, _, _, _)) diff --git a/clippy_utils/src/ast_utils.rs b/clippy_utils/src/ast_utils.rs index c271e498665..7fe76b946a4 100644 --- a/clippy_utils/src/ast_utils.rs +++ b/clippy_utils/src/ast_utils.rs @@ -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), diff --git a/clippy_utils/src/sugg.rs b/clippy_utils/src/sugg.rs index 9b2bc8df1f3..c86362c427c 100644 --- a/clippy_utils/src/sugg.rs +++ b/clippy_utils/src/sugg.rs @@ -197,7 +197,7 @@ impl<'a> Sugg<'a> { | ast::ExprKind::Continue(..) | ast::ExprKind::Yield(..) | ast::ExprKind::Field(..) - | ast::ExprKind::ForLoop(..) + | ast::ExprKind::ForLoop { .. } | ast::ExprKind::Index(..) | ast::ExprKind::InlineAsm(..) | ast::ExprKind::OffsetOf(..) |
