1use crate::ast::prelude::*;
23#[test]
4#[cfg(not(miri))]
5fn ast_parse() {
6 rt::<ast::ExprFor>("for i in x {}");
7 rt::<ast::ExprFor>("for (a, _) in x {}");
8 rt::<ast::ExprFor>("'label: for i in x {}");
9 rt::<ast::ExprFor>("#[attr] 'label: for i in x {}");
10}
1112/// A `for` loop over an iterator.
13///
14/// * `for <pat> in <expr> <block>`.
15#[derive(Debug, TryClone, PartialEq, Eq, ToTokens, Spanned)]
16#[non_exhaustive]
17pub struct ExprFor {
18/// The attributes of the `for` loop
19#[rune(iter)]
20pub attributes: Vec<ast::Attribute>,
21/// The label of the loop.
22#[rune(iter)]
23pub label: Option<(ast::Label, T![:])>,
24/// The `for` keyword.
25pub for_token: T![for],
26/// The pattern binding to use.
27 /// Non-trivial pattern bindings will panic if the value doesn't match.
28pub binding: ast::Pat,
29/// The `in` keyword.
30pub in_: T![in],
31/// Expression producing the iterator.
32pub iter: Box<ast::Expr>,
33/// The body of the loop.
34pub body: Box<ast::Block>,
35}
3637impl ExprFor {
38/// Parse with the given attributes and label.
39pub(crate) fn parse_with_meta(
40 parser: &mut Parser<'_>,
41 attributes: Vec<ast::Attribute>,
42 label: Option<(ast::Label, T![:])>,
43 ) -> Result<Self> {
44Ok(Self {
45 attributes,
46 label,
47 for_token: parser.parse()?,
48 binding: parser.parse()?,
49 in_: parser.parse()?,
50 iter: Box::try_new(ast::Expr::parse_without_eager_brace(parser)?)?,
51 body: Box::try_new(parser.parse()?)?,
52 })
53 }
54}
5556expr_parse!(For, ExprFor, "for loop expression");