diff --git a/CHANGELOG.md b/CHANGELOG.md index 2bf2d32700..24dd156b27 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/compiler/syntax/src/res_core.ml b/compiler/syntax/src/res_core.ml index aebd7bc62d..ef4782192d 100644 --- a/compiler/syntax/src/res_core.ml +++ b/compiler/syntax/src/res_core.ml @@ -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\ @@ -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\ diff --git a/tests/syntax_tests/data/parsing/errors/other/expected/spread.res.txt b/tests/syntax_tests/data/parsing/errors/other/expected/spread.res.txt index d857ed03ee..adcec38799 100644 --- a/tests/syntax_tests/data/parsing/errors/other/expected/spread.res.txt +++ b/tests/syntax_tests/data/parsing/errors/other/expected/spread.res.txt @@ -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! @@ -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. diff --git a/tests/syntax_tests/data/parsing/recovery/expression/expected/list.res.txt b/tests/syntax_tests/data/parsing/recovery/expression/expected/list.res.txt index 305426345c..3b8e3ad587 100644 --- a/tests/syntax_tests/data/parsing/recovery/expression/expected/list.res.txt +++ b/tests/syntax_tests/data/parsing/recovery/expression/expected/list.res.txt @@ -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! @@ -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 diff --git a/tests/syntax_tests/data/parsing/recovery/pattern/expected/record.res.txt b/tests/syntax_tests/data/parsing/recovery/pattern/expected/record.res.txt index 3446836046..68b19a3825 100644 --- a/tests/syntax_tests/data/parsing/recovery/pattern/expected/record.res.txt +++ b/tests/syntax_tests/data/parsing/recovery/pattern/expected/record.res.txt @@ -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.