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