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.
Alexis Sellier committed ago 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 +
}