Let's say we have the following code:
TypeAB x : [A, B]x
TypeCD x : TypeAB [C, D]x
TypeEF x : TypeCD [E, F]x
Combined : TypeCD (TypeAB (TypeEF []))
combined_to_int : Combined -> U8
combined_to_int = |test1|
when test1 is
A -> 1
B -> 2
C -> 3
D -> 4
E -> 5
F -> 6
_ -> crash("combined_to_int() failed")
expect
value = E
int_value = combined_to_int(E)
int_value == 5
The above actually works fine. However, simply removing the wildcard case from the when
branch inside combined_to_int
causes the compiler to fail an internal assertion. Here is the message:
---> roc test
An internal compiler expectation was broken.
This is definitely a compiler bug.
Please file an issue here: <https://github.com/roc-lang/roc/issues/new/choose>
not a tag union: Alias(`Ast.IdentId(34)`, [3395], <3396>['A' , 'A' , 'B' , 'B' , 'C' , 'D' , 'E' , 'F' , ]<Openness(3)>)
Location: crates/compiler/solve/src/solve.rs:1840:34
What I would expect is for the compiler to output a type error telling me that I haven't covered all the cases. However, I also think that's a semantic bug in itself, as the Combined
tag union is not extensible (all type variables are populated by concrete types), so it seems like a mistake to require a wildcard case when pattern matching on it.
I'll check this out, I made a minimal repro:
❯ roc check temp.roc
An internal compiler expectation was broken.
This is definitely a compiler bug.
Please file an issue here: <https://github.com/roc-lang/roc/issues/new/choose>
not a tag union: Alias(`temp.IdentId(0)`, [3172], <3173>['A' , 'B' , ]<Any(3174)>)
Location: crates/compiler/solve/src/solve.rs:1840:34
~/Downloads/temp
❯ cat temp.roc
module []
TypeAB x : [A, B]x
TypeCD x : TypeAB [C]x
Combined : TypeCD (TypeAB [])
combined_to_int : Combined -> U8
combined_to_int = |test1|
when test1 is
A -> 1
B -> 2
C -> 3
Thanks for looking into it. The minimal example might seem trivial, but I have some non-trivial use cases that would improve the quality of life for the code I'm currently writing.
We should definitely make trivial things work :)
Fix in PR#8107, it turned out these type definitions created a tag union with lots of duplicates:
['A' , 'A' , 'A' , 'B' , 'B' , 'B' , 'C' , 'C' , 'D' , 'D' , 'E' , 'F' ]
I added deduplication at the right point and all is well :tada:
That was a fun bug hunt :)
Amazing, that was fast! Thanks for taking the time to fix it!
Last updated: Jul 26 2025 at 12:14 UTC