mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-03 16:44:33 +00:00
Parse field access after record literal
e.g. `{ x: 4 }.x` now parses. This is of limited practical use of course but I would expect this to work based on the signature of `.x`.
This commit is contained in:
parent
8ba59e035d
commit
a5cf0fc505
2 changed files with 22 additions and 1 deletions
|
@ -1240,7 +1240,23 @@ pub fn record_literal<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>> {
|
|||
move |arena, state, (loc_assigned_fields, opt_def)| match opt_def {
|
||||
None => {
|
||||
// This is a record literal, not a destructure.
|
||||
Ok((Expr::Record(loc_assigned_fields.value), state))
|
||||
let mut value = Expr::Record(loc_assigned_fields.value);
|
||||
|
||||
// there can be field access, e.g. `{ x : 4 }.x`
|
||||
let (accesses, state) =
|
||||
optional(one_or_more!(skip_first!(char('.'), lowercase_ident())))
|
||||
.parse(arena, state)?;
|
||||
|
||||
if let Some(fields) = accesses {
|
||||
for field in fields {
|
||||
// Wrap the previous answer in the new one, so we end up
|
||||
// with a nested Expr. That way, `foo.bar.baz` gets represented
|
||||
// in the AST as if it had been written (foo.bar).baz all along.
|
||||
value = Expr::Access(arena.alloc(value), field);
|
||||
}
|
||||
}
|
||||
|
||||
Ok((value, state))
|
||||
}
|
||||
Some((spaces_before_equals, equals_indent)) => {
|
||||
// This is a record destructure def.
|
||||
|
|
|
@ -830,6 +830,11 @@ mod test_infer {
|
|||
infer_eq("{ x: 5, y : 3.14 }", "{ x : Int, y : Float }");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn record_literal_accessor() {
|
||||
infer_eq("{ x: 5, y : 3.14 }.x", "Int");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn record_arg() {
|
||||
infer_eq("\\rec -> rec.x", "{ x : a }* -> a");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue