Parse record literals in condition call arguments
7ff309338514c2144d60eca1639f1a773d0517ef4fe7c05112e2c146133fb76f
The parser propagated `Context::Condition` into parenthesized call arguments. A named record literal used as an argument in an if condition therefore treated its opening brace as the condition body and failed with an unexpected-token error. Temporarily parse call arguments in `Context::Normal` and restore the enclosing context afterward.
1 parent
69762c5c
lib/std/lang/parser.rad
+5 -0
| 272 | 272 | ||
| 273 | 273 | /// Parse a function call expression. |
|
| 274 | 274 | fn parseCall(p: *mut Parser, callee: *ast::Node) -> *ast::Node |
|
| 275 | 275 | throws (ParseError) |
|
| 276 | 276 | { |
|
| 277 | + | // The argument list is delimited, so `{` starts a record literal rather |
|
| 278 | + | // than the body of an enclosing conditional statement. |
|
| 279 | + | let saved = p.context; |
|
| 280 | + | set p.context = Context::Normal; |
|
| 277 | 281 | let args = try parseList( |
|
| 278 | 282 | p, |
|
| 279 | 283 | scanner::TokenKind::LParen, |
|
| 280 | 284 | scanner::TokenKind::RParen, |
|
| 281 | 285 | parseExpr |
|
| 282 | 286 | ); |
|
| 287 | + | set p.context = saved; |
|
| 283 | 288 | return node(p, ast::NodeValue::Call( |
|
| 284 | 289 | ast::Call { callee, args } |
|
| 285 | 290 | )); |
|
| 286 | 291 | } |
|
| 287 | 292 |
test/tests/parser.call.record.argument.rad
added
+14 -0
| 1 | + | //! returns: 0 |
|
| 2 | + | ||
| 3 | + | record Box { value: i32 } |
|
| 4 | + | ||
| 5 | + | fn isOne(box: Box) -> bool { |
|
| 6 | + | return box.value == 1; |
|
| 7 | + | } |
|
| 8 | + | ||
| 9 | + | @default fn main() -> i32 { |
|
| 10 | + | if isOne(Box { value: 1 }) { |
|
| 11 | + | return 0; |
|
| 12 | + | } |
|
| 13 | + | return 1; |
|
| 14 | + | } |