roc-lang / roc

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

Inspecting an empty dict causes the compiler to panic #7067

Open ageron opened 1 month ago

ageron commented 1 month ago

This code should reproduce the issue:

app [main] {
    pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.15.0/SlwdbJ-3GR7uBWQo6zlmYWNYOxnvo8r6YABXD-45UOw.tar.br",
}

import pf.Stdout

main =
    emptyDict = Dict.empty {}
    Stdout.line! (Inspect.toStr emptyDict)

I get this error:

$ roc empty-dict.roc
thread '<unnamed>' panicked at crates/compiler/mono/src/ir.rs:6151:56:
called `Option::unwrap()` on a `None` value
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

The error goes away if I add a type annotation to emptyDict, such as:

emptyDict : Dict Str U64
Thymelizabeth commented 1 month ago

I have the same thing happen to me when attempting to pattern match a list.

app [main] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.15.0/SlwdbJ-3GR7uBWQo6zlmYWNYOxnvo8r6YABXD-45UOw.tar.br" }

import pf.Stdout

main =
    # testList : List U8 # This line allows the code to compile
    testList = []
    when isPrefix testList [] is
        Equal -> Stdout.line! "Empty list is equal to empty list"
        _ -> crash "Empty list should be equal to empty list"

isPrefix : List a, List a -> [Equal, Prefix, Nothing] where a implements Eq
isPrefix = \list1, list2 ->
    when list1 is
        [] -> when list2 is
            [] -> Equal
            _ -> Prefix

        [x, .. as xs] -> when list2 is
            [] -> Nothing
            [y, .. as ys] ->
                if x == y then
                    isPrefix xs ys
                else
                    Nothing
$ RUST_BACKTRACE="full" nix run github:roc-lang/roc --extra-experimental-features nix-command --extra-experimental-features flakes -- dev
thread '<unnamed>' panicked at crates/compiler/mono/src/ir.rs:6151:56:
called `Option::unwrap()` on a `None` value
stack backtrace:
   0:     0x56157e199146 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h410d4c66be4e37f9
   1:     0x56157e1c9dd0 - core::fmt::write::he40921d4802ce2ac
   2:     0x56157e194c1f - std::io::Write::write_fmt::h5de5a4e7037c9b20
   3:     0x56157e198f24 - std::sys_common::backtrace::print::h11c067a88e3bdb22
   4:     0x56157e19a7b7 - std::panicking::default_hook::{{closure}}::h8c832ecb03fde8ea
   5:     0x56157e19a519 - std::panicking::default_hook::h1633e272b4150cf3
   6:     0x56157e19ac48 - std::panicking::rust_panic_with_hook::hb164d19c0c1e71d4
   7:     0x56157e19aae9 - std::panicking::begin_panic_handler::{{closure}}::h0369088c533c20e9
   8:     0x56157e199646 - std::sys_common::backtrace::__rust_end_short_backtrace::hc11d910daf35ac2e
   9:     0x56157e19a874 - rust_begin_unwind
  10:     0x56157b617c05 - core::panicking::panic_fmt::ha6effc2775a0749c
  11:     0x56157b617cc3 - core::panicking::panic::h44790a89027c670f
  12:     0x56157b617b56 - core::option::unwrap_failed::hcb3a256a9f1ca882
  13:     0x56157de347bb - roc_mono::ir::late_resolve_ability_specialization::h4ca09e59d7b4ee73
  14:     0x56157de2728d - roc_mono::ir::with_hole::h17b1605e4cbd01e5
  15:     0x56157de4d7e7 - roc_mono::ir::assign_to_symbol::h1b3576846682d464
  16:     0x56157de41b54 - roc_mono::ir::from_can::h3b67df580f94e51b
  17:     0x56157de44b10 - roc_mono::ir::from_can_when::ha038ba5262d690a4
  18:     0x56157de3fe8b - roc_mono::ir::from_can::h3b67df580f94e51b
  19:     0x56157de44b10 - roc_mono::ir::from_can_when::ha038ba5262d690a4
  20:     0x56157de3fe8b - roc_mono::ir::from_can::h3b67df580f94e51b
  21:     0x56157de2494c - roc_mono::ir::specialize_variable::h0f01d889b4dfad0e
  22:     0x56157de4ff27 - roc_mono::ir::call_by_name::h7e99434818f3cc4c
  23:     0x56157de29bf7 - roc_mono::ir::with_hole::h17b1605e4cbd01e5
  24:     0x56157de4d7e7 - roc_mono::ir::assign_to_symbol::h1b3576846682d464
  25:     0x56157de3fed3 - roc_mono::ir::from_can::h3b67df580f94e51b
  26:     0x56157de171b2 - roc_mono::ir::from_can_let::hc81c571137115e56
  27:     0x56157de40522 - roc_mono::ir::from_can::h3b67df580f94e51b
  28:     0x56157de2494c - roc_mono::ir::specialize_variable::h0f01d889b4dfad0e
  29:     0x56157de1d85b - roc_mono::ir::specialize_external_help::h781d9580ac5942af
  30:     0x56157de1aedc - roc_mono::ir::specialize_all::hcdbfbc4b34e39146
  31:     0x56157d96c18c - roc_load_internal::file::run_task::hbe73be6aab3fb3fd
  32:     0x56157d8f9ccd - core::ops::function::FnOnce::call_once{{vtable.shim}}::hd75ee2e4d31090e7
  33:     0x56157d8f2bbe - std::sys_common::backtrace::__rust_begin_short_backtrace::h55c22558c9ccdcd5
  34:     0x56157d8fa9b9 - core::ops::function::FnOnce::call_once{{vtable.shim}}::hf73e97d2b415e140
  35:     0x56157e1a0e35 - std::sys::pal::unix::thread::Thread::new::thread_start::h3631815ad38387d6
  36:     0x7f5bdb6a1272 - start_thread
  37:     0x7f5bdb71cdcc - __GI___clone3
  38:                0x0 - <unknown>
bhansconnect commented 1 month ago

It looks like ability implementations don't know how to specify for non-existent types. Which makes sense that it wouldn't be handled.