Stream: bugs

Topic: Compiler crash when it can not find out the Err type


view this post on Zulip Oskar Hahn (Dec 01 2024 at 17:56):

I changed the signature of my AoC-platform to Str -> Result Str _.

There seems to be a bug, when the compiler can not find out the type of the error value.

This works:

part1 : Str -> Result Str []
part1 = \input ->
    input
    |> Ok

This also works:

part1 = \input ->
    input
    |> Ok
    |> Result.mapErr \_ -> ThisLineIsNecessaryForRoc

But this fails:

part1 = \input ->
    input
    |> Ok
thread '<unnamed>' panicked at crates/compiler/mono/src/ir.rs:6171:56:
called `Option::unwrap()` on a `None` value

stack backtrace:

Is this a known issue?

view this post on Zulip Eli Dowling (Dec 01 2024 at 18:25):

if you run a debug build of the compiler, it will have a slightly more interesting error:

        let mut iter_lambda_set = solved.iter_all();
        debug_assert_eq!(
            iter_lambda_set.len(),
            1,
            "{:?}",
            (env.subs.dbg(*lambda_set), env.subs.dbg(ambient_function))
        );
        let spec_symbol_index = iter_lambda_set.next().unwrap().0;

That's the code causing the panic.
In debug it'll hit the assert and might give us some more info

view this post on Zulip Oskar Hahn (Dec 01 2024 at 18:38):

With a debug build, I get the following error:

thread '<unnamed>' panicked at crates/compiler/mono/src/layout.rs:2066:17:
unspecialized lambda sets left over during resolution: LambdaSet([] + (<2418>FlexAble(*, [`Inspect.Inspect`]):`Inspect.toInspector`:2), ^<2421>), UlsOfVar(VecMap { keys: [2418], values: [VecSet { elements: [2416, 2420] }] })

Maybe it is relevant, that the platform runs this code:

part1ForHost : Str -> Result Str Str
part1ForHost = \input ->
    part1 input
    |> errToStr


errToStr : Result Str _ -> Result Str Str
errToStr = \r ->
    r |> Result.mapErr Inspect.toStr

view this post on Zulip Brendan Hansknecht (Dec 01 2024 at 18:39):

Yeah, the issue is Inspect.toStr probably

view this post on Zulip Brendan Hansknecht (Dec 01 2024 at 18:39):

Cause it doesn't know how to inspect a *

view this post on Zulip Brendan Hansknecht (Dec 01 2024 at 18:40):

Though I could be wrong, might be related to mapping a * error, but I recall that working.

view this post on Zulip Oskar Hahn (Dec 01 2024 at 18:40):

Yes, you are right. You get the same error in the repl:

Ok "foo" |> Result.mapErr Inspect.toStr

view this post on Zulip Brendan Hansknecht (Dec 01 2024 at 18:41):

By any chance does it work if you wrap Inspect.toStr with a lambda?

view this post on Zulip Oskar Hahn (Dec 01 2024 at 18:42):

Brendan Hansknecht said:

By any chance does it work if you wrap Inspect.toStr with a lambda?

No, same error:

Ok "foo" |> Result.mapErr \err -> Inspect.toStr err

view this post on Zulip Brendan Hansknecht (Dec 01 2024 at 18:43):

And I assume it works if you remove the Inspect.toStr? Just replace with identify function?

view this post on Zulip Oskar Hahn (Dec 01 2024 at 18:44):

Brendan Hansknecht said:

And I assume it works if you remove the Inspect.toStr? Just replace with identify function?

Yes. This works:

Ok "foo" |> Result.mapErr \err -> err

view this post on Zulip Brendan Hansknecht (Dec 01 2024 at 18:45):

Yeah. So it just that you can't inspect a *. Hmm... I wonder if we can still autoderrive for that and add in a dummy value. At a minimum this should produce a good error about applying abilities to *

view this post on Zulip Oskar Hahn (Dec 01 2024 at 18:46):

But why does it work in basic-cli? https://github.com/roc-lang/basic-cli/blob/6b9bc85d18c30cb34bf1351067fe3ec94811bf93/platform/main.roc#L44

view this post on Zulip Brendan Hansknecht (Dec 01 2024 at 18:46):

Or maybe we can just make abilities not generate when called on *. Like it would be fine to generate a crash in those cases. Cause those cases are impossible to call.

view this post on Zulip Brendan Hansknecht (Dec 01 2024 at 18:47):

Basic cli always has at least the Exit error tag

view this post on Zulip Brendan Hansknecht (Dec 01 2024 at 18:48):

Oh, I bet you could work around this with a dummy tag

view this post on Zulip Oskar Hahn (Dec 01 2024 at 18:49):

This does not seem to work. I get the same error, if I change the signature to part1 : Str -> Result Str [SomeError]_

view this post on Zulip Brendan Hansknecht (Dec 01 2024 at 18:49):

Result.map \err ->
    when err is
        Dummy -> Inspect.toStr Dummy
        e -> Inspect.toStr e

view this post on Zulip Oskar Hahn (Dec 01 2024 at 18:51):

Yes. This works! Thank you

errToStr : Result Str _ -> Result Str Str
errToStr = \r ->
    when r is
        Ok v -> Ok v
        Err SomeError -> Err "dummy error"
        Err err -> Err (Inspect.toStr err)

I don't have to do anything in the main signature

view this post on Zulip Brendan Hansknecht (Dec 01 2024 at 18:51):

Can you file a bug for this?

view this post on Zulip Oskar Hahn (Dec 01 2024 at 18:56):

Sure: https://github.com/roc-lang/roc/issues/7289


Last updated: Jul 06 2025 at 12:14 UTC