fe_parser/grammar/
functions.rs

1use super::expressions::parse_expr;
2use super::types::parse_type_desc;
3
4use crate::ast::{
5    BinOperator, Expr, FuncStmt, Function, FunctionArg, FunctionSignature, GenericParameter,
6    LiteralPattern, MatchArm, Path, Pattern, TypeDesc, VarDeclTarget,
7};
8use crate::node::{Node, Span};
9use crate::{Label, ParseFailed, ParseResult, Parser, TokenKind};
10
11/// Parse a function definition without a body. The optional `pub` qualifier
12/// must be parsed by the caller, and passed in. Next token must be `unsafe` or
13/// `fn`.
14pub fn parse_fn_sig(
15    par: &mut Parser,
16    mut pub_qual: Option<Span>,
17) -> ParseResult<Node<FunctionSignature>> {
18    let unsafe_qual = par.optional(TokenKind::Unsafe).map(|tok| tok.span);
19    if let Some(pub_) = par.optional(TokenKind::Pub) {
20        let unsafe_span =
21            unsafe_qual.expect("caller must verify that next token is `unsafe` or `fn`");
22
23        par.fancy_error(
24            "`pub` visibility modifier must come before `unsafe`",
25            vec![Label::primary(
26                unsafe_span + pub_.span,
27                "use `pub unsafe` here",
28            )],
29            vec![],
30        );
31        pub_qual = pub_qual.or(Some(pub_.span));
32    }
33    let fn_tok = par.expect(TokenKind::Fn, "failed to parse function definition")?;
34    let name = par.expect(TokenKind::Name, "failed to parse function definition")?;
35
36    let mut span = fn_tok.span + name.span + unsafe_qual + pub_qual;
37
38    let generic_params = if par.peek() == Some(TokenKind::Lt) {
39        parse_generic_params(par)?
40    } else {
41        Node::new(vec![], name.span)
42    };
43
44    let args = match par.peek_or_err()? {
45        TokenKind::ParenOpen => {
46            let node = parse_fn_param_list(par)?;
47            span += node.span;
48            node.kind
49        }
50        TokenKind::BraceOpen | TokenKind::Arrow => {
51            par.fancy_error(
52                "function definition requires a list of parameters",
53                vec![Label::primary(
54                    name.span,
55                    "function name must be followed by `(`",
56                )],
57                vec![
58                    format!(
59                        "Note: if the function `{}` takes no parameters, use an empty set of parentheses.",
60                        name.text
61                    ),
62                    format!("Example: fn {}()", name.text),
63                    "Note: each parameter must have a name and a type.".into(),
64                    format!("Example: fn {}(my_value: u256, x: bool)", name.text),
65                ],
66            );
67            vec![]
68        }
69        _ => {
70            let tok = par.next()?;
71            par.unexpected_token_error(
72                &tok,
73                "failed to parse function definition",
74                vec![
75                    "function name must be followed by a list of parameters".into(),
76                    "Example: `fn foo(x: address, y: u256)` or `fn f()`".into(),
77                ],
78            );
79            return Err(ParseFailed);
80        }
81    };
82    let return_type = if par.peek() == Some(TokenKind::Arrow) {
83        par.next()?;
84        let typ = parse_type_desc(par)?;
85        span += typ.span;
86        Some(typ)
87    } else {
88        None
89    };
90
91    Ok(Node::new(
92        FunctionSignature {
93            pub_: pub_qual,
94            unsafe_: unsafe_qual,
95            name: name.into(),
96            args,
97            generic_params,
98            return_type,
99        },
100        span,
101    ))
102}
103
104/// Parse a function definition. The optional `pub` qualifier must be parsed by
105/// the caller, and passed in. Next token must be `unsafe` or `fn`.
106pub fn parse_fn_def(par: &mut Parser, pub_qual: Option<Span>) -> ParseResult<Node<Function>> {
107    let sig = parse_fn_sig(par, pub_qual)?;
108
109    // TODO: allow multi-line return type? `fn f()\n ->\n u8`
110    par.enter_block(sig.span, "function definition")?;
111    let body = parse_block_stmts(par)?;
112    let rbrace = par.expect(TokenKind::BraceClose, "missing `}` in fn definition")?;
113
114    Ok(Node::new(
115        Function {
116            sig: sig.clone(),
117            body,
118        },
119        sig.span + rbrace.span,
120    ))
121}
122
123/// Parse a single generic function parameter (eg. `T:SomeTrait` in `fn foo<T:
124/// SomeTrait>(some_arg: u256) -> bool`). # Panics
125/// Panics if the first token isn't `Name`.
126pub fn parse_generic_param(par: &mut Parser) -> ParseResult<GenericParameter> {
127    use TokenKind::*;
128
129    let name = par.assert(Name);
130    match par.optional(Colon) {
131        Some(_) => {
132            let bound = par.expect(TokenKind::Name, "failed to parse generic bound")?;
133            Ok(GenericParameter::Bounded {
134                name: Node::new(name.text.into(), name.span),
135                bound: Node::new(
136                    TypeDesc::Base {
137                        base: bound.text.into(),
138                    },
139                    bound.span,
140                ),
141            })
142        }
143        None => Ok(GenericParameter::Unbounded(Node::new(
144            name.text.into(),
145            name.span,
146        ))),
147    }
148}
149
150/// Parse an angle-bracket-wrapped list of generic arguments (eg. `<T, R:
151/// SomeTrait>` in `fn foo<T, R: SomeTrait>(some_arg: u256) -> bool`). # Panics
152/// Panics if the first token isn't `<`.
153pub fn parse_generic_params(par: &mut Parser) -> ParseResult<Node<Vec<GenericParameter>>> {
154    use TokenKind::*;
155    let mut span = par.assert(Lt).span;
156
157    let mut args = vec![];
158
159    let expect_end = |par: &mut Parser| {
160        // If there's no comma, the next token must be `>`
161        match par.peek_or_err()? {
162            Gt => Ok(par.next()?.span),
163            _ => {
164                let tok = par.next()?;
165                par.unexpected_token_error(
166                    &tok,
167                    "Unexpected token while parsing generic arg list",
168                    vec!["Expected a `>` here".to_string()],
169                );
170                Err(ParseFailed)
171            }
172        }
173    };
174
175    loop {
176        match par.peek_or_err()? {
177            Gt => {
178                span += par.next()?.span;
179                break;
180            }
181            Name => {
182                let typ = parse_generic_param(par)?;
183                args.push(typ);
184                if par.peek() == Some(Comma) {
185                    par.next()?;
186                } else {
187                    span += expect_end(par)?;
188                    break;
189                }
190            }
191
192            // Invalid generic argument.
193            _ => {
194                let tok = par.next()?;
195                par.unexpected_token_error(
196                    &tok,
197                    "failed to parse list of generic function parameters",
198                    vec!["Expected a generic parameter name such as `T` here".to_string()],
199                );
200                return Err(ParseFailed);
201            }
202        }
203    }
204    Ok(Node::new(args, span))
205}
206
207fn parse_fn_param_list(par: &mut Parser) -> ParseResult<Node<Vec<Node<FunctionArg>>>> {
208    let mut span = par.assert(TokenKind::ParenOpen).span;
209    let mut params = vec![];
210    loop {
211        match par.peek_or_err()? {
212            TokenKind::ParenClose => {
213                span += par.next()?.span;
214                break;
215            }
216            TokenKind::Mut | TokenKind::Name | TokenKind::SelfValue => {
217                params.push(parse_fn_param(par)?);
218
219                if par.peek() == Some(TokenKind::Comma) {
220                    par.next()?;
221                } else {
222                    span += par
223                        .expect(
224                            TokenKind::ParenClose,
225                            "unexpected token while parsing function parameter list",
226                        )?
227                        .span;
228                    break;
229                }
230            }
231            _ => {
232                let tok = par.next()?;
233                par.unexpected_token_error(&tok, "failed to parse function parameter list", vec![]);
234                return Err(ParseFailed);
235            }
236        }
237    }
238    Ok(Node::new(params, span))
239}
240
241fn parse_fn_param(par: &mut Parser) -> ParseResult<Node<FunctionArg>> {
242    let mut_ = par.optional(TokenKind::Mut).map(|tok| tok.span);
243
244    match par.peek_or_err()? {
245        TokenKind::SelfValue => Ok(Node::new(FunctionArg::Self_ { mut_ }, par.next()?.span)),
246        TokenKind::Name => {
247            let ident = par.next()?;
248
249            // Parameter can have an optional label specifier. Example:
250            //     fn transfer(from sender: address, to recipient: address, _ val: u256)
251            //     transfer(from: me, to: you, 100)
252
253            let (label, name) = match par.optional(TokenKind::Name) {
254                Some(name) => (Some(ident), name),
255                None => (None, ident),
256            };
257            par.expect_with_notes(
258                TokenKind::Colon,
259                "failed to parse function parameter",
260                |_| {
261                    vec![
262                        "Note: parameter name must be followed by a colon and a type description"
263                            .into(),
264                        format!("Example: `{}: u256`", name.text),
265                    ]
266                },
267            )?;
268            let typ = parse_type_desc(par)?;
269            let param_span = name.span + typ.span + mut_ + label.as_ref();
270            Ok(Node::new(
271                FunctionArg::Regular {
272                    mut_,
273                    label: label.map(Node::from),
274                    name: name.into(),
275                    typ,
276                },
277                param_span,
278            ))
279        }
280        _ => {
281            let tok = par.next()?;
282            par.unexpected_token_error(&tok, "failed to parse function parameter list", vec![]);
283            Err(ParseFailed)
284        }
285    }
286}
287
288/// Parse (function) statements until a `}` or end-of-file is reached.
289fn parse_block_stmts(par: &mut Parser) -> ParseResult<Vec<Node<FuncStmt>>> {
290    let mut body = vec![];
291    loop {
292        par.eat_newlines();
293        match par.peek_or_err()? {
294            TokenKind::BraceClose => break,
295            _ => body.push(parse_stmt(par)?),
296        }
297    }
298    Ok(body)
299}
300
301fn aug_assign_op(tk: TokenKind) -> Option<BinOperator> {
302    use BinOperator::*;
303    use TokenKind::*;
304
305    let op = match tk {
306        PlusEq => Add,
307        MinusEq => Sub,
308        StarEq => Mult,
309        SlashEq => Div,
310        PercentEq => Mod,
311        StarStarEq => Pow,
312        LtLtEq => LShift,
313        GtGtEq => RShift,
314        PipeEq => BitOr,
315        HatEq => BitXor,
316        AmperEq => BitAnd,
317        _ => return None,
318    };
319    Some(op)
320}
321
322/// Parse a `continue`, `break`, `pass`, or `revert` statement.
323///
324/// # Panics
325/// Panics if the next token isn't one of the above.
326pub fn parse_single_word_stmt(par: &mut Parser) -> ParseResult<Node<FuncStmt>> {
327    let tok = par.next()?;
328    par.expect_stmt_end(tok.kind.describe())?;
329    let stmt = match tok.kind {
330        TokenKind::Continue => FuncStmt::Continue,
331        TokenKind::Break => FuncStmt::Break,
332        _ => panic!(),
333    };
334    Ok(Node::new(stmt, tok.span))
335}
336
337/// Parse a function-level statement.
338pub fn parse_stmt(par: &mut Parser) -> ParseResult<Node<FuncStmt>> {
339    use TokenKind::*;
340
341    // rule: stmt parsing fns eat the trailing separator (newline, semi)
342    match par.peek_or_err()? {
343        For => parse_for_stmt(par),
344        If => parse_if_stmt(par),
345        Match => parse_match_stmt(par),
346        While => parse_while_stmt(par),
347        Return => parse_return_stmt(par),
348        Assert => parse_assert_stmt(par),
349        Revert => parse_revert_stmt(par),
350        Continue | Break => parse_single_word_stmt(par),
351        Let => parse_var_decl(par),
352        Const => parse_const_decl(par),
353        Unsafe => parse_unsafe_block(par),
354        _ => parse_expr_stmt(par),
355    }
356}
357
358fn parse_var_decl(par: &mut Parser) -> ParseResult<Node<FuncStmt>> {
359    let let_tkn = par.assert(TokenKind::Let);
360    let mut_ = par.optional(TokenKind::Mut).map(|t| t.span);
361    let expr = parse_expr(par)?;
362    let target = expr_to_vardecl_target(par, expr.clone())?;
363    let node = match par.peek() {
364        Some(TokenKind::Colon) => {
365            par.next()?;
366            let typ = parse_type_desc(par)?;
367            let value = if par.peek() == Some(TokenKind::Eq) {
368                par.next()?;
369                Some(parse_expr(par)?)
370            } else {
371                None
372            };
373            let span = let_tkn.span + target.span + typ.span + value.as_ref();
374            par.expect_stmt_end("variable declaration")?;
375            Node::new(
376                FuncStmt::VarDecl {
377                    mut_,
378                    target,
379                    typ,
380                    value,
381                },
382                span,
383            )
384        }
385        _ => {
386            par.fancy_error(
387                "failed to parse variable declaration",
388                vec![Label::primary(
389                    expr.span,
390                    "Must be followed by type annotation",
391                )],
392                vec!["Example: `let x: u8 = 1`".into()],
393            );
394            return Err(ParseFailed);
395        }
396    };
397    Ok(node)
398}
399
400fn parse_const_decl(par: &mut Parser) -> ParseResult<Node<FuncStmt>> {
401    let const_tok = par.assert(TokenKind::Const);
402    let name = par.expect(TokenKind::Name, "failed to parse constant declaration")?;
403    par.expect_with_notes(
404        TokenKind::Colon,
405        "failed to parse constant declaration",
406        |_| {
407            vec![
408                "Note: constant name must be followed by a colon and a type description".into(),
409                format!("Example: let `{}: u256 = 1000`", name.text),
410            ]
411        },
412    )?;
413    let typ = parse_type_desc(par)?;
414    par.expect_with_notes(
415        TokenKind::Eq,
416        "failed to parse constant declaration",
417        |_| {
418            vec![
419            "Note: the type of a constant must be followed by an equals sign and a value assignment"
420                .into(),
421                format!(
422                    "Example: let `{}: u256 = 1000`",
423                    name.text
424                ),
425        ]
426        },
427    )?;
428
429    let value = parse_expr(par)?;
430    par.expect_stmt_end("variable declaration")?;
431
432    let span = const_tok.span + value.span;
433    Ok(Node::new(
434        FuncStmt::ConstantDecl {
435            name: name.into(),
436            typ,
437            value,
438        },
439        span,
440    ))
441}
442
443/// Parse a (function) statement that begins with an expression. This might be
444/// a `VarDecl`, `Assign`, or an expression.
445fn parse_expr_stmt(par: &mut Parser) -> ParseResult<Node<FuncStmt>> {
446    use TokenKind::*;
447    let expr = parse_expr(par)?;
448    let node = match par.peek() {
449        None | Some(Newline | Semi | BraceClose) => {
450            let span = expr.span;
451            Node::new(FuncStmt::Expr { value: expr }, span)
452        }
453        Some(Colon) => {
454            par.fancy_error(
455                "Variable declaration must begin with `let`",
456                vec![Label::primary(expr.span, "invalid variable declaration")],
457                vec!["Example: `let x: u8 = 1`".into()],
458            );
459            return Err(ParseFailed);
460        }
461        Some(Eq) => {
462            par.next()?;
463            let value = parse_expr(par)?;
464            let span = expr.span + value.span;
465            // TODO: should `x = y = z` be allowed?
466            Node::new(
467                FuncStmt::Assign {
468                    target: expr,
469                    value,
470                },
471                span,
472            )
473        }
474        Some(tk) => {
475            let tok = par.next()?;
476            if let Some(op) = aug_assign_op(tk) {
477                let value = parse_expr(par)?;
478                let span = expr.span + value.span;
479                Node::new(
480                    FuncStmt::AugAssign {
481                        target: expr,
482                        op: Node::new(op, tok.span),
483                        value,
484                    },
485                    span,
486                )
487            } else {
488                par.unexpected_token_error(&tok, "invalid syntax in function body", vec![]);
489                return Err(ParseFailed);
490            }
491        }
492    };
493    par.expect_stmt_end("statement")?;
494    Ok(node)
495}
496
497fn expr_to_vardecl_target(par: &mut Parser, expr: Node<Expr>) -> ParseResult<Node<VarDeclTarget>> {
498    match expr.kind {
499        Expr::Name(name) => Ok(Node::new(VarDeclTarget::Name(name), expr.span)),
500        Expr::Tuple { elts } if !elts.is_empty() => Ok(Node::new(
501            VarDeclTarget::Tuple(
502                elts.into_iter()
503                    .map(|elt| expr_to_vardecl_target(par, elt))
504                    .collect::<ParseResult<Vec<_>>>()?,
505            ),
506            expr.span,
507        )),
508        _ => {
509            par.fancy_error(
510                "failed to parse variable declaration",
511                vec![Label::primary(
512                    expr.span,
513                    "invalid variable declaration target",
514                )],
515                vec![
516                    "The left side of a variable declaration can be either a name\nor a non-empty tuple."
517                        .into(),
518                ],
519            );
520            Err(ParseFailed)
521        }
522    }
523}
524
525/// Parse an `if` statement.
526///
527/// # Panics
528/// Panics if the next token isn't `if`.
529pub fn parse_if_stmt(par: &mut Parser) -> ParseResult<Node<FuncStmt>> {
530    let if_tok = par.assert(TokenKind::If);
531    let test = parse_expr(par)?;
532    par.enter_block(if_tok.span + test.span, "`if` statement")?;
533    let body = parse_block_stmts(par)?;
534    par.expect(TokenKind::BraceClose, "`if` statement")?;
535    par.eat_newlines();
536
537    let else_block = match par.peek() {
538        Some(TokenKind::Else) => {
539            let else_tok = par.next()?;
540            if par.peek() == Some(TokenKind::If) {
541                vec![parse_if_stmt(par)?]
542            } else {
543                par.enter_block(else_tok.span, "`if` statement `else` branch")?;
544                let else_body = parse_block_stmts(par)?;
545                par.expect(TokenKind::BraceClose, "`if` statement")?;
546                else_body
547            }
548        }
549        _ => vec![],
550    };
551
552    let span = if_tok.span + test.span + body.last() + else_block.last();
553    Ok(Node::new(
554        FuncStmt::If {
555            test,
556            body,
557            or_else: else_block,
558        },
559        span,
560    ))
561}
562
563/// Parse a `match` statement.
564///
565/// # Panics
566/// Panics if the next token isn't `match`.
567pub fn parse_match_stmt(par: &mut Parser) -> ParseResult<Node<FuncStmt>> {
568    let match_tok = par.assert(TokenKind::Match);
569    let expr = parse_expr(par)?;
570    par.enter_block(match_tok.span + expr.span, "`match` statement")?;
571    let arms = parse_match_arms(par)?;
572    let end = par.expect(TokenKind::BraceClose, "`match` statement")?;
573
574    let span = match_tok.span + end.span;
575    Ok(Node::new(FuncStmt::Match { expr, arms }, span))
576}
577
578pub fn parse_match_arms(par: &mut Parser) -> ParseResult<Vec<Node<MatchArm>>> {
579    let mut arms = vec![];
580    par.eat_newlines();
581    while par.peek_or_err()? != TokenKind::BraceClose {
582        let pat = parse_pattern(par)?;
583
584        par.expect(TokenKind::FatArrow, "`match arm`")?;
585
586        par.enter_block(pat.span, "`match` arm")?;
587        let body = parse_block_stmts(par)?;
588        let end = par.expect(TokenKind::BraceClose, "`match` arm")?;
589
590        let span = pat.span + end.span;
591        arms.push(Node::new(MatchArm { pat, body }, span));
592        par.eat_newlines();
593    }
594
595    Ok(arms)
596}
597
598pub fn parse_pattern(par: &mut Parser) -> ParseResult<Node<Pattern>> {
599    let mut left_pat = parse_pattern_atom(par)?;
600    let mut span = left_pat.span;
601    while let Some(TokenKind::Pipe) = par.peek() {
602        par.next().unwrap();
603        let right_pat = parse_pattern_atom(par)?;
604        span += right_pat.span;
605        let patterns = match left_pat.kind {
606            Pattern::Or(mut patterns) => {
607                patterns.push(right_pat);
608                patterns
609            }
610            _ => {
611                vec![left_pat, right_pat]
612            }
613        };
614        left_pat = Node::new(Pattern::Or(patterns), span);
615    }
616
617    Ok(left_pat)
618}
619
620/// Parse a `while` statement.
621///
622/// # Panics
623/// Panics if the next token isn't `while`.
624pub fn parse_while_stmt(par: &mut Parser) -> ParseResult<Node<FuncStmt>> {
625    let while_tok = par.assert(TokenKind::While);
626
627    let test = parse_expr(par)?;
628    par.enter_block(while_tok.span + test.span, "`while` statement")?;
629    let body = parse_block_stmts(par)?;
630    let end = par.expect(TokenKind::BraceClose, "`while` statement")?;
631    let span = while_tok.span + test.span + end.span;
632
633    Ok(Node::new(FuncStmt::While { test, body }, span))
634}
635
636/// Parse a `for` statement.
637///
638/// # Panics
639/// Panics if the next token isn't `for`.
640pub fn parse_for_stmt(par: &mut Parser) -> ParseResult<Node<FuncStmt>> {
641    let for_tok = par.assert(TokenKind::For);
642
643    let target = par
644        .expect(TokenKind::Name, "failed to parse `for` statement")?
645        .into();
646    par.expect(TokenKind::In, "failed to parse `for` statement")?;
647    let iter = parse_expr(par)?;
648    par.enter_block(for_tok.span + iter.span, "`for` statement")?;
649    let body = parse_block_stmts(par)?;
650    let end = par.expect(TokenKind::BraceClose, "`for` statement")?;
651    par.expect_stmt_end("`for` statement")?;
652    let span = for_tok.span + iter.span + end.span;
653
654    Ok(Node::new(FuncStmt::For { target, iter, body }, span))
655}
656
657/// Parse a `return` statement.
658///
659/// # Panics
660/// Panics if the next token isn't `return`.
661pub fn parse_return_stmt(par: &mut Parser) -> ParseResult<Node<FuncStmt>> {
662    let ret = par.assert(TokenKind::Return);
663    let value = match par.peek() {
664        None | Some(TokenKind::Newline) => None,
665        Some(_) => Some(parse_expr(par)?),
666    };
667    par.expect_stmt_end("return statement")?;
668    let span = ret.span + value.as_ref();
669    Ok(Node::new(FuncStmt::Return { value }, span))
670}
671
672/// Parse an `assert` statement.
673///
674/// # Panics
675/// Panics if the next token isn't `assert`.
676pub fn parse_assert_stmt(par: &mut Parser) -> ParseResult<Node<FuncStmt>> {
677    let assert_tok = par.assert(TokenKind::Assert);
678    let test = parse_expr(par)?;
679    let msg = match par.peek() {
680        None | Some(TokenKind::Newline) => None,
681        Some(TokenKind::Comma) => {
682            par.next()?;
683            Some(parse_expr(par)?)
684        }
685        Some(_) => {
686            let tok = par.next()?;
687            par.unexpected_token_error(&tok, "failed to parse `assert` statement", vec![]);
688            return Err(ParseFailed);
689        }
690    };
691    par.expect_stmt_end("assert statement")?;
692    let span = assert_tok.span + test.span + msg.as_ref();
693    Ok(Node::new(FuncStmt::Assert { test, msg }, span))
694}
695
696/// Parse a `revert` statement.
697///
698/// # Panics
699/// Panics if the next token isn't `revert`.
700pub fn parse_revert_stmt(par: &mut Parser) -> ParseResult<Node<FuncStmt>> {
701    let revert_tok = par.assert(TokenKind::Revert);
702    let error = match par.peek() {
703        None | Some(TokenKind::Newline) => None,
704        Some(_) => Some(parse_expr(par)?),
705    };
706    par.expect_stmt_end("revert statement")?;
707    let span = revert_tok.span + error.as_ref();
708    Ok(Node::new(FuncStmt::Revert { error }, span))
709}
710
711/// Parse an `unsafe` block.
712///
713/// # Panics
714/// Panics if the next token isn't `unsafe`.
715pub fn parse_unsafe_block(par: &mut Parser) -> ParseResult<Node<FuncStmt>> {
716    let kw_tok = par.assert(TokenKind::Unsafe);
717    par.enter_block(kw_tok.span, "`unsafe` block")?;
718    let body = parse_block_stmts(par)?;
719    let end = par.expect(TokenKind::BraceClose, "`unsafe` block")?;
720    let span = kw_tok.span + end.span;
721
722    Ok(Node::new(FuncStmt::Unsafe(body), span))
723}
724
725fn parse_pattern_atom(par: &mut Parser) -> ParseResult<Node<Pattern>> {
726    match par.peek() {
727        Some(TokenKind::ParenOpen) => return parse_tuple_pattern(par, None),
728        Some(TokenKind::True) => {
729            let span = par.next().unwrap().span;
730            let literal_pat = Node::new(LiteralPattern::Bool(true), span);
731            return Ok(Node::new(Pattern::Literal(literal_pat), span));
732        }
733        Some(TokenKind::False) => {
734            let span = par.next().unwrap().span;
735            let literal_pat = Node::new(LiteralPattern::Bool(false), span);
736            return Ok(Node::new(Pattern::Literal(literal_pat), span));
737        }
738        Some(TokenKind::DotDot) => {
739            let span = par.next().unwrap().span;
740            return Ok(Node::new(Pattern::Rest, span));
741        }
742        _ => {}
743    }
744
745    let mut pattern = parse_path_pattern_segment(par)?;
746
747    while let Some(TokenKind::ColonColon) = par.peek() {
748        par.next().unwrap();
749        let right = parse_path_pattern_segment(par)?;
750        pattern = try_merge_path_pattern(par, pattern, right)?;
751    }
752
753    if let Some(TokenKind::ParenOpen) = par.peek() {
754        match pattern.kind {
755            Pattern::Path(path) => parse_tuple_pattern(par, Some(path)),
756            Pattern::WildCard => {
757                invalid_pattern(par, "can't use wildcard with tuple pattern", pattern.span)
758            }
759            _ => unreachable!(),
760        }
761    } else if let Some(TokenKind::BraceOpen) = par.peek() {
762        match pattern.kind {
763            Pattern::Path(path) => parse_struct_pattern(par, path),
764            Pattern::WildCard => {
765                invalid_pattern(par, "can't use wildcard with struct pattern", pattern.span)
766            }
767            _ => unreachable!(),
768        }
769    } else {
770        Ok(pattern)
771    }
772}
773
774fn parse_tuple_pattern(par: &mut Parser, path: Option<Node<Path>>) -> ParseResult<Node<Pattern>> {
775    if let Some(TokenKind::ParenOpen) = par.peek() {
776        par.eat_newlines();
777        let paren_span = par.next().unwrap().span;
778
779        let (elts, last_span) = if let Some(TokenKind::ParenClose) = par.peek() {
780            (vec![], par.next().unwrap().span)
781        } else {
782            par.eat_newlines();
783            let mut elts = vec![parse_pattern(par)?];
784            while let Some(TokenKind::Comma) = par.peek() {
785                par.next().unwrap();
786                elts.push(parse_pattern(par)?);
787                par.eat_newlines();
788            }
789            let last_span = par.expect(TokenKind::ParenClose, "pattern")?.span;
790            (elts, last_span)
791        };
792
793        if let Some(path) = path {
794            let span = path.span + last_span;
795            Ok(Node::new(Pattern::PathTuple(path, elts), span))
796        } else {
797            let span = paren_span + last_span;
798            Ok(Node::new(Pattern::Tuple(elts), span))
799        }
800    } else {
801        unreachable!()
802    }
803}
804
805fn parse_struct_pattern(par: &mut Parser, path: Node<Path>) -> ParseResult<Node<Pattern>> {
806    if let Some(TokenKind::BraceOpen) = par.peek() {
807        par.eat_newlines();
808        let mut span = par.next().unwrap().span;
809
810        let mut fields = vec![];
811        let mut has_rest = false;
812        loop {
813            par.eat_newlines();
814            match par.peek_or_err()? {
815                TokenKind::Name => {
816                    let name = par.next().unwrap();
817                    let field_name = Node::new(name.text.into(), name.span);
818                    par.expect(TokenKind::Colon, "failed to parse struct pattern")?;
819                    let pat = parse_pattern(par)?;
820                    fields.push((field_name, pat));
821                    if par.peek() == Some(TokenKind::Comma) {
822                        par.next()?;
823                    } else {
824                        span += par
825                            .expect(TokenKind::BraceClose, "failed to parse struct pattern")?
826                            .span;
827                        break;
828                    }
829                }
830
831                TokenKind::DotDot => {
832                    par.next().unwrap();
833                    has_rest = true;
834                    par.eat_newlines();
835                    span += par
836                        .expect(
837                            TokenKind::BraceClose,
838                            "`..` pattern should be the last position in the struct pattern",
839                        )?
840                        .span;
841                    break;
842                }
843
844                TokenKind::BraceClose => {
845                    span += par.next().unwrap().span;
846                    break;
847                }
848
849                _ => {
850                    let tok = par.next()?;
851                    par.unexpected_token_error(&tok, "failed to parse struct pattern", vec![]);
852                    return Err(ParseFailed);
853                }
854            }
855        }
856
857        Ok(Node::new(
858            Pattern::PathStruct {
859                path,
860                fields,
861                has_rest,
862            },
863            span,
864        ))
865    } else {
866        unreachable!()
867    }
868}
869
870fn try_merge_path_pattern(
871    par: &mut Parser,
872    left: Node<Pattern>,
873    right: Node<Pattern>,
874) -> ParseResult<Node<Pattern>> {
875    let span = left.span + right.span;
876
877    match (left.kind, right.kind) {
878        (Pattern::Path(mut left_path), Pattern::Path(right_path)) => {
879            left_path
880                .kind
881                .segments
882                .extend_from_slice(&right_path.kind.segments);
883            left_path.span = span;
884            let span = left.span + right.span;
885            Ok(Node::new(Pattern::Path(left_path), span))
886        }
887        _ => invalid_pattern(par, "invalid pattern here", span),
888    }
889}
890
891fn parse_path_pattern_segment(par: &mut Parser) -> ParseResult<Node<Pattern>> {
892    let tok = par.expect(TokenKind::Name, "failed to parse pattern")?;
893    let text = tok.text;
894    if text == "_" {
895        Ok(Node::new(Pattern::WildCard, tok.span))
896    } else {
897        let path = Path {
898            segments: vec![Node::new(text.into(), tok.span)],
899        };
900        Ok(Node::new(
901            Pattern::Path(Node::new(path, tok.span)),
902            tok.span,
903        ))
904    }
905}
906
907fn invalid_pattern(par: &mut Parser, message: &str, span: Span) -> ParseResult<Node<Pattern>> {
908    par.fancy_error(
909        "invalid pattern",
910        vec![Label::primary(span, message)],
911        vec![],
912    );
913    Err(ParseFailed)
914}