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
11pub 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
104pub 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 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
123pub 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
150pub 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 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 _ => {
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 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
288fn 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
322pub 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
337pub fn parse_stmt(par: &mut Parser) -> ParseResult<Node<FuncStmt>> {
339 use TokenKind::*;
340
341 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
443fn 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 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
525pub 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
563pub 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
620pub 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
636pub 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
657pub 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
672pub 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
696pub 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
711pub 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}