roc icon indicating copy to clipboard operation
roc copied to clipboard

Pattern matching panic

Open stuarth opened this issue 1 year ago • 2 comments

app "xyz"
    packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.8.1/x8URkvfyi9I0QhmVG98roKBUs_AZRkLFwFJVJ3942YA.tar.br" }
    imports [
        pf.Stdout,
    ]
    provides [main] to pf

match = \pattern ->
    when pattern is
        [_, '*'] -> Bool.true
        [_c, .. as remainingPattern] if Bool.true -> match remainingPattern
        _ -> Bool.false

main =
    dbg match ['a']

    Stdout.line "hello world"

produces

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
thread 'main' panicked at 'Expected symbol `17.IdentId(3)` to be in environment', crates/compiler/mono/src/inc_dec.rs:293:21
stack backtrace:
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

stuarth avatar Mar 23 '24 20:03 stuarth

I just ran into this too. Here's another example:

app "experiment"
    packages {
        pf: "https://github.com/roc-lang/basic-cli/releases/download/0.8.1/x8URkvfyi9I0QhmVG98roKBUs_AZRkLFwFJVJ3942YA.tar.br",
    }
    imports [pf.Task.{ Task }]
    provides [main] to pf

main : Task {} I32
main =
    {} =
        when [] is
            [.. as rest] if Bool.false -> foo rest
            [] -> {}

    Task.ok {}

foo = \_ -> {}

Error is when running the roc run command:

$ roc run package/main.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
thread 'main' panicked at 'Expected symbol `17.IdentId(2)` to be in environment', crates/compiler/mono/src/inc_dec.rs:293:21
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

The example is as small as I can make it.

  • It needs to have the .. as rest pattern. Substituting it with simply rest makes the error go away.
  • The branch needs to have a conditional.
  • The branch with the conditional needs to pass the rest value to another function
  • There needs to be another list pattern, simplest one is []. Using _ does not result in the error.
  • The pattern above isn't exhaustive, but fixing that by adding an extra branch doesn't make the error go away.
  • The whole pattern match doesn't actually need to run. Even if lifted into a lambda that doesn't get called, like below, the error occurs:
main : Task {} I32
main =
    _ =
        \_ ->
            when [] is
                [.. as rest] if Bool.false -> foo rest
                [] -> {}

    Task.ok {}

foo = \_ -> {}

jwoudenberg avatar Mar 24 '24 15:03 jwoudenberg

Thanks for the further investigation @jwoudenberg!

For the person that tries to resolve this; note that the first example by @stuarth passes roc check whereas the second one by @jwoudenberg does not.

Anton-4 avatar Mar 25 '24 13:03 Anton-4