Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Depends on #1819.
This PR finally brings the work done around patterns and ADTs together by making match expressions accept arbitrary patterns on the left hand side of the
=>
sign. This results in both full pattern matching, and the ability to deconstruct ADTs in a type-safe way.Beside some administrative changes (changing the parsing rule of
match
, switching to the pattern compilation instead of the current ad-hoc evaluation of match expressions for enum tags, etc.), the bulk of the new work of this PR is the typechecking of general patterns.Typechecking
For simplicity, I reproduce here what I wrote as a comment inside the typechecker:
In consequence, the current approach to typecheck a pattern is:
typecheck::pattern
, thepattern_types
function which elaborates the type of a pattern as well as its variables always elaborates open-ended enum rows when it encounters an enum pattern. It saves the open tail in a vector, together with a pattern path, which localizes the enum pattern inside the wider patternmatch { 'Foo => .., 'Bar => .., _ => } : forall rows. [| 'Foo, 'Bar; rows |]
. The other paths are currently not leveraged, but we can imagine in the near future having wildcard patterns, in which case we would also let open the tails corresponding to each path where there is a wildcard pattern: typically, we would havematch { {foo = 'Foo} => ..., {foo = 'Bar} => ..., {foo = _} => ...} : forall rows . { foo : [| 'Foo, 'Bar; rows |] }
Content
Besides the typechecking implementation, the rest is mostly obvious consequences of generalizing match expressions, as well as bug fixing in pattern compilations and pattern type checking discovered by adding more comprehensive tests.
Follow-up (ADTs + patterns)
'Foo
to be matched by'Foo x
or not, adding%unit%: %Unit%
.