[RFC] only allow irrefutable patterns in the toplevel

This proposal brings some restrictions to address this issue
Assertion failed when destructuring list from a let binding · Issue #4632 · rescript-lang/rescript-compiler (github.com), this is a small change that should not impact users in general.

The toplevel fragile pattern makes calculating exports difficult, to avoid user surpise (assertion failure in compiler), we are going to check if the toplevel pattern match is fragile or not. If it is a fragile pattern in the toplevel, we will raise a type checking error.

For example:

let myList = list{1, 2, 3}
let list{head , ... tail} = myList // fragile pattern since myList may be empty

The old behavior is that this will crash the compiler, the new behavior will raise a type checking error instead. For irrefutable pattern, e.g, tuple, such restriction is lifted.

8 Likes

I think the example above is in ml syntax?

Here’s the ReScript equivalent for a better understanding of the syntax:

let myList = list{1, 2, 3}
let list{head, ...tail} = myList // fragile pattern since myList may be empty
2 Likes

I’m confused, why is this not a “You forgot to handle a case: list{}” warning?

This is the error (rightly so) when calling a function that returns a list at the top level:

let myList = () => list{1, 2, 3}
// You forgot to handle a possible case here, for example: []
let list{head , ... tail} = myList()

We already had this warning. The thing is that if user ignore this warning, it will crash the compiler which is unexpected behavior

Ah I see, so what would the error message look like? And would the applied function example also turn into an error instead of the “unhandled case” warning it is right now?