roc-lang / roc

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

Closure capture causes out-of-bounds in unification table #6880

Open folkertdev opened 4 months ago

folkertdev commented 4 months ago
interface B exposes [] imports []

Op := [StdoutLine Str ({} -> Op), Done]

bad : ({} -> Op) -> Op
bad = \fromResult -> @Op (StdoutLine "foo" fromResult)

done = 
    d : Op
    d = @Op Done
    \{} -> d 

expect
    when bad done is
        _ -> Bool.true

gives this error

thread '<unnamed>' panicked at 'index out of bounds: the len is 2922 but the index is 2922', crates/compiler/types/src/unification_table.rs:295:49
stack backtrace:
   0: rust_begin_unwind
             at /rustc/8ede3aae28fe6e4d52b38157d7bfe0d3bceef225/library/std/src/panicking.rs:593:5
   1: core::panicking::panic_fmt
             at /rustc/8ede3aae28fe6e4d52b38157d7bfe0d3bceef225/library/core/src/panicking.rs:67:14
   2: core::panicking::panic_bounds_check
             at /rustc/8ede3aae28fe6e4d52b38157d7bfe0d3bceef225/library/core/src/panicking.rs:162:5
   3: <usize as core::slice::index::SliceIndex<[T]>>::index
             at /rustc/8ede3aae28fe6e4d52b38157d7bfe0d3bceef225/library/core/src/slice/index.rs:258:10
   4: index<roc_types::unification_table::Combine, usize>
             at /rustc/8ede3aae28fe6e4d52b38157d7bfe0d3bceef225/library/core/src/slice/index.rs:18:9
   5: index<roc_types::unification_table::Combine, usize, alloc::alloc::Global>
             at /rustc/8ede3aae28fe6e4d52b38157d7bfe0d3bceef225/library/alloc/src/vec/mod.rs:2690:9
   6: root_key_without_compacting
             at ./crates/compiler/types/src/unification_table.rs:295:49
   7: get_root
             at ./crates/compiler/types/src/unification_table.rs:179:24
   8: get_copy
             at ./crates/compiler/types/src/unification_table.rs:204:9
   9: get_copy
             at ./crates/compiler/types/src/subs.rs:1870:9
  10: instantiate_rigids_help
             at ./crates/compiler/types/src/subs.rs:5826:12
  11: roc_types::subs::instantiate_rigids
             at ./crates/compiler/types/src/subs.rs:5807:5
  12: specialize_variable
             at ./crates/compiler/mono/src/ir.rs:4043:5
  13: insert_passed_by_name
             at ./crates/compiler/mono/src/ir.rs:1227:23

the error is the same whether EXPERIMENTAL_ROC_ERASE=1 is enabled or not, but disappears when the d variable is manually inlined. So maybe this has to do with closure captures?

https://github.com/roc-lang/roc/issues/6511 has the same error message but seems like it would have a very different cause