The following code works fine:
TypeA := [
X TypeB,
Y TypeB,
Nil,
]
TypeB := TypeA
But this code fails:
TypeA := [
X TypeA,
Y TypeB,
Nil,
]
TypeB := TypeA
The only difference between them is that, in the second block, the X
and Y
tags contain _different_ inner types (TypeA
and TypeB
), and in the first block, the X
and Y
tags contain _the same_ inner type (TypeA
).
In the first case, the compiler accepts the type with no errors. In the second case, we get the following error message:
thread '<unknown>' has overflowed its stack
fatal runtime error: stack overflow
zsh: abort roc check
Expectation:
Both kinds of recursive data structures should be accepted by the compiler. The issue does not seem to be with mutual recursion in general, but rather this special case of multiple distinct inner recursive types.
Result:
Compiler crashes due to stack overflow when running roc check
.
Notes:
Compiler release:
roc_nightly-macos_apple_silicon-2025-03-22-c47a8e9cdac
I should also add that this bug basically makes it impossible to represent any kind of complex recursive tree structure in Roc, including the AST in the compiler project I’m working on. I don’t think there is a real workaround at this point.
I suppose it may be possible to emulate GADTs with phantom types in order to keep the entire recursive structure within a single unified type declaration. I might try that just to see if it’s possible. But that is extremely far from ergonomic, unfortunately.
Hi @Austin Davis,
This will be fixed in the new compiler:
Awesome, can’t wait for the new compiler release!!
Last updated: Jul 26 2025 at 12:14 UTC