Summary
When formatting code with an unmatched closing parenthesis after a record builder expression, the formatter silently drops the unmatched ) and any subsequent tokens without reporting an error. This can result in data loss when formatting files.
Minimal Reproduction
Expected Behavior
The formatter should report a parse error about the unmatched ) token and preserve the original source, or at minimum warn the user that tokens are being dropped.
Actual Behavior
The formatter outputs:
The ).bar() portion is silently dropped with no error or warning.
Analysis
Looking at the parse tree output:
(e-record-builder
(mapper (e-tag (raw "Foo")))
(field (field "x")
(e-int (raw "5")))
(field (field "y")
(e-int (raw "6"))))
The parser only parses up to .Foo and stops. The tokens after (CloseRound, NoSpaceDotLowerIdent, etc.) are silently ignored.
Impact
This bug can cause silent data loss when:
- Users accidentally introduce unmatched parentheses while editing
- Running
roc fmt on a file would permanently delete code
- CI/CD pipelines with format checks could pass while dropping code
Snapshot Test
A minimal reproduction is available here unmatched_close_paren_multifield.md
Summary
When formatting code with an unmatched closing parenthesis after a record builder expression, the formatter silently drops the unmatched
)and any subsequent tokens without reporting an error. This can result in data loss when formatting files.Minimal Reproduction
{x: 5, y: 6}.Foo).bar()Expected Behavior
The formatter should report a parse error about the unmatched
)token and preserve the original source, or at minimum warn the user that tokens are being dropped.Actual Behavior
The formatter outputs:
{ x: 5, y: 6 }.FooThe
).bar()portion is silently dropped with no error or warning.Analysis
Looking at the parse tree output:
The parser only parses up to
.Fooand stops. The tokens after (CloseRound,NoSpaceDotLowerIdent, etc.) are silently ignored.Impact
This bug can cause silent data loss when:
roc fmton a file would permanently delete codeSnapshot Test
A minimal reproduction is available here unmatched_close_paren_multifield.md