Skip to content

Improve array pattern spread error message #7549

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jun 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
- Improve doc comment formatting to match the style of multiline comments. https://github.com/rescript-lang/rescript/pull/7529
- Improve error messages around type mismatches for try/catch, if, for, while, and optional record fields + optional function arguments. https://github.com/rescript-lang/rescript/pull/7522
- sync Reanalyze with the new APIs around exception. https://github.com/rescript-lang/rescript/pull/7536
- Improve array pattern spread error message. https://github.com/rescript-lang/rescript/pull/7549

#### :house: Internal

Expand Down
17 changes: 9 additions & 8 deletions compiler/syntax/src/res_core.ml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ module ErrorMessages = struct
matching currently guarantees to never create new intermediate data."

let record_pattern_spread =
"Record's `...` spread is not supported in pattern matches.\n\
"Record spread (`...`) is not supported in pattern matches.\n\
Explanation: you can't collect a subset of a record's field into its own \
record, since a record needs an explicit declaration and that subset \
wouldn't have one.\n\
Expand All @@ -70,13 +70,14 @@ module ErrorMessages = struct
[@@live]

let array_pattern_spread =
"Array's `...` spread is not supported in pattern matches.\n\
Explanation: such spread would create a subarray; out of performance \
concern, our pattern matching currently guarantees to never create new \
intermediate data.\n\
Solution: if it's to validate the first few elements, use a `when` clause \
+ Array size check + `get` checks on the current pattern. If it's to \
obtain a subarray, use `Array.sub` or `Belt.Array.slice`."
"Array spread (`...`) is not supported in pattern matches.\n\n\
Explanation: Allowing `...` here would require creating a new subarray at \
match time, but for performance reasons pattern matching is guaranteed to \
never create intermediate data.\n\n\
Possible solutions:\n\
- To validate specific elements: Use `if` with length checks and \
`Array.get`\n\
- To extract a subarray: Use `Array.slice`"

let record_expr_spread =
"Records can only have one `...` spread, at the beginning.\n\
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,13 @@
2 │
3 │ let record = {...x, ...y}

Array's `...` spread is not supported in pattern matches.
Explanation: such spread would create a subarray; out of performance concern, our pattern matching currently guarantees to never create new intermediate data.
Solution: if it's to validate the first few elements, use a `when` clause + Array size check + `get` checks on the current pattern. If it's to obtain a subarray, use `Array.sub` or `Belt.Array.slice`.
Array spread (`...`) is not supported in pattern matches.

Explanation: Allowing `...` here would require creating a new subarray at match time, but for performance reasons pattern matching is guaranteed to never create intermediate data.

Possible solutions:
- To validate specific elements: Use `if` with length checks and `Array.get`
- To extract a subarray: Use `Array.slice`


Syntax error!
Expand All @@ -33,7 +37,7 @@ Explanation: since records have a known, fixed shape, a spread like `{a, ...b}`
5 │
6 │ let list{...x, ...y} = myList

Record's `...` spread is not supported in pattern matches.
Record spread (`...`) is not supported in pattern matches.
Explanation: you can't collect a subset of a record's field into its own record, since a record needs an explicit declaration and that subset wouldn't have one.
Solution: you need to pull out each field you want explicitly.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,13 @@
7 ┆ | [x, ...rest] => [x, ...loop(rest)]
8 ┆ | [] => []

Array's `...` spread is not supported in pattern matches.
Explanation: such spread would create a subarray; out of performance concern, our pattern matching currently guarantees to never create new intermediate data.
Solution: if it's to validate the first few elements, use a `when` clause + Array size check + `get` checks on the current pattern. If it's to obtain a subarray, use `Array.sub` or `Belt.Array.slice`.
Array spread (`...`) is not supported in pattern matches.

Explanation: Allowing `...` here would require creating a new subarray at match time, but for performance reasons pattern matching is guaranteed to never create intermediate data.

Possible solutions:
- To validate specific elements: Use `if` with length checks and `Array.get`
- To extract a subarray: Use `Array.slice`


Syntax error!
Expand All @@ -22,9 +26,13 @@ Solution: if it's to validate the first few elements, use a `when` clause + Arra
8 ┆ | [] => []
9 ┆ }

Array's `...` spread is not supported in pattern matches.
Explanation: such spread would create a subarray; out of performance concern, our pattern matching currently guarantees to never create new intermediate data.
Solution: if it's to validate the first few elements, use a `when` clause + Array size check + `get` checks on the current pattern. If it's to obtain a subarray, use `Array.sub` or `Belt.Array.slice`.
Array spread (`...`) is not supported in pattern matches.

Explanation: Allowing `...` here would require creating a new subarray at match time, but for performance reasons pattern matching is guaranteed to never create intermediate data.

Possible solutions:
- To validate specific elements: Use `if` with length checks and `Array.get`
- To extract a subarray: Use `Array.slice`

let flags =
((if reasonFormat
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
4 │ | {a, _, b} => ()
5 │ }

Record's `...` spread is not supported in pattern matches.
Record spread (`...`) is not supported in pattern matches.
Explanation: you can't collect a subset of a record's field into its own record, since a record needs an explicit declaration and that subset wouldn't have one.
Solution: you need to pull out each field you want explicitly.

Expand Down
Loading