Skip to content

Commit 85b8473

Browse files
committed
Add ForLoopKind
1 parent 6d42dbf commit 85b8473

File tree

8 files changed

+70
-55
lines changed

8 files changed

+70
-55
lines changed

compiler/rustc_ast/src/ast.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -1426,7 +1426,7 @@ pub enum ExprKind {
14261426
/// `'label: for await? pat in iter { block }`
14271427
///
14281428
/// This is desugared to a combination of `loop` and `match` expressions.
1429-
ForLoop { pat: P<Pat>, iter: P<Expr>, body: P<Block>, label: Option<Label>, is_await: bool },
1429+
ForLoop { pat: P<Pat>, iter: P<Expr>, body: P<Block>, label: Option<Label>, kind: ForLoopKind },
14301430
/// Conditionless loop (can be exited with `break`, `continue`, or `return`).
14311431
///
14321432
/// `'label: loop { block }`
@@ -1529,6 +1529,13 @@ pub enum ExprKind {
15291529
Err,
15301530
}
15311531

1532+
/// Used to differentiate between `for` loops and `for await` loops.
1533+
#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Eq)]
1534+
pub enum ForLoopKind {
1535+
For,
1536+
ForAwait,
1537+
}
1538+
15321539
/// Used to differentiate between `async {}` blocks and `gen {}` blocks.
15331540
#[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq)]
15341541
pub enum GenBlockKind {

compiler/rustc_ast/src/mut_visit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1389,7 +1389,7 @@ pub fn noop_visit_expr<T: MutVisitor>(
13891389
vis.visit_block(body);
13901390
visit_opt(label, |label| vis.visit_label(label));
13911391
}
1392-
ExprKind::ForLoop { pat, iter, body, label, is_await: _ } => {
1392+
ExprKind::ForLoop { pat, iter, body, label, kind: _ } => {
13931393
vis.visit_pat(pat);
13941394
vis.visit_expr(iter);
13951395
vis.visit_block(body);

compiler/rustc_ast/src/visit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -844,7 +844,7 @@ 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 { pat, iter, body, label, is_await: _ } => {
847+
ExprKind::ForLoop { pat, iter, body, label, kind: _ } => {
848848
walk_list!(visitor, visit_label, label);
849849
visitor.visit_pat(pat);
850850
visitor.visit_expr(iter);

compiler/rustc_ast_lowering/src/expr.rs

+48-42
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
6060
//
6161
// This also needs special handling because the HirId of the returned `hir::Expr` will not
6262
// 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);
63+
ExprKind::ForLoop { pat, iter, body, label, kind } => {
64+
return self.lower_expr_for(e, pat, iter, body, *label, *kind);
6565
}
6666
_ => (),
6767
}
@@ -1679,7 +1679,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
16791679
head: &Expr,
16801680
body: &Block,
16811681
opt_label: Option<Label>,
1682-
is_await: bool,
1682+
loop_kind: ForLoopKind,
16831683
) -> hir::Expr<'hir> {
16841684
let head = self.lower_expr_mut(head);
16851685
let pat = self.lower_pat(pat);
@@ -1710,30 +1710,33 @@ impl<'hir> LoweringContext<'_, 'hir> {
17101710

17111711
let match_expr = {
17121712
let iter = self.expr_ident(head_span, iter, iter_pat_nid);
1713-
let next_expr = if is_await {
1714-
// `async_iter_next(unsafe { Pin::new_unchecked(&mut iter) }).await`
1715-
let future = self.expr_mut_addr_of(head_span, iter);
1716-
let future = self.arena.alloc(self.expr_call_lang_item_fn_mut(
1717-
head_span,
1718-
hir::LangItem::PinNewUnchecked,
1719-
arena_vec![self; future],
1720-
));
1721-
let future = self.expr_unsafe(future);
1722-
let future = self.expr_call_lang_item_fn(
1723-
head_span,
1724-
hir::LangItem::AsyncIterNext,
1725-
arena_vec![self; future],
1726-
);
1727-
let kind = self.make_lowered_await(head_span, future);
1728-
self.arena.alloc(hir::Expr { hir_id: self.next_id(), kind, span: head_span })
1729-
} else {
1730-
// `match Iterator::next(&mut iter) { ... }`
1731-
let ref_mut_iter = self.expr_mut_addr_of(head_span, iter);
1732-
self.expr_call_lang_item_fn(
1733-
head_span,
1734-
hir::LangItem::IteratorNext,
1735-
arena_vec![self; ref_mut_iter],
1736-
)
1713+
let next_expr = match loop_kind {
1714+
ForLoopKind::For => {
1715+
// `match Iterator::next(&mut iter) { ... }`
1716+
let ref_mut_iter = self.expr_mut_addr_of(head_span, iter);
1717+
self.expr_call_lang_item_fn(
1718+
head_span,
1719+
hir::LangItem::IteratorNext,
1720+
arena_vec![self; ref_mut_iter],
1721+
)
1722+
}
1723+
ForLoopKind::ForAwait => {
1724+
// `async_iter_next(unsafe { Pin::new_unchecked(&mut iter) }).await`
1725+
let future = self.expr_mut_addr_of(head_span, iter);
1726+
let future = self.arena.alloc(self.expr_call_lang_item_fn_mut(
1727+
head_span,
1728+
hir::LangItem::PinNewUnchecked,
1729+
arena_vec![self; future],
1730+
));
1731+
let future = self.expr_unsafe(future);
1732+
let future = self.expr_call_lang_item_fn(
1733+
head_span,
1734+
hir::LangItem::AsyncIterNext,
1735+
arena_vec![self; future],
1736+
);
1737+
let kind = self.make_lowered_await(head_span, future);
1738+
self.arena.alloc(hir::Expr { hir_id: self.next_id(), kind, span: head_span })
1739+
}
17371740
};
17381741
let arms = arena_vec![self; none_arm, some_arm];
17391742

@@ -1756,21 +1759,24 @@ impl<'hir> LoweringContext<'_, 'hir> {
17561759
// `mut iter => { ... }`
17571760
let iter_arm = self.arm(iter_pat, loop_expr);
17581761

1759-
let into_iter_expr = if is_await {
1760-
// `::core::async_iter::IntoAsyncIterator::into_async_iter(<head>)`
1761-
let iter = self.expr_call_lang_item_fn(
1762-
head_span,
1763-
hir::LangItem::IntoAsyncIterIntoIter,
1764-
arena_vec![self; head],
1765-
);
1766-
self.arena.alloc(self.expr_mut_addr_of(head_span, iter))
1767-
} else {
1768-
// `::std::iter::IntoIterator::into_iter(<head>)`
1769-
self.expr_call_lang_item_fn(
1770-
head_span,
1771-
hir::LangItem::IntoIterIntoIter,
1772-
arena_vec![self; head],
1773-
)
1762+
let into_iter_expr = match loop_kind {
1763+
ForLoopKind::For => {
1764+
// `::std::iter::IntoIterator::into_iter(<head>)`
1765+
self.expr_call_lang_item_fn(
1766+
head_span,
1767+
hir::LangItem::IntoIterIntoIter,
1768+
arena_vec![self; head],
1769+
)
1770+
}
1771+
ForLoopKind::ForAwait => {
1772+
// `::core::async_iter::IntoAsyncIterator::into_async_iter(<head>)`
1773+
let iter = self.expr_call_lang_item_fn(
1774+
head_span,
1775+
hir::LangItem::IntoAsyncIterIntoIter,
1776+
arena_vec![self; head],
1777+
);
1778+
self.arena.alloc(self.expr_mut_addr_of(head_span, iter))
1779+
}
17741780
};
17751781

17761782
let match_expr = self.arena.alloc(self.expr_match(

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

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::pp::Breaks::Inconsistent;
22
use crate::pprust::state::{AnnNode, PrintState, State, INDENT_UNIT};
3+
use ast::ForLoopKind;
34
use itertools::{Itertools, Position};
45
use rustc_ast::ptr::P;
56
use rustc_ast::token;
@@ -418,15 +419,15 @@ impl<'a> State<'a> {
418419
self.space();
419420
self.print_block_with_attrs(blk, attrs);
420421
}
421-
ast::ExprKind::ForLoop { pat, iter, body, label, is_await } => {
422+
ast::ExprKind::ForLoop { pat, iter, body, label, kind } => {
422423
if let Some(label) = label {
423424
self.print_ident(label.ident);
424425
self.word_space(":");
425426
}
426427
self.cbox(0);
427428
self.ibox(0);
428429
self.word_nbsp("for");
429-
if *is_await {
430+
if kind == &ForLoopKind::ForAwait {
430431
self.word_nbsp("await");
431432
}
432433
self.print_pat(pat);

compiler/rustc_parse/src/parser/expr.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use super::{
1010
use crate::errors;
1111
use crate::maybe_recover_from_interpolated_ty_qpath;
1212
use ast::mut_visit::{noop_visit_expr, MutVisitor};
13-
use ast::{CoroutineKind, GenBlockKind, Pat, Path, PathSegment};
13+
use ast::{CoroutineKind, ForLoopKind, GenBlockKind, Pat, Path, PathSegment};
1414
use core::mem;
1515
use rustc_ast::ptr::P;
1616
use rustc_ast::token::{self, Delimiter, Token, TokenKind};
@@ -2689,6 +2689,8 @@ impl<'a> Parser<'a> {
26892689
self.sess.gated_spans.gate(sym::async_iterator, self.prev_token.span);
26902690
}
26912691

2692+
let kind = if is_await { ForLoopKind::ForAwait } else { ForLoopKind::For };
2693+
26922694
let (pat, expr) = self.parse_for_head()?;
26932695
// Recover from missing expression in `for` loop
26942696
if matches!(expr.kind, ExprKind::Block(..))
@@ -2701,14 +2703,13 @@ impl<'a> Parser<'a> {
27012703
let block = self.mk_block(thin_vec![], BlockCheckMode::Default, self.prev_token.span);
27022704
return Ok(self.mk_expr(
27032705
lo.to(self.prev_token.span),
2704-
ExprKind::ForLoop { pat, iter: err_expr, body: block, label: opt_label, is_await },
2706+
ExprKind::ForLoop { pat, iter: err_expr, body: block, label: opt_label, kind },
27052707
));
27062708
}
27072709

27082710
let (attrs, loop_block) = self.parse_inner_attrs_and_block()?;
27092711

2710-
let kind =
2711-
ExprKind::ForLoop { pat, iter: expr, body: loop_block, label: opt_label, is_await };
2712+
let kind = ExprKind::ForLoop { pat, iter: expr, body: loop_block, label: opt_label, kind };
27122713

27132714
self.recover_loop_else("for", lo)?;
27142715

compiler/rustc_resolve/src/late.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -4250,7 +4250,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
42504250
});
42514251
}
42524252

4253-
ExprKind::ForLoop { ref pat, ref iter, ref body, label, is_await: _ } => {
4253+
ExprKind::ForLoop { ref pat, ref iter, ref body, label, kind: _ } => {
42544254
self.visit_expr(iter);
42554255
self.with_rib(ValueNS, RibKind::Normal, |this| {
42564256
this.resolve_pattern_top(pat, PatternSource::For);

src/tools/clippy/clippy_utils/src/ast_utils.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -175,16 +175,16 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool {
175175
iter: li,
176176
body: lt,
177177
label: ll,
178-
is_await: la,
178+
kind: lk,
179179
},
180180
ForLoop {
181181
pat: rp,
182182
iter: ri,
183183
body: rt,
184184
label: rl,
185-
is_await: ra,
185+
kind: rk,
186186
},
187-
) => eq_label(ll, rl) && eq_pat(lp, rp) && eq_expr(li, ri) && eq_block(lt, rt) && la == ra,
187+
) => eq_label(ll, rl) && eq_pat(lp, rp) && eq_expr(li, ri) && eq_block(lt, rt) && lk == rk,
188188
(Loop(lt, ll, _), Loop(rt, rl, _)) => eq_label(ll, rl) && eq_block(lt, rt),
189189
(Block(lb, ll), Block(rb, rl)) => eq_label(ll, rl) && eq_block(lb, rb),
190190
(TryBlock(l), TryBlock(r)) => eq_block(l, r),

0 commit comments

Comments
 (0)