(&mut self, lhs: Expr)
| 665 | } |
| 666 | |
| 667 | fn expr_struct_call(&mut self, lhs: Expr) -> Expr { |
| 668 | assert!(self.tok.kind == TokenKind::LCurly); |
| 669 | |
| 670 | let name = self.flatten_expr_to_name(&lhs); |
| 671 | |
| 672 | // consume '{' |
| 673 | let start = self.next(); |
| 674 | |
| 675 | let mut fields = vec![]; |
| 676 | let mut rest = None; |
| 677 | |
| 678 | while self.is_not(TokenKind::RCurly) { |
| 679 | if rest.is_some() { |
| 680 | self.error("rest expression (..x) should be last".to_string()); |
| 681 | break; |
| 682 | } |
| 683 | |
| 684 | // Parse ..rest |
| 685 | if self.tok.kind == TokenKind::Dot { |
| 686 | rest = Some(self.expr_rest()); |
| 687 | continue; |
| 688 | } |
| 689 | |
| 690 | // Parse field: value |
| 691 | let field = self.parse_one_ident(); |
| 692 | let value = if self.tok.kind == TokenKind::Colon { |
| 693 | // consume ':' |
| 694 | self.next(); |
| 695 | self.parse_expr() |
| 696 | } else { |
| 697 | // shorthand syntax ie. Foo { x } |
| 698 | // create a field x => Var("x") |
| 699 | Expr::Var { |
| 700 | value: field.clone(), |
| 701 | decl: Span::dummy(), |
| 702 | generics_instantiated: Default::default(), |
| 703 | ty: Type::dummy(), |
| 704 | span: self.make_span(start), |
| 705 | } |
| 706 | }; |
| 707 | |
| 708 | fields.push(StructField { name: field, value }); |
| 709 | |
| 710 | if self.tok.kind == TokenKind::Comma { |
| 711 | self.next(); |
| 712 | } |
| 713 | } |
| 714 | |
| 715 | self.expect(TokenKind::RCurly); |
| 716 | |
| 717 | Expr::StructCall { |
| 718 | name, |
| 719 | fields, |
| 720 | rest: rest.into(), |
| 721 | ty: Type::dummy(), |
| 722 | span: self.make_span(start), |
| 723 | } |
| 724 | } |
no test coverage detected