roc-lang / roc

A fast, friendly, functional language.
https://roc-lang.org
Universal Permissive License v1.0
4.46k stars 313 forks source link

recursive tag union: assertion failed: `!matches!(union_layout, UnionLayout :: NonRecursive(..))'` #5462

Open AjaiKN opened 1 year ago

AjaiKN commented 1 year ago
app "main"
    packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.3.2/tE4xS_zLdmmxmHwHih9kHWQ7fsXtJr7W7h3425-eZFk.tar.br" }
    imports [pf.Stdout]
    provides [main] to pf

Term : [
    Foo,
    Bar Term,
]

f : Term -> Term
f = \term ->
    when term is
        Bar (Bar _) if Bool.false -> Foo
        Bar t if Bool.false -> t
        _ -> Foo

main =
    whatever = \_ -> ""
    Stdout.line (whatever (f Foo))
$ cargo run roc build
    Finished dev [unoptimized + debuginfo] target(s) in 0.47s
     Running `/Users/ajainelson/prog/roc/roc/target/debug/roc roc build`
thread 'main' panicked at 'assertion failed: !matches!(union_layout, UnionLayout :: NonRecursive(..))', crates/compiler/alias_analysis/src/lib.rs:1583:17
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Anton-4 commented 1 year ago

Thanks for reporting this @Aurelius333, I don't think we allow recursive definitions like this:

Term : [
    Foo,
    Bar Term,
]

But the error message should be improved of course.

AjaiKN commented 1 year ago

I'm a little confused because I've been writing programs the last couple days that rely extensively on recursive tag unions, and mostly, they've worked well. It's only in this specific case (when I write a when expression structured as above with the ifs) that it hasn't worked.

It also says in roc-for-elm-programmers.md that recursive tag unions are allowed:

You can also use tags to define recursive data structures, because recursive type aliases are allowed as long as the recursion happens within a tag. For example:

LinkedList a : [Nil, Cons a (LinkedList a)]

Inferred recursive tags use the as keyword. For example, the inferred version of the above type alias would be:

[Nil, Cons a b] as b

Anton-4 commented 1 year ago

Oh you're right, I'm sorry. I'll tag @ayazhafiz for follow-up.