Support pattern contracts in match statement #1823
Merged
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 #1821.
Match expressions have been extended to accept the full range of patterns (that was reserved to destructuring before). Patterns allow, in particular, to annotate fields with metadata, such as contract annotations or default values. Those were, until now, simply ignored by the new match expressions.
This commit modifies the pattern compilation scheme to handle contracts and default values properly. It follows the current semantics of destructuring (which has been supporting contract in pattern). There is something to be said about default value being merged with the default priority. I'm not sure it aligns well with intuition and other PLs that
{foo | default = 1} |> match { {foo ? 2} => foo } }
currently fails with a merge conflict instead of returning1
. But at least this PR adds the required machinery. I also think it's mostly forward-compatible with a shift toward a default value that would be used only if the field isn't defined in the original record, as the latter would accept strictly more programs (it's not entirely true, as it would change the meaning of e.g.{foo | default = {}} |> match {{foo ? {bar = 1}} => _
, but honestly relying on the fact that the two default values will be merged by the pattern sounds very cursed and twisted...)