tweag / nickel

Better configuration for less
https://nickel-lang.org/
MIT License
2.24k stars 84 forks source link

Relax enum row conflicts #1831

Closed yannham closed 4 months ago

yannham commented 4 months ago

The current design of structural ADTs is to clearly separate syntactically unapplied variants (enum tags) from enum variants with an argument, both when constructing them or when deconstructing them (pattern matching).

However, the previous handling of row conflicts would still forbid types like [| 'Foo, 'Foo Number |]. Because enum tags and variants are constructed separately, and because they can be matched on separately, this type is actually unproblematic. Thus, this commit relaxes the notion of row conflicts for enums by basically ignoring unapplied enum rows (corresponding to enum tags) within enum row types.

This makes it possible to typecheck expressions such as match { 'Foo => .., 'Foo x => ..}, which are indeed entirely fine.

On paper, it seems like we should separate row conflicts in two distinct dimension: enum tags and enum variants. However, enum variants can never cause an actual conflict: 'Foo is always compatible with another occurrence 'Foo (and indeed, we didn't bother checking for conflicts just before ADTs where introduced). We thus boldly ignore enum rows that don't have any type argument (corresponding to enum tags) when handling conflicts in this PR.