Skip to content

Commit caa63dc

Browse files
committed
Plumb awaitness of for loops
1 parent 4f47328 commit caa63dc

File tree

22 files changed

+95
-52
lines changed

22 files changed

+95
-52
lines changed

compiler/rustc_ast/src/ast.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1261,7 +1261,7 @@ impl Expr {
12611261
ExprKind::Let(..) => ExprPrecedence::Let,
12621262
ExprKind::If(..) => ExprPrecedence::If,
12631263
ExprKind::While(..) => ExprPrecedence::While,
1264-
ExprKind::ForLoop(..) => ExprPrecedence::ForLoop,
1264+
ExprKind::ForLoop { .. } => ExprPrecedence::ForLoop,
12651265
ExprKind::Loop(..) => ExprPrecedence::Loop,
12661266
ExprKind::Match(..) => ExprPrecedence::Match,
12671267
ExprKind::Closure(..) => ExprPrecedence::Closure,
@@ -1423,10 +1423,10 @@ pub enum ExprKind {
14231423
While(P<Expr>, P<Block>, Option<Label>),
14241424
/// A `for` loop, with an optional label.
14251425
///
1426-
/// `'label: for pat in expr { block }`
1426+
/// `'label: for await? pat in iter { block }`
14271427
///
14281428
/// This is desugared to a combination of `loop` and `match` expressions.
1429-
ForLoop(P<Pat>, P<Expr>, P<Block>, Option<Label>),
1429+
ForLoop { pat: P<Pat>, iter: P<Expr>, body: P<Block>, label: Option<Label>, is_await: bool },
14301430
/// Conditionless loop (can be exited with `break`, `continue`, or `return`).
14311431
///
14321432
/// `'label: loop { block }`

compiler/rustc_ast/src/mut_visit.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1388,7 +1388,7 @@ pub fn noop_visit_expr<T: MutVisitor>(
13881388
vis.visit_block(body);
13891389
visit_opt(label, |label| vis.visit_label(label));
13901390
}
1391-
ExprKind::ForLoop(pat, iter, body, label) => {
1391+
ExprKind::ForLoop{pat, iter, body, label, is_await: _} => {
13921392
vis.visit_pat(pat);
13931393
vis.visit_expr(iter);
13941394
vis.visit_block(body);

compiler/rustc_ast/src/util/classify.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ pub fn expr_requires_semi_to_be_stmt(e: &ast::Expr) -> bool {
1919
| ast::ExprKind::Block(..)
2020
| ast::ExprKind::While(..)
2121
| ast::ExprKind::Loop(..)
22-
| ast::ExprKind::ForLoop(..)
22+
| ast::ExprKind::ForLoop { .. }
2323
| ast::ExprKind::TryBlock(..)
2424
| ast::ExprKind::ConstBlock(..)
2525
)
@@ -46,8 +46,15 @@ pub fn expr_trailing_brace(mut expr: &ast::Expr) -> Option<&ast::Expr> {
4646
Closure(closure) => {
4747
expr = &closure.body;
4848
}
49-
Gen(..) | Block(..) | ForLoop(..) | If(..) | Loop(..) | Match(..) | Struct(..)
50-
| TryBlock(..) | While(..) => break Some(expr),
49+
Gen(..)
50+
| Block(..)
51+
| ForLoop { .. }
52+
| If(..)
53+
| Loop(..)
54+
| Match(..)
55+
| Struct(..)
56+
| TryBlock(..)
57+
| While(..) => break Some(expr),
5158
_ => break None,
5259
}
5360
}

compiler/rustc_ast/src/visit.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -844,11 +844,11 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
844844
visitor.visit_expr(subexpression);
845845
visitor.visit_block(block);
846846
}
847-
ExprKind::ForLoop(pattern, subexpression, block, opt_label) => {
848-
walk_list!(visitor, visit_label, opt_label);
849-
visitor.visit_pat(pattern);
850-
visitor.visit_expr(subexpression);
851-
visitor.visit_block(block);
847+
ExprKind::ForLoop { pat, iter, body, label, is_await: _ } => {
848+
walk_list!(visitor, visit_label, label);
849+
visitor.visit_pat(pat);
850+
visitor.visit_expr(iter);
851+
visitor.visit_block(body);
852852
}
853853
ExprKind::Loop(block, opt_label, _) => {
854854
walk_list!(visitor, visit_label, opt_label);

compiler/rustc_ast_lowering/src/expr.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
5656
return ex;
5757
}
5858
// Desugar `ExprForLoop`
59-
// from: `[opt_ident]: for <pat> in <head> <body>`
59+
// from: `[opt_ident]: for await? <pat> in <iter> <body>`
6060
//
6161
// This also needs special handling because the HirId of the returned `hir::Expr` will not
62-
// correspond to the `e.id`, so `lower_expr_for` handles attribute lowering itself.
63-
ExprKind::ForLoop(pat, head, body, opt_label) => {
64-
return self.lower_expr_for(e, pat, head, body, *opt_label);
62+
// correspond to the `e.id`, so `lower_expr_for` handles attribute low}ering itself.
63+
ExprKind::ForLoop { pat, iter, body, label, is_await } => {
64+
return self.lower_expr_for(e, pat, iter, body, *label, *is_await);
6565
}
6666
_ => (),
6767
}
@@ -331,7 +331,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
331331
),
332332
ExprKind::Try(sub_expr) => self.lower_expr_try(e.span, sub_expr),
333333

334-
ExprKind::Paren(_) | ExprKind::ForLoop(..) => {
334+
ExprKind::Paren(_) | ExprKind::ForLoop{..} => {
335335
unreachable!("already handled")
336336
}
337337

@@ -1554,6 +1554,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
15541554
head: &Expr,
15551555
body: &Block,
15561556
opt_label: Option<Label>,
1557+
_is_await: bool,
15571558
) -> hir::Expr<'hir> {
15581559
let head = self.lower_expr_mut(head);
15591560
let pat = self.lower_pat(pat);

compiler/rustc_ast_pretty/src/pprust/state/expr.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -370,20 +370,23 @@ impl<'a> State<'a> {
370370
self.space();
371371
self.print_block_with_attrs(blk, attrs);
372372
}
373-
ast::ExprKind::ForLoop(pat, iter, blk, opt_label) => {
374-
if let Some(label) = opt_label {
373+
ast::ExprKind::ForLoop { pat, iter, body, label, is_await } => {
374+
if let Some(label) = label {
375375
self.print_ident(label.ident);
376376
self.word_space(":");
377377
}
378378
self.cbox(0);
379379
self.ibox(0);
380380
self.word_nbsp("for");
381+
if *is_await {
382+
self.word_nbsp("await");
383+
}
381384
self.print_pat(pat);
382385
self.space();
383386
self.word_space("in");
384387
self.print_expr_as_cond(iter);
385388
self.space();
386-
self.print_block_with_attrs(blk, attrs);
389+
self.print_block_with_attrs(body, attrs);
387390
}
388391
ast::ExprKind::Loop(blk, opt_label, _) => {
389392
if let Some(label) = opt_label {

compiler/rustc_builtin_macros/src/assert/context.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ impl<'cx, 'a> Context<'cx, 'a> {
303303
| ExprKind::Continue(_)
304304
| ExprKind::Err
305305
| ExprKind::Field(_, _)
306-
| ExprKind::ForLoop(_, _, _, _)
306+
| ExprKind::ForLoop {..}
307307
| ExprKind::FormatArgs(_)
308308
| ExprKind::IncludedBytes(..)
309309
| ExprKind::InlineAsm(_)

compiler/rustc_lint/src/unused.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -852,8 +852,8 @@ trait UnusedDelimLint {
852852
(cond, UnusedDelimsCtx::WhileCond, true, Some(left), Some(right), true)
853853
}
854854

855-
ForLoop(_, ref cond, ref block, ..) => {
856-
(cond, UnusedDelimsCtx::ForIterExpr, true, None, Some(block.span.lo()), true)
855+
ForLoop { ref iter, ref body, .. } => {
856+
(iter, UnusedDelimsCtx::ForIterExpr, true, None, Some(body.span.lo()), true)
857857
}
858858

859859
Match(ref head, _) if Self::LINT_EXPR_IN_PATTERN_MATCHING_CTX => {
@@ -1085,7 +1085,7 @@ impl EarlyLintPass for UnusedParens {
10851085
}
10861086

10871087
match e.kind {
1088-
ExprKind::Let(ref pat, _, _, _) | ExprKind::ForLoop(ref pat, ..) => {
1088+
ExprKind::Let(ref pat, _, _, _) | ExprKind::ForLoop { ref pat, .. } => {
10891089
self.check_unused_parens_pat(cx, pat, false, false, (true, true));
10901090
}
10911091
// We ignore parens in cases like `if (((let Some(0) = Some(1))))` because we already

compiler/rustc_parse/src/parser/expr.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1799,7 +1799,7 @@ impl<'a> Parser<'a> {
17991799
&& matches!(
18001800
expr.kind,
18011801
ExprKind::While(_, _, None)
1802-
| ExprKind::ForLoop(_, _, _, None)
1802+
| ExprKind::ForLoop { label: None, .. }
18031803
| ExprKind::Loop(_, None, _)
18041804
| ExprKind::Block(_, None)
18051805
)
@@ -2672,8 +2672,14 @@ impl<'a> Parser<'a> {
26722672
Ok((pat, expr))
26732673
}
26742674

2675-
/// Parses `for <src_pat> in <src_expr> <src_loop_block>` (`for` token already eaten).
2675+
/// Parses `for await? <src_pat> in <src_expr> <src_loop_block>` (`for` token already eaten).
26762676
fn parse_expr_for(&mut self, opt_label: Option<Label>, lo: Span) -> PResult<'a, P<Expr>> {
2677+
let is_await = self.eat_keyword(kw::Await);
2678+
2679+
if is_await {
2680+
self.sess.gated_spans.gate(sym::async_iterator, self.prev_token.span);
2681+
}
2682+
26772683
let (pat, expr) = self.parse_for_head()?;
26782684
// Recover from missing expression in `for` loop
26792685
if matches!(expr.kind, ExprKind::Block(..))
@@ -2686,13 +2692,14 @@ impl<'a> Parser<'a> {
26862692
let block = self.mk_block(thin_vec![], BlockCheckMode::Default, self.prev_token.span);
26872693
return Ok(self.mk_expr(
26882694
lo.to(self.prev_token.span),
2689-
ExprKind::ForLoop(pat, err_expr, block, opt_label),
2695+
ExprKind::ForLoop { pat, iter: err_expr, body: block, label: opt_label, is_await },
26902696
));
26912697
}
26922698

26932699
let (attrs, loop_block) = self.parse_inner_attrs_and_block()?;
26942700

2695-
let kind = ExprKind::ForLoop(pat, expr, loop_block, opt_label);
2701+
let kind =
2702+
ExprKind::ForLoop { pat, iter: expr, body: loop_block, label: opt_label, is_await };
26962703

26972704
self.recover_loop_else("for", lo)?;
26982705

@@ -3770,7 +3777,7 @@ impl MutVisitor for CondChecker<'_> {
37703777
| ExprKind::Lit(_)
37713778
| ExprKind::If(_, _, _)
37723779
| ExprKind::While(_, _, _)
3773-
| ExprKind::ForLoop(_, _, _, _)
3780+
| ExprKind::ForLoop { .. }
37743781
| ExprKind::Loop(_, _, _)
37753782
| ExprKind::Match(_, _)
37763783
| ExprKind::Closure(_)

compiler/rustc_resolve/src/late.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4246,11 +4246,11 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
42464246
});
42474247
}
42484248

4249-
ExprKind::ForLoop(ref pat, ref iter_expr, ref block, label) => {
4250-
self.visit_expr(iter_expr);
4249+
ExprKind::ForLoop { ref pat, ref iter, ref body, label, is_await: _ } => {
4250+
self.visit_expr(iter);
42514251
self.with_rib(ValueNS, RibKind::Normal, |this| {
42524252
this.resolve_pattern_top(pat, PatternSource::For);
4253-
this.resolve_labeled_block(label, expr.id, block);
4253+
this.resolve_labeled_block(label, expr.id, body);
42544254
});
42554255
}
42564256

0 commit comments

Comments
 (0)