Skip to main content

rune/ast/
expr.rs

1use core::mem::take;
2use core::ops;
3
4use crate::ast::prelude::*;
5
6#[test]
7#[cfg(not(miri))]
8fn ast_parse() {
9    rt::<ast::Expr>("()");
10    rt::<ast::Expr>("foo[\"foo\"]");
11    rt::<ast::Expr>("foo[\"bar\"]");
12    rt::<ast::Expr>("foo.bar()");
13    rt::<ast::Expr>("var()");
14    rt::<ast::Expr>("var");
15    rt::<ast::Expr>("42");
16    rt::<ast::Expr>("1 + 2 / 3 - 4 * 1");
17    rt::<ast::Expr>("let var = 42");
18    rt::<ast::Expr>("let var = \"foo bar\"");
19    rt::<ast::Expr>("var[\"foo\"] = \"bar\"");
20    rt::<ast::Expr>("let var = objects[\"foo\"] + 1");
21    rt::<ast::Expr>("var = 42");
22
23    let expr = rt::<ast::Expr>(
24        r#"
25        if 1 { } else { if 2 { } else { } }
26    "#,
27    );
28    assert!(matches!(expr, ast::Expr::If(..)));
29
30    // Chained function calls.
31    rt::<ast::Expr>("foo.bar.baz()");
32    rt::<ast::Expr>("foo[0][1][2]");
33    rt::<ast::Expr>("foo.bar()[0].baz()[1]");
34
35    rt::<ast::Expr>("42 is i64::i64");
36    rt::<ast::Expr>("{ let x = 1; x }");
37
38    let expr = rt::<ast::Expr>("#[cfg(debug_assertions)] { assert_eq(x, 32); }");
39    assert!(
40        matches!(expr, ast::Expr::Block(b) if b.attributes.len() == 1 && b.block.statements.len() == 1)
41    );
42
43    rt::<ast::Expr>("#{\"foo\": b\"bar\"}");
44    rt::<ast::Expr>("Disco {\"never_died\": true }");
45    rt::<ast::Expr>("(false, 1, 'n')");
46    rt::<ast::Expr>("[false, 1, 'b']");
47
48    let expr = rt::<ast::Expr>(r#"if true {} else {}"#);
49    assert!(matches!(expr, ast::Expr::If(..)));
50
51    let expr = rt::<ast::Expr>("if 1 { } else { if 2 { } else { } }");
52    assert!(matches!(expr, ast::Expr::If(..)));
53
54    let expr = rt::<ast::Expr>(r#"while true {}"#);
55    assert!(matches!(expr, ast::Expr::While(..)));
56
57    rt::<ast::Expr>("format!(\"{}\", a).bar()");
58}
59
60/// Indicator that an expression should be parsed with an eager brace.
61#[derive(Debug, Clone, Copy)]
62pub(crate) struct EagerBrace(bool);
63
64/// Indicates that an expression should be parsed with eager braces.
65pub(crate) const EAGER_BRACE: EagerBrace = EagerBrace(true);
66
67/// Indicates that an expression should not be parsed with eager braces. This is
68/// used to solve a parsing ambiguity.
69pub(crate) const NOT_EAGER_BRACE: EagerBrace = EagerBrace(false);
70
71impl ops::Deref for EagerBrace {
72    type Target = bool;
73
74    fn deref(&self) -> &Self::Target {
75        &self.0
76    }
77}
78
79/// Indicator that an expression should be parsed as an eager binary expression.
80#[derive(Debug, Clone, Copy)]
81pub(crate) struct EagerBinary(bool);
82
83/// Indicates that an expression should be parsed as a binary expression.
84pub(crate) const EAGER_BINARY: EagerBinary = EagerBinary(true);
85
86/// Indicates that an expression should not be parsed as a binary expression.
87pub(crate) const NOT_EAGER_BINARY: EagerBinary = EagerBinary(false);
88
89impl ops::Deref for EagerBinary {
90    type Target = bool;
91
92    fn deref(&self) -> &Self::Target {
93        &self.0
94    }
95}
96
97/// Indicates if an expression can be called. By default, this depends on if the
98/// expression is a block expression (no) or not (yes). This allows the caller
99/// to contextually override that behavior.
100#[derive(Debug, Clone, Copy)]
101pub(crate) struct Callable(bool);
102
103/// Indicates that an expression should be treated as if it could be callable.
104/// Such as `foo::bar(42)`.
105pub(crate) const CALLABLE: Callable = Callable(true);
106
107/// Indicates that an expression should be treated as if it's *not* callable.
108/// This is used to solve otherwise parsing ambiguities, such as when a
109/// block-like expression in statement position is followed by parenthesis like
110/// `if true { } (1, 2, 3);`. It is treated as two statements rather than call.
111pub(crate) const NOT_CALLABLE: Callable = Callable(false);
112
113impl ops::Deref for Callable {
114    type Target = bool;
115
116    fn deref(&self) -> &Self::Target {
117        &self.0
118    }
119}
120
121/// A rune expression.
122#[derive(Debug, TryClone, PartialEq, Eq, ToTokens, Spanned)]
123#[non_exhaustive]
124pub enum Expr {
125    /// An path expression.
126    Path(ast::Path),
127    /// An assign expression.
128    Assign(ast::ExprAssign),
129    /// A while loop.
130    While(ast::ExprWhile),
131    /// An unconditional loop.
132    Loop(ast::ExprLoop),
133    /// An for loop.
134    For(ast::ExprFor),
135    /// A let expression.
136    Let(ast::ExprLet),
137    /// An if expression.
138    If(ast::ExprIf),
139    /// An match expression.
140    Match(ast::ExprMatch),
141    /// A function call,
142    Call(ast::ExprCall),
143    /// A field access on an expression.
144    FieldAccess(ast::ExprFieldAccess),
145    /// A binary expression.
146    Binary(ast::ExprBinary),
147    /// A unary expression.
148    Unary(ast::ExprUnary),
149    /// An index set operation.
150    Index(ast::ExprIndex),
151    /// A break expression.
152    Break(ast::ExprBreak),
153    /// A continue expression.
154    Continue(ast::ExprContinue),
155    /// A yield expression.
156    Yield(ast::ExprYield),
157    /// A block as an expression.
158    Block(ast::ExprBlock),
159    /// A return statement.
160    Return(ast::ExprReturn),
161    /// An await expression.
162    Await(ast::ExprAwait),
163    /// Try expression.
164    Try(ast::ExprTry),
165    /// A select expression.
166    Select(ast::ExprSelect),
167    /// A closure expression.
168    Closure(ast::ExprClosure),
169    /// A literal expression.
170    Lit(ast::ExprLit),
171    /// An object literal
172    Object(ast::ExprObject),
173    /// A tuple literal
174    Tuple(ast::ExprTuple),
175    /// A vec literal
176    Vec(ast::ExprVec),
177    /// A range expression.
178    Range(ast::ExprRange),
179    /// A grouped empty expression.
180    Empty(ast::ExprEmpty),
181    /// A grouped expression.
182    Group(ast::ExprGroup),
183    /// A macro call,
184    MacroCall(ast::MacroCall),
185}
186
187impl Expr {
188    /// Indicates if an expression is callable unless it's permitted by an
189    /// override.
190    pub(crate) fn is_callable(&self, callable: bool) -> bool {
191        match self {
192            Self::While(_) => false,
193            Self::Loop(_) => callable,
194            Self::For(_) => false,
195            Self::If(_) => callable,
196            Self::Match(_) => callable,
197            Self::Select(_) => callable,
198            Self::Block(_) => callable,
199            _ => true,
200        }
201    }
202
203    /// Take the attributes from the expression.
204    pub(crate) fn take_attributes(&mut self) -> Vec<ast::Attribute> {
205        match self {
206            Self::Path(_) => Vec::new(),
207            Self::Break(expr) => take(&mut expr.attributes),
208            Self::Continue(expr) => take(&mut expr.attributes),
209            Self::Yield(expr) => take(&mut expr.attributes),
210            Self::Block(expr) => take(&mut expr.attributes),
211            Self::Return(expr) => take(&mut expr.attributes),
212            Self::Closure(expr) => take(&mut expr.attributes),
213            Self::Match(expr) => take(&mut expr.attributes),
214            Self::While(expr) => take(&mut expr.attributes),
215            Self::Loop(expr) => take(&mut expr.attributes),
216            Self::For(expr) => take(&mut expr.attributes),
217            Self::Let(expr) => take(&mut expr.attributes),
218            Self::If(expr) => take(&mut expr.attributes),
219            Self::Select(expr) => take(&mut expr.attributes),
220            Self::Lit(expr) => take(&mut expr.attributes),
221            Self::Assign(expr) => take(&mut expr.attributes),
222            Self::Binary(expr) => take(&mut expr.attributes),
223            Self::Call(expr) => take(&mut expr.attributes),
224            Self::FieldAccess(expr) => take(&mut expr.attributes),
225            Self::Group(expr) => take(&mut expr.attributes),
226            Self::Empty(expr) => take(&mut expr.attributes),
227            Self::Unary(expr) => take(&mut expr.attributes),
228            Self::Index(expr) => take(&mut expr.attributes),
229            Self::Await(expr) => take(&mut expr.attributes),
230            Self::Try(expr) => take(&mut expr.attributes),
231            Self::Object(expr) => take(&mut expr.attributes),
232            Self::Range(expr) => take(&mut expr.attributes),
233            Self::Vec(expr) => take(&mut expr.attributes),
234            Self::Tuple(expr) => take(&mut expr.attributes),
235            Self::MacroCall(expr) => take(&mut expr.attributes),
236        }
237    }
238
239    /// Check if this expression is a literal expression.
240    ///
241    /// There are exactly two kinds of literal expressions:
242    /// * Ones that are ExprLit
243    /// * Unary expressions which are the negate operation.
244    pub(crate) fn is_lit(&self) -> bool {
245        match self {
246            Self::Lit(..) => return true,
247            Self::Unary(ast::ExprUnary {
248                op: ast::UnOp::Neg(..),
249                expr,
250                ..
251            }) => {
252                return matches!(
253                    &**expr,
254                    Self::Lit(ast::ExprLit {
255                        lit: ast::Lit::Number(..),
256                        ..
257                    })
258                );
259            }
260            _ => (),
261        }
262
263        false
264    }
265
266    /// Internal function to construct a literal expression.
267    pub(crate) fn from_lit(lit: ast::Lit) -> Self {
268        Self::Lit(ast::ExprLit {
269            attributes: Vec::new(),
270            lit,
271        })
272    }
273
274    /// Parse an expression without an eager brace.
275    ///
276    /// This is used to solve a syntax ambiguity when parsing expressions that
277    /// are arguments to statements immediately followed by blocks. Like `if`,
278    /// `while`, and `match`.
279    pub(crate) fn parse_without_eager_brace(p: &mut Parser<'_>) -> Result<Self> {
280        Self::parse_with(p, NOT_EAGER_BRACE, EAGER_BINARY, CALLABLE)
281    }
282
283    /// Helper to perform a parse with the given meta.
284    ///
285    /// Every nested expression is parsed through here or through
286    /// [`Expr::parse_with`], so this is where how deep an expression is allowed
287    /// to get is bounded.
288    pub(crate) fn parse_with_meta(
289        p: &mut Parser<'_>,
290        attributes: &mut Vec<ast::Attribute>,
291        callable: Callable,
292    ) -> Result<Self> {
293        p.nested(|p| {
294            let lhs = primary(p, attributes, EAGER_BRACE, callable)?;
295            let lookahead = ast::BinOp::from_peeker(p.peeker());
296            binary(p, lhs, lookahead, 0, EAGER_BRACE)
297        })
298    }
299
300    /// ull, configurable parsing of an expression.F
301    pub(crate) fn parse_with(
302        p: &mut Parser<'_>,
303        eager_brace: EagerBrace,
304        eager_binary: EagerBinary,
305        callable: Callable,
306    ) -> Result<Self> {
307        p.nested(|p| {
308            let mut attributes = p.parse()?;
309
310            let expr = primary(p, &mut attributes, eager_brace, callable)?;
311
312            let expr = if *eager_binary {
313                let lookeahead = ast::BinOp::from_peeker(p.peeker());
314                binary(p, expr, lookeahead, 0, eager_brace)?
315            } else {
316                expr
317            };
318
319            if let Some(span) = attributes.option_span() {
320                return Err(compile::Error::unsupported(span, "attributes"));
321            }
322
323            Ok(expr)
324        })
325    }
326
327    /// Parse expressions that start with an identifier.
328    pub(crate) fn parse_with_meta_path(
329        p: &mut Parser<'_>,
330        attributes: &mut Vec<ast::Attribute>,
331        path: ast::Path,
332        eager_brace: EagerBrace,
333    ) -> Result<Self> {
334        if *eager_brace && p.peek::<T!['{']>()? {
335            let ident = ast::ObjectIdent::Named(path);
336
337            return Ok(Self::Object(ast::ExprObject::parse_with_meta(
338                p,
339                take(attributes),
340                ident,
341            )?));
342        }
343
344        if p.peek::<T![!]>()? {
345            return Ok(Self::MacroCall(ast::MacroCall::parse_with_meta_path(
346                p,
347                take(attributes),
348                path,
349            )?));
350        }
351
352        Ok(Self::Path(path))
353    }
354
355    pub(crate) fn peek_with_brace(p: &mut Peeker<'_>, eager_brace: EagerBrace) -> bool {
356        match p.nth(0) {
357            K![async] => true,
358            K![self] => true,
359            K![select] => true,
360            K![#] => true,
361            K![-] => true,
362            K![!] => true,
363            K![&] => true,
364            K![*] => true,
365            K![while] => true,
366            K![loop] => true,
367            K![for] => true,
368            K![let] => true,
369            K![if] => true,
370            K![break] => true,
371            K![continue] => true,
372            K![return] => true,
373            K![true] => true,
374            K![false] => true,
375            K![ident] => true,
376            K![::] => true,
377            K![number] => true,
378            K![char] => true,
379            K![byte] => true,
380            K![str] => true,
381            K![bytestr] => true,
382            K!['label] => matches!(p.nth(1), K![:]),
383            K![..] => true,
384            K!['('] => true,
385            K!['['] => true,
386            K!['{'] if *eager_brace => true,
387            _ => false,
388        }
389    }
390}
391
392impl Parse for Expr {
393    fn parse(p: &mut Parser<'_>) -> Result<Self> {
394        Self::parse_with(p, EAGER_BRACE, EAGER_BINARY, CALLABLE)
395    }
396}
397
398impl Peek for Expr {
399    fn peek(p: &mut Peeker<'_>) -> bool {
400        Self::peek_with_brace(p, EAGER_BRACE)
401    }
402}
403
404/// Primary parse entry point.
405fn primary(
406    p: &mut Parser<'_>,
407    attributes: &mut Vec<ast::Attribute>,
408    eager_brace: EagerBrace,
409    callable: Callable,
410) -> Result<Expr> {
411    let expr = base(p, attributes, eager_brace)?;
412    chain(p, expr, callable)
413}
414
415/// Parse a basic expression.
416fn base(
417    p: &mut Parser<'_>,
418    attributes: &mut Vec<ast::Attribute>,
419    eager_brace: EagerBrace,
420) -> Result<Expr> {
421    if let Some(path) = p.parse::<Option<ast::Path>>()? {
422        return Expr::parse_with_meta_path(p, attributes, path, eager_brace);
423    }
424
425    if ast::Lit::peek_in_expr(p.peeker()) {
426        return Ok(Expr::Lit(ast::ExprLit::parse_with_meta(
427            p,
428            take(attributes),
429        )?));
430    }
431
432    let mut label = p.parse::<Option<(ast::Label, T![:])>>()?;
433    let mut async_token = p.parse::<Option<T![async]>>()?;
434    let mut const_token = p.parse::<Option<T![const]>>()?;
435    let mut move_token = p.parse::<Option<T![move]>>()?;
436
437    let expr = match p.nth(0)? {
438        K![..] => {
439            let limits = ast::ExprRangeLimits::HalfOpen(p.parse()?);
440            range(p, take(attributes), None, limits, eager_brace)?
441        }
442        K![..=] => {
443            let limits = ast::ExprRangeLimits::Closed(p.parse()?);
444            range(p, take(attributes), None, limits, eager_brace)?
445        }
446        K![#] => {
447            let ident = ast::ObjectIdent::Anonymous(p.parse()?);
448
449            Expr::Object(ast::ExprObject::parse_with_meta(
450                p,
451                take(attributes),
452                ident,
453            )?)
454        }
455        K![||] | K![|] => Expr::Closure(ast::ExprClosure::parse_with_meta(
456            p,
457            take(attributes),
458            take(&mut async_token),
459            take(&mut move_token),
460        )?),
461        K![select] => Expr::Select(ast::ExprSelect::parse_with_attributes(p, take(attributes))?),
462        K![!] | K![-] | K![&] | K![*] => Expr::Unary(ast::ExprUnary::parse_with_meta(
463            p,
464            take(attributes),
465            eager_brace,
466        )?),
467        K![while] => Expr::While(ast::ExprWhile::parse_with_meta(
468            p,
469            take(attributes),
470            take(&mut label),
471        )?),
472        K![loop] => Expr::Loop(ast::ExprLoop::parse_with_meta(
473            p,
474            take(attributes),
475            take(&mut label),
476        )?),
477        K![for] => Expr::For(ast::ExprFor::parse_with_meta(
478            p,
479            take(attributes),
480            take(&mut label),
481        )?),
482        K![let] => Expr::Let(ast::ExprLet::parse_with_meta(p, take(attributes))?),
483        K![if] => Expr::If(ast::ExprIf::parse_with_meta(p, take(attributes))?),
484        K![match] => Expr::Match(ast::ExprMatch::parse_with_attributes(p, take(attributes))?),
485        K!['['] => Expr::Vec(ast::ExprVec::parse_with_meta(p, take(attributes))?),
486        ast::Kind::Open(ast::Delimiter::Empty) => empty_group(p, take(attributes))?,
487        K!['('] => paren_group(p, take(attributes))?,
488        K!['{'] => Expr::Block(ast::ExprBlock {
489            attributes: take(attributes),
490            async_token: take(&mut async_token),
491            const_token: take(&mut const_token),
492            move_token: take(&mut move_token),
493            label: take(&mut label),
494            block: p.parse()?,
495        }),
496        K![break] => Expr::Break(ast::ExprBreak::parse_with_meta(p, take(attributes))?),
497        K![continue] => Expr::Continue(ast::ExprContinue::parse_with_meta(p, take(attributes))?),
498        K![yield] => Expr::Yield(ast::ExprYield::parse_with_meta(p, take(attributes))?),
499        K![return] => Expr::Return(ast::ExprReturn::parse_with_meta(p, take(attributes))?),
500        _ => {
501            return Err(compile::Error::expected(
502                p.tok_at(0)?,
503                Expectation::Expression,
504            ));
505        }
506    };
507
508    if let Some(span) = label.option_span() {
509        return Err(compile::Error::unsupported(span, "label"));
510    }
511
512    if let Some(span) = async_token.option_span() {
513        return Err(compile::Error::unsupported(span, "async modifier"));
514    }
515
516    if let Some(span) = const_token.option_span() {
517        return Err(compile::Error::unsupported(span, "const modifier"));
518    }
519
520    if let Some(span) = move_token.option_span() {
521        return Err(compile::Error::unsupported(span, "move modifier"));
522    }
523
524    Ok(expr)
525}
526
527/// Parse an expression chain.
528///
529/// A chain is flat in the source but each link wraps the expression parsed so
530/// far, so the tree gets one level deeper per link even though this loops
531/// rather than recurses. Each link is accounted for as depth.
532fn chain(p: &mut Parser<'_>, mut expr: Expr, callable: Callable) -> Result<Expr> {
533    while !p.is_eof()? {
534        let is_callable = expr.is_callable(*callable);
535
536        match p.nth(0)? {
537            K!['['] if is_callable => {
538                p.link()?;
539
540                expr = Expr::Index(ast::ExprIndex {
541                    attributes: expr.take_attributes(),
542                    target: Box::try_new(expr)?,
543                    open: p.parse()?,
544                    index: p.parse()?,
545                    close: p.parse()?,
546                });
547            }
548            // Chained function call.
549            K!['('] if is_callable => {
550                p.link()?;
551
552                expr = Expr::Call(ast::ExprCall::parse_with_meta(
553                    p,
554                    expr.take_attributes(),
555                    Box::try_new(expr)?,
556                )?);
557            }
558            K![?] => {
559                p.link()?;
560
561                expr = Expr::Try(ast::ExprTry {
562                    attributes: expr.take_attributes(),
563                    expr: Box::try_new(expr)?,
564                    try_token: p.parse()?,
565                });
566            }
567            K![=] => {
568                p.link()?;
569
570                let eq = p.parse()?;
571                let rhs = Expr::parse_with(p, EAGER_BRACE, EAGER_BINARY, CALLABLE)?;
572
573                expr = Expr::Assign(ast::ExprAssign {
574                    attributes: expr.take_attributes(),
575                    lhs: Box::try_new(expr)?,
576                    eq,
577                    rhs: Box::try_new(rhs)?,
578                });
579            }
580            K![.] => {
581                p.link()?;
582
583                match p.nth(1)? {
584                    // <expr>.await
585                    K![await] => {
586                        expr = Expr::Await(ast::ExprAwait {
587                            attributes: expr.take_attributes(),
588                            expr: Box::try_new(expr)?,
589                            dot: p.parse()?,
590                            await_token: p.parse()?,
591                        });
592                    }
593                    // <expr>.field
594                    K![ident] => {
595                        expr = Expr::FieldAccess(ast::ExprFieldAccess {
596                            attributes: expr.take_attributes(),
597                            expr: Box::try_new(expr)?,
598                            dot: p.parse()?,
599                            expr_field: ast::ExprField::Path(p.parse()?),
600                        });
601                    }
602                    // tuple access: <expr>.<number>
603                    K![number] => {
604                        expr = Expr::FieldAccess(ast::ExprFieldAccess {
605                            attributes: expr.take_attributes(),
606                            expr: Box::try_new(expr)?,
607                            dot: p.parse()?,
608                            expr_field: ast::ExprField::LitNumber(p.parse()?),
609                        });
610                    }
611                    _ => {
612                        return Err(compile::Error::new(p.span(0..1), ErrorKind::BadFieldAccess));
613                    }
614                }
615            }
616            _ => break,
617        }
618    }
619
620    Ok(expr)
621}
622
623/// Parse a binary expression.
624fn binary(
625    p: &mut Parser<'_>,
626    mut lhs: Expr,
627    mut lookahead: Option<ast::BinOp>,
628    min_precedence: usize,
629    eager_brace: EagerBrace,
630) -> Result<Expr> {
631    while let Some(op) = lookahead {
632        let precedence = op.precedence();
633
634        if precedence < min_precedence {
635            break;
636        }
637
638        // Operands of the same precedence are parsed over this loop rather than
639        // by recursing, but each one still wraps the expression parsed so far.
640        p.link()?;
641
642        op.advance(p)?;
643
644        match op {
645            ast::BinOp::DotDot(token) => {
646                lhs = range(
647                    p,
648                    lhs.take_attributes(),
649                    Some(Box::try_new(lhs)?),
650                    ast::ExprRangeLimits::HalfOpen(token),
651                    eager_brace,
652                )?;
653                lookahead = ast::BinOp::from_peeker(p.peeker());
654                continue;
655            }
656            ast::BinOp::DotDotEq(token) => {
657                lhs = range(
658                    p,
659                    lhs.take_attributes(),
660                    Some(Box::try_new(lhs)?),
661                    ast::ExprRangeLimits::Closed(token),
662                    eager_brace,
663                )?;
664                lookahead = ast::BinOp::from_peeker(p.peeker());
665                continue;
666            }
667            _ => (),
668        }
669
670        let mut rhs = primary(p, &mut Vec::new(), eager_brace, CALLABLE)?;
671        lookahead = ast::BinOp::from_peeker(p.peeker());
672
673        while let Some(next) = lookahead {
674            match (precedence, next.precedence()) {
675                (lh, rh) if lh < rh => {
676                    // Higher precedence elements require us to recurse.
677                    rhs = binary(p, rhs, Some(next), lh + 1, eager_brace)?;
678                    lookahead = ast::BinOp::from_peeker(p.peeker());
679                    continue;
680                }
681                (lh, rh) if lh == rh && !next.is_assoc() => {
682                    return Err(compile::Error::new(
683                        lhs.span().join(rhs.span()),
684                        ErrorKind::PrecedenceGroupRequired,
685                    ));
686                }
687                _ => {}
688            };
689
690            break;
691        }
692
693        lhs = Expr::Binary(ast::ExprBinary {
694            attributes: lhs.take_attributes(),
695            lhs: Box::try_new(lhs)?,
696            op,
697            rhs: Box::try_new(rhs)?,
698        });
699    }
700
701    Ok(lhs)
702}
703
704/// Parse the tail-end of a range.
705fn range(
706    p: &mut Parser<'_>,
707    attributes: Vec<ast::Attribute>,
708    from: Option<Box<Expr>>,
709    limits: ast::ExprRangeLimits,
710    eager_brace: EagerBrace,
711) -> Result<Expr> {
712    let to = if Expr::peek_with_brace(p.peeker(), eager_brace) {
713        Some(Box::try_new(Expr::parse_with(
714            p,
715            eager_brace,
716            EAGER_BINARY,
717            CALLABLE,
718        )?)?)
719    } else {
720        None
721    };
722
723    Ok(Expr::Range(ast::ExprRange {
724        attributes,
725        start: from,
726        limits,
727        end: to,
728    }))
729}
730
731/// Parsing something that opens with an empty group marker.
732fn empty_group(p: &mut Parser<'_>, attributes: Vec<ast::Attribute>) -> Result<Expr> {
733    let open = p.parse::<ast::OpenEmpty>()?;
734    let expr = p.parse::<Expr>()?;
735    let close = p.parse::<ast::CloseEmpty>()?;
736
737    Ok(Expr::Empty(ast::ExprEmpty {
738        attributes,
739        open,
740        expr: Box::try_new(expr)?,
741        close,
742    }))
743}
744
745/// Parsing something that opens with a parenthesis.
746fn paren_group(p: &mut Parser<'_>, attributes: Vec<ast::Attribute>) -> Result<Expr> {
747    // Empty tuple.
748    if let (K!['('], K![')']) = (p.nth(0)?, p.nth(1)?) {
749        return Ok(Expr::Tuple(ast::ExprTuple::parse_with_meta(p, attributes)?));
750    }
751
752    let open = p.parse::<T!['(']>()?;
753    let expr = p.parse::<Expr>()?;
754
755    // Priority expression group.
756    if p.peek::<T![')']>()? {
757        return Ok(Expr::Group(ast::ExprGroup {
758            attributes,
759            open,
760            expr: Box::try_new(expr)?,
761            close: p.parse()?,
762        }));
763    }
764
765    // Tuple expression. These are distinguished from a group with a single item
766    // by adding a `,` at the end like `(foo,)`.
767    Ok(Expr::Tuple(ast::ExprTuple::parse_from_first_expr(
768        p, attributes, open, expr,
769    )?))
770}