Skip to main content

cl_parser/parser/
expr.rs

1//! Conlang's [Expression](Expr) parser.
2
3use super::{PResult, PResultExt, Parse, ParseError, Parser, no_eof, pat::Prec as PPrec};
4use cl_ast::{types::Literal, *};
5use cl_token::{TKind, Token};
6
7/// Organizes the precedence hierarchy for syntactic elements
8#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
9pub enum Prec {
10    Min,
11    /// The Semicolon Operator gets its own precedence level
12    Do,
13    /// The body of a function, conditional, etc.
14    Body,
15    /// An assignment
16    Assign,
17    /// Constructor for a struct
18    Make,
19    /// Constructor for a tuple
20    Tuple,
21    /// The conditional of an `if` or `while` (which is really an `if`)
22    Logical,
23    /// The short-circuiting "boolean or" operator
24    LogOr,
25    /// The short-circuiting "boolean and" operator
26    LogAnd,
27    /// Value comparison operators
28    Compare,
29    /// Constructor for a Range
30    Range,
31    /// Binary/bitwise operators
32    Binary,
33    /// Bit-shifting operators
34    Shift,
35    /// Addition and Subtraction operators
36    Factor,
37    /// Multiplication, Division, and Remainder operators
38    Term,
39    /// Negation, Reference, Try
40    Unary,
41    /// Place-projection operators (`*x`, `x[1]`, `x.a`, `x.1`)
42    Project,
43    /// Call subscripting
44    Extend,
45    Max,
46}
47
48impl Prec {
49    pub const MIN: usize = Prec::Min.value();
50
51    pub const fn value(self) -> usize {
52        self as usize * 2
53    }
54
55    pub const fn prev(self) -> usize {
56        match self {
57            Self::Assign => self.value() + 1,
58            _ => self.value(),
59        }
60    }
61
62    pub const fn next(self) -> usize {
63        match self {
64            Self::Assign => self.value(),
65            _ => self.value() + 1,
66        }
67    }
68}
69
70/// `PseudoOperator`: fake operators used to give certain tokens special behavior.
71#[derive(Clone, Copy, Debug, PartialEq, Eq)]
72pub enum Ps {
73    Id,         // Identifier
74    Mid,        // MetaIdentifier
75    Lit,        // Literal
76    Use,        // use Use
77    Def,        // any definition (let, struct, enum, fn, ...)
78    DocInner,   // Documentation Comment `//!`
79    DocOuter,   // Documentation Comment `///`
80    For,        // for Pat in Expr Expr else Expr
81    Lambda0,    // || Expr
82    Lambda,     // | Pat,* | Expr
83    DoubleRef,  // && Expr
84    Make,       // Expr{ Expr,* }
85    Match,      // match Expr { (Pat => Expr),* }
86    ImplicitDo, // An implicit semicolon
87    Ellipsis,   // An ellipsis (...)
88    End,        // Produces an empty value.
89    Op(Op),     // A normal [ast::Op]
90}
91
92/// Tries to map the incoming [Token] to a prefix [expression operator](Op)
93/// and its [precedence level](Prec)
94fn from_prefix(token: &Token) -> PResult<(Ps, Prec)> {
95    Ok(match token.kind {
96        TKind::InDoc => (Ps::DocInner, Prec::Min),
97        TKind::OutDoc => (Ps::DocOuter, Prec::Max),
98        TKind::Do => (Ps::Op(Op::Do), Prec::Do),
99        TKind::Semi => (Ps::End, Prec::Body),
100
101        TKind::Identifier | TKind::ColonColon => (Ps::Id, Prec::Max),
102        TKind::Dollar => (Ps::Mid, Prec::Max),
103        TKind::True | TKind::False | TKind::Character | TKind::Integer | TKind::String => {
104            (Ps::Lit, Prec::Max)
105        }
106        TKind::Use => (Ps::Use, Prec::Max),
107
108        TKind::Pub => (Ps::Op(Op::Pub), Prec::Max),
109        TKind::Const => (Ps::Op(Op::Const), Prec::Max),
110        TKind::Static => (Ps::Op(Op::Static), Prec::Max),
111        TKind::For => (Ps::For, Prec::Max),
112        TKind::Match => (Ps::Match, Prec::Max),
113        TKind::Macro => (Ps::Op(Op::Macro), Prec::Assign),
114
115        TKind::Fn
116        | TKind::Mod
117        | TKind::Impl
118        | TKind::Let
119        | TKind::Type
120        | TKind::Struct
121        | TKind::Enum => (Ps::Def, Prec::Max),
122
123        TKind::Loop => (Ps::Op(Op::Loop), Prec::Body),
124        TKind::If => (Ps::Op(Op::If), Prec::Body),
125        TKind::While => (Ps::Op(Op::While), Prec::Body),
126        TKind::Defer => (Ps::Op(Op::Defer), Prec::Body),
127        TKind::Break => (Ps::Op(Op::Break), Prec::Body),
128        TKind::Return => (Ps::Op(Op::Return), Prec::Body),
129        TKind::Continue => (Ps::Op(Op::Continue), Prec::Max),
130
131        TKind::LCurly => (Ps::Op(Op::Block), Prec::Min),
132        TKind::RCurly => (Ps::End, Prec::Do),
133        TKind::LBrack => (Ps::Op(Op::Array), Prec::Tuple),
134        TKind::RBrack => (Ps::End, Prec::Tuple),
135        TKind::LParen => (Ps::Op(Op::Group), Prec::Min),
136        TKind::RParen => (Ps::End, Prec::Tuple),
137        TKind::Amp => (Ps::Op(Op::Refer), Prec::Unary),
138        TKind::AmpAmp => (Ps::DoubleRef, Prec::Unary),
139        TKind::Bang => (Ps::Op(Op::Not), Prec::Unary),
140        TKind::BangBang => (Ps::Op(Op::Identity), Prec::Unary),
141        TKind::Bar => (Ps::Lambda, Prec::Body),
142        TKind::BarBar => (Ps::Lambda0, Prec::Body),
143        TKind::DotDot => (Ps::Op(Op::RangeEx), Prec::Range),
144        TKind::DotDotDot => (Ps::Ellipsis, Prec::Max),
145        TKind::DotDotEq => (Ps::Op(Op::RangeIn), Prec::Range),
146        TKind::Minus => (Ps::Op(Op::Neg), Prec::Unary),
147        TKind::Plus => (Ps::Op(Op::Identity), Prec::Unary),
148        TKind::Star => (Ps::Op(Op::Deref), Prec::Unary),
149        TKind::Hash => (Ps::Op(Op::MetaOuter), Prec::Max),
150        TKind::HashBang => (Ps::Op(Op::MetaInner), Prec::Max),
151
152        kind => Err(ParseError::NotPrefix(kind, token.span))?,
153    })
154}
155
156/// Tries to map the incoming [Token] to an infix [expression operator](Op)
157/// and its [precedence level](Prec)
158const fn from_infix(token: &Token) -> PResult<(Ps, Prec)> {
159    Ok(match token.kind {
160        TKind::Semi => (Ps::Op(Op::Do), Prec::Do), // the inspiration
161        TKind::In => (Ps::Op(Op::Do), Prec::Do),
162
163        TKind::Eq => (Ps::Op(Op::Set), Prec::Assign),
164        TKind::StarEq => (Ps::Op(Op::MulSet), Prec::Assign),
165        TKind::SlashEq => (Ps::Op(Op::DivSet), Prec::Assign),
166        TKind::RemEq => (Ps::Op(Op::RemSet), Prec::Assign),
167        TKind::PlusEq => (Ps::Op(Op::AddSet), Prec::Assign),
168        TKind::MinusEq => (Ps::Op(Op::SubSet), Prec::Assign),
169        TKind::LtLtEq => (Ps::Op(Op::ShlSet), Prec::Assign),
170        TKind::GtGtEq => (Ps::Op(Op::ShrSet), Prec::Assign),
171        TKind::AmpEq => (Ps::Op(Op::AndSet), Prec::Assign),
172        TKind::XorEq => (Ps::Op(Op::XorSet), Prec::Assign),
173        TKind::BarEq => (Ps::Op(Op::OrSet), Prec::Assign),
174        TKind::Comma => (Ps::Op(Op::Tuple), Prec::Tuple),
175        TKind::LCurly => (Ps::Make, Prec::Make),
176        TKind::XorXor => (Ps::Op(Op::LogXor), Prec::Logical),
177        TKind::BarBar => (Ps::Op(Op::LogOr), Prec::LogOr),
178        TKind::AmpAmp => (Ps::Op(Op::LogAnd), Prec::LogAnd),
179        TKind::Lt => (Ps::Op(Op::Lt), Prec::Compare),
180        TKind::LtEq => (Ps::Op(Op::Leq), Prec::Compare),
181        TKind::EqEq => (Ps::Op(Op::Eq), Prec::Compare),
182        TKind::BangEq => (Ps::Op(Op::Neq), Prec::Compare),
183        TKind::GtEq => (Ps::Op(Op::Geq), Prec::Compare),
184        TKind::Gt => (Ps::Op(Op::Gt), Prec::Compare),
185        TKind::DotDot => (Ps::Op(Op::RangeEx), Prec::Range),
186        TKind::DotDotEq => (Ps::Op(Op::RangeIn), Prec::Range),
187        TKind::Amp => (Ps::Op(Op::And), Prec::Binary),
188        TKind::Xor => (Ps::Op(Op::Xor), Prec::Binary),
189        TKind::Bar => (Ps::Op(Op::Or), Prec::Binary),
190        TKind::LtLt => (Ps::Op(Op::Shl), Prec::Shift),
191        TKind::GtGt => (Ps::Op(Op::Shr), Prec::Shift),
192        TKind::Plus => (Ps::Op(Op::Add), Prec::Factor),
193        TKind::Minus => (Ps::Op(Op::Sub), Prec::Factor),
194        TKind::Star => (Ps::Op(Op::Mul), Prec::Term),
195        TKind::Slash => (Ps::Op(Op::Div), Prec::Term),
196        TKind::Rem => (Ps::Op(Op::Rem), Prec::Term),
197
198        TKind::Question => (Ps::Op(Op::Try), Prec::Unary),
199        TKind::Dot => (Ps::Op(Op::Dot), Prec::Project),
200        TKind::LBrack => (Ps::Op(Op::Index), Prec::Project),
201        TKind::LParen => (Ps::Op(Op::Call), Prec::Extend),
202
203        TKind::RParen | TKind::RBrack | TKind::RCurly => (Ps::End, Prec::Max),
204        TKind::As => (Ps::Op(Op::As), Prec::Unary),
205        _ => (Ps::ImplicitDo, Prec::Do),
206    })
207}
208
209impl<'t> Parse<'t> for Expr {
210    type Prec = usize;
211
212    /// Parses an [Expr]ession.
213    ///
214    /// The `level` parameter indicates the operator binding level of the expression.
215    fn parse(p: &mut Parser<'t>, level: usize) -> PResult<Self> {
216        const MIN: usize = Prec::MIN;
217
218        // Prefix
219        let tok @ &Token { kind, span, .. } = p.peek()?;
220        let (op, prec) = from_prefix(tok)?;
221        no_eof(move || {
222            let mut head = match op {
223                // "End" is produced when an "empty" expression is syntactically required.
224                // This happens when a semi or closing delimiter begins an expression.
225                // The token which emitted "End" cannot be consumed, as it is expected
226                // elsewhere.
227                Ps::End if level <= prec.next() => Expr::Omitted,
228                Ps::End => Err(ParseError::NotPrefix(kind, span))?,
229
230                Ps::Id => Expr::Id(p.parse(())?),
231                Ps::Mid => Expr::MetId(p.consume().next()?.lexeme.to_string().as_str().into()),
232                Ps::Lit => Expr::Lit(p.parse(())?),
233                Ps::Use => Expr::Use(p.consume().parse(())?),
234                Ps::Def => Expr::Bind(p.parse(())?),
235                Ps::For => parse_for(p, ())?,
236                Ps::Match => Expr::Match(p.parse(())?),
237                Ps::Lambda | Ps::Lambda0 => {
238                    p.consume();
239
240                    let args = if kind == TKind::Bar {
241                        p.opt(PPrec::Tuple, TKind::Bar)?
242                            .map(|At(pat, span): At<Pat>| pat.to_tuple(span).at(span))
243                            .unwrap_or(At(Pat::Op(PatOp::Tuple, vec![]), span.merge(p.span())))
244                    } else {
245                        Pat::Op(PatOp::Tuple, vec![]).at(span)
246                    };
247
248                    let rety = p
249                        .opt_if(PPrec::Max, TKind::Arrow)?
250                        .unwrap_or(Pat::Ignore.at(p.span()));
251
252                    Expr::Bind(Box::new(Bind(
253                        BindOp::Fn,
254                        vec![],
255                        Pat::Op(PatOp::Fn, vec![args, rety]).at(span.merge(p.span())),
256                        vec![p.parse(prec.next())?],
257                    )))
258                }
259                Ps::DocOuter | Ps::DocInner => {
260                    let comment = Literal::Str(p.take_lexeme()?.string().unwrap());
261                    let comment = Expr::Lit(comment).at(span);
262                    // TODO: collapse consecutive doc comments into one
263                    let next = match p.peek().allow_eof()? {
264                        Some(_) => p.parse(prec.next())?,
265                        None => Expr::Omitted.at(span),
266                    };
267                    Expr::Op(
268                        match op {
269                            Ps::DocOuter => Op::MetaOuter,
270                            _ => Op::MetaInner,
271                        },
272                        vec![comment, next],
273                    )
274                }
275                Ps::Ellipsis => p.consume().then(Expr::Omitted),
276
277                // Warning: the guard of this pattern modifies the parser.
278                Ps::Op(Op::MetaOuter | Op::MetaInner)
279                    if p.consume().expect(TKind::LBrack).is_err() =>
280                {
281                    return p.parse(level);
282                }
283                Ps::Op(op @ (Op::MetaOuter | Op::MetaInner)) => Expr::Op(
284                    op,
285                    vec![
286                        p.opt(MIN, TKind::RBrack)?
287                            .unwrap_or_else(|| Expr::Omitted.at(span)),
288                        p.parse(prec.next())?,
289                    ],
290                ),
291                Ps::Op(Op::Block) => Expr::Op(
292                    Op::Block,
293                    p.consume().opt(MIN, kind.flip())?.into_iter().collect(),
294                ),
295                Ps::Op(Op::Array) => parse_array(p)?,
296                Ps::Op(Op::Group) => match p.consume().opt(MIN, kind.flip())? {
297                    Some(value) => Expr::Op(Op::Group, vec![value]),
298                    None => Expr::Op(Op::Tuple, vec![]),
299                },
300                Ps::Op(Op::Continue) => p.consume().then(Expr::Op(Op::Continue, vec![])),
301                Ps::Op(op @ (Op::If | Op::While)) => {
302                    p.consume();
303                    let exprs = vec![
304                        // conditional restricted to Logical operators or above
305                        p.parse(Prec::Logical.value())?,
306                        p.parse(prec.next())?,
307                        match p.peek() {
308                            Ok(Token { kind: TKind::Else, .. }) => {
309                                p.consume().parse(prec.next())?
310                            }
311                            _ => Expr::Omitted.at(span.merge(p.span())),
312                        },
313                    ];
314                    Expr::Op(op, exprs)
315                }
316                Ps::DoubleRef => p.consume().parse(prec.next()).map(|At(expr, span)| {
317                    Expr::Op(
318                        Op::Refer,
319                        vec![At(Expr::Op(Op::Refer, vec![At(expr, span)]), span)],
320                    )
321                })?,
322
323                Ps::Op(op) => Expr::Op(op, vec![p.consume().parse(prec.next())?]),
324                _ => unimplemented!("prefix {op:?}"),
325            };
326
327            // Infix and Postfix
328            while let Ok(Some(tok @ &Token { kind, .. })) = p.peek().allow_eof()
329                && let Ok((op, prec)) = from_infix(tok)
330                && level <= prec.prev()
331                && op != Ps::End
332            {
333                let span = span.merge(p.span());
334
335                head = match op {
336                    // Make (structor expressions) are context-sensitive
337                    Ps::Make => match &head {
338                        Expr::Id(_) | Expr::MetId(_) => Expr::Make(Box::new(Make(
339                            head.at(span),
340                            p.consume().list(vec![], (), TKind::Comma, TKind::RCurly)?,
341                        ))),
342                        _ => break,
343                    },
344                    // As is ImplicitDo (semicolon elision)
345                    Ps::ImplicitDo if p.elide_do => head.and_do(span, p.parse(prec.next())?),
346                    Ps::ImplicitDo => break,
347                    // Allow `;` at end of file
348                    Ps::Op(Op::Do) => head.and_do(
349                        span,
350                        match p.consume().peek().allow_eof()? {
351                            Some(_) => p.parse(prec.next())?,
352                            None => At(Expr::Omitted, p.span()),
353                        },
354                    ),
355                    Ps::Op(Op::Index) => Expr::Op(
356                        Op::Index,
357                        p.consume()
358                            .list(vec![head.at(span)], 0, TKind::Comma, TKind::RBrack)?,
359                    ),
360                    Ps::Op(Op::Call) => {
361                        let head = head.at(span);
362                        let args = match p.consume().opt::<At<Expr>>(0, TKind::RParen)? {
363                            None => Expr::Op(Op::Tuple, vec![]).at(span),
364                            Some(At(expr, span)) => expr.to_tuple(span).at(span),
365                        };
366                        Expr::Op(Op::Call, vec![head, args])
367                    }
368                    Ps::Op(op @ Op::Tuple) => Expr::Op(
369                        op,
370                        p.consume()
371                            .list_bare(vec![head.at(span)], prec.next(), kind)?,
372                    ) // then remove `...`s
373                    .deomit(),
374                    Ps::Op(op @ Op::Try) => {
375                        p.consume();
376                        Expr::Op(op, vec![head.at(span)])
377                    }
378                    Ps::Op(op) => {
379                        Expr::Op(op, vec![head.at(span), p.consume().parse(prec.next())?])
380                    }
381                    _ => Err(ParseError::NotInfix(kind, span))?,
382                }
383            }
384
385            Ok(head)
386        })
387    }
388}
389
390/// Parses an array with 0 or more elements, or an array-repetition
391fn parse_array(p: &mut Parser<'_>) -> PResult<Expr> {
392    if p.consume().peek()?.kind == TKind::RBrack {
393        p.consume();
394        return Ok(Expr::Op(Op::Array, vec![]));
395    }
396
397    let prec = Prec::Tuple;
398    let item = p.parse(prec.value())?;
399    let repeat = p.opt_if(prec.next(), TKind::Semi)?;
400    p.expect(TKind::RBrack)?;
401
402    Ok(match (repeat, item) {
403        (Some(repeat), item) => Expr::Op(Op::ArRep, vec![item, repeat]),
404        (None, At(Expr::Op(Op::Tuple, items), _)) => Expr::Op(Op::Array, items),
405        (None, item) => Expr::Op(Op::Array, vec![item]),
406    })
407}
408
409/// Parses a `match` expression
410///
411/// ```ignore
412/// match scrutinee {
413///     (Pat => Expr);*
414/// }
415/// ```
416impl<'t> Parse<'t> for Match {
417    type Prec = ();
418
419    fn parse(p: &mut Parser<'t>, _level: Self::Prec) -> PResult<Self>
420    where Self: Sized {
421        Ok(Self(
422            p.consume().parse(Prec::Tuple.value())?,
423            p.expect(TKind::LCurly)?
424                .list(vec![], (), TKind::Semi, TKind::RCurly)?,
425        ))
426    }
427}
428
429impl<'t> Parse<'t> for MatchArm {
430    type Prec = ();
431
432    fn parse(p: &mut Parser<'t>, _level: Self::Prec) -> PResult<Self>
433    where Self: Sized {
434        // <T,*>
435        // let generics = match p.next_if(TKind::Lt)? {
436        //     Ok(_) => p.list(vec![], (), TKind::Comma, TKind::Gt)?,
437        //     Err(_) => vec![],
438        // };
439
440        // Pat
441        let pat = p.parse(PPrec::Min)?;
442        p.expect(TKind::FatArrow)?;
443        let body = p.parse(Prec::Body.value())?;
444
445        Ok(Self(pat, body))
446    }
447}
448
449/// Parses a `for` loop expression
450fn parse_for(p: &mut Parser<'_>, _level: ()) -> PResult<Expr> {
451    // for Pat
452    let pat = p.consume().parse(PPrec::Tuple)?;
453    // in Expr
454    let iter: At<Expr> = p.expect(TKind::In)?.parse(Prec::Logical.next())?;
455    // Expr
456    let pass: At<Expr> = p.parse(Prec::Body.next())?;
457    let pspan = pass.1;
458    // else Expr?
459    let fail = match p.next_if(TKind::Else).allow_eof()? {
460        Some(Ok(_)) => p.parse(Prec::Body.next())?,
461        _ => Expr::Omitted.at(pspan),
462    };
463    /*
464    TODO: desugar for into loop-match:
465    for `pat in `iter `pass else `fail
466    ==>
467    match (`iter).into_iter() {
468        #iter => loop match #iter.next() {
469            None => break `fail,
470            Some(`pat) => `pass,
471        },
472    }
473    */
474
475    Ok(Expr::Bind(Box::new(Bind(
476        BindOp::For,
477        vec![],
478        pat,
479        vec![iter, pass, fail],
480    ))))
481}
482
483/// Returns the [BindOp], [pattern precedence](PPrec), [arrow TKind](TKind), [body precedence](Prec),
484/// and [else precedence](Prec), (if applicable,) which controls the parsing of Bind expressions.
485#[rustfmt::skip]
486#[allow(clippy::type_complexity)]
487fn from_bind(p: &mut Parser<'_>) -> PResult<(BindOp, PPrec, Option<TKind>, Option<Prec>, Option<Prec>)> {
488    let bk = match p.peek()?.kind {
489        // Token            Operator        Pat prec      Body Token             Body prec            Else prec
490        TKind::Let =>    (BindOp::Let,    PPrec::Tuple, Some(TKind::Eq),       Some(Prec::Tuple),  Some(Prec::Body)),
491        TKind::Type =>   (BindOp::Type,   PPrec::Alt,   Some(TKind::Eq),       Some(Prec::Tuple),  None),
492        TKind::Struct => (BindOp::Struct, PPrec::Tuple, None,                  None,               None),
493        TKind::Enum =>   (BindOp::Enum,   PPrec::Tuple, None,                  None,               None),
494        TKind::Fn =>     (BindOp::Fn,     PPrec::Fn,    None,                  Some(Prec::Body),   None),
495        TKind::Mod =>    (BindOp::Mod,    PPrec::Max,   None,                  Some(Prec::Body),   None),
496        TKind::Impl =>   (BindOp::Impl,   PPrec::Fn,    None,                  Some(Prec::Body),   None),
497        other => return Err(ParseError::NotBind(other, p.span()))
498    };
499
500    p.consume();
501    Ok(bk)
502}
503
504impl<'t> Parse<'t> for Bind {
505    type Prec = ();
506
507    fn parse(p: &mut Parser<'t>, _level: Self::Prec) -> PResult<Self> {
508        // let
509        let (level, patp, arrow, bodyp, failp) = from_bind(p)?;
510
511        // <T,*>
512        let generics = match p.next_if(TKind::Lt)? {
513            Ok(_) => p.list(vec![], (), TKind::Comma, TKind::Gt)?,
514            Err(_) => vec![],
515        };
516
517        // Pat
518        let pat = p.parse(patp)?;
519
520        let Some(bodyp) = bodyp else {
521            return Ok(Self(level, generics, pat, vec![]));
522        };
523
524        // `=>` for match, `=` for `let`, `type`
525        if let Some(arrow) = arrow {
526            if p.next_if(arrow).allow_eof()?.is_none_or(|v| v.is_err()) {
527                return Ok(Self(level, generics, pat, vec![]));
528            }
529        } else {
530            // Allow prefix `=`? for the rest of them
531            p.next_if(TKind::Eq).allow_eof()?;
532        }
533
534        // `=` Expr
535        let body = p.parse(bodyp.value())?;
536
537        let Some(failp) = failp else {
538            return Ok(Self(level, generics, pat, vec![body]));
539        };
540
541        // `else` Expr
542        if p.next_if(TKind::Else)
543            .allow_eof()?
544            .is_none_or(|v| v.is_err())
545        {
546            return Ok(Self(level, generics, pat, vec![body]));
547        }
548
549        let fail = p.parse(failp.value())?;
550
551        Ok(Self(level, generics, pat, vec![body, fail]))
552    }
553}
554
555impl<'t> Parse<'t> for MakeArm {
556    type Prec = ();
557
558    fn parse(p: &mut Parser<'t>, _level: ()) -> PResult<Self> {
559        let name = p
560            .next_if(TKind::Identifier)?
561            .map_err(|tk| ParseError::Expected(TKind::Identifier, tk, p.span()))?;
562        Ok(MakeArm(
563            name.lexeme
564                .str()
565                .expect("Identifier should have String")
566                .into(),
567            p.opt_if(Prec::Tuple.next(), TKind::Colon)?,
568        ))
569    }
570}