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