Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compiler panic when returning [] from _ -> List List _ #7357

Open
ScallyGames opened this issue Dec 13, 2024 · 2 comments
Open

Compiler panic when returning [] from _ -> List List _ #7357

ScallyGames opened this issue Dec 13, 2024 · 2 comments
Labels
bug Something isn't working mono Relates to the Monomorphization compiler stage

Comments

@ScallyGames
Copy link

ScallyGames commented Dec 13, 2024

Returning an empty list ([]) from a function that has a signature of returning a nested empty list crashes the compiler.

Code example:

app [main] {
    pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.17.0/lZFLstMUCUvd5bjnnpYromZJXkQUrdhbva4xdBInicE.tar.br",
}

import pf.Stdout

getListOfLists : {} -> List List _
getListOfLists = \_ ->
    []

main =
    Stdout.line! ((getListOfLists {}) |> List.len |> Num.toStr)

Expected behavior:

I'd expect an empty list to be a valid value for a list of lists.

Actual behavior:

thread '<unnamed>' panicked at crates/compiler/mono/src/layout.rs:3297:69:
index out of bounds: the len is 0 but the index is 0
stack backtrace:
   0:     0x56231c7aa91b - <unknown>
   1:     0x56231ba06f70 - <unknown>
   2:     0x56231c7a6783 - <unknown>
   3:     0x56231c7aa6b4 - <unknown>
   4:     0x56231c7ac210 - <unknown>
   5:     0x56231c7abf2f - <unknown>
   6:     0x56231c7ac72e - <unknown>
   7:     0x56231c7ac632 - <unknown>
   8:     0x56231c7aae16 - <unknown>
   9:     0x56231c7ac394 - <unknown>
  10:     0x56231b8fce75 - <unknown>
  11:     0x56231b8fd0b2 - <unknown>
  12:     0x56231c2b93bf - <unknown>
  13:     0x56231c2a9141 - <unknown>
  14:     0x56231c2e4e8d - <unknown>
  15:     0x56231c2af1c5 - <unknown>
  16:     0x56231c2a9141 - <unknown>
  17:     0x56231c29e99f - <unknown>
  18:     0x56231c29fb81 - <unknown>
  19:     0x56231c28f9d3 - <unknown>
  20:     0x56231c26875c - <unknown>
  21:     0x56231c28e712 - <unknown>
  22:     0x56231c28e8f6 - <unknown>
  23:     0x56231c290999 - <unknown>
  24:     0x56231c26875c - <unknown>
  25:     0x56231c28e712 - <unknown>
  26:     0x56231c28e8f6 - <unknown>
  27:     0x56231c290999 - <unknown>
  28:     0x56231c26875c - <unknown>
  29:     0x56231c281c43 - <unknown>
  30:     0x56231c262e27 - <unknown>
  31:     0x56231c25bc6a - <unknown>
  32:     0x56231c259207 - <unknown>
  33:     0x56231c1613b1 - <unknown>
  34:     0x56231c0ea5bc - <unknown>
  35:     0x56231c0df56e - <unknown>
  36:     0x56231c0eaf45 - <unknown>
  37:     0x56231c7b1e85 - <unknown>
  38:     0x7c61412a339d - <unknown>
  39:     0x7c614132849c - <unknown>
  40:                0x0 - <unknown>

Observations:

  • Returning [[]] instead works just fine
  • The specific type of nested list doesn't seem to make a difference (Could be List List _, List List a, List List U64)
  • While in this minimal example the signature could just specifically be that of an empty list, in more complex examples a function could return either some actual nested list or just an empty list as a default case (which is how I came across this issue) and it breaks there as well. This is just an MRE.

Environment:

OS: Archlinux
Roc: roc nightly pre-release, built from commit 50ec8ef on Di 10 Dez 2024 09:02:17 UTC

@lukewilliamboswell
Copy link
Collaborator

Here is a more minimal repro.

$ cargo run -- test repro.roc
    Finished dev [unoptimized + debuginfo] target(s) in 0.24s
     Running `target/debug/roc test repro.roc`
thread '<unnamed>' panicked at crates/compiler/mono/src/layout.rs:3297:69:
index out of bounds: the len is 0 but the index is 0
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
^C
module [getListOfLists]

getListOfLists : {} -> List List _
getListOfLists = \_ -> []

expect getListOfLists {} == []

@smores56 would you be able to investigate this? I think it's Mono related

@lukewilliamboswell lukewilliamboswell added bug Something isn't working mono Relates to the Monomorphization compiler stage labels Dec 14, 2024
@smores56
Copy link
Collaborator

Some pretty weird observations here:

  • When I add parentheses around what should be the inner type of List _, everything type checks and roc test repro.roc passes.
  • The LSP currently thinks that the type of List List _ is List List, implying to me that we infer the type hole as a type variable that gets ignored or something.
  • Interestingly, if I change the type to List Str _ then the inferred type is List Str even without the parentheses, and everything works.
  • However, List Str Str also works, which shouldn't.
  • {} -> List is inferred as {} -> List a where a implements Eq (because of the == in the test)

So this looks like a bug where we are not validating the number of type args a type constructor gets. If it receives fewer args than expected, it sometimes infers a new variable, and sometimes doesn't leading to crashes like the one reported. Extra type args are seemingly ignored. I think the fix would involve us adding type arg amount constraining somewhere in roc_constrain.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working mono Relates to the Monomorphization compiler stage
Projects
None yet
Development

No branches or pull requests

3 participants