Stream: contributing

Topic: dbg in packages


view this post on Zulip Agus Zubiaga (Mar 24 2023 at 02:18):

If you use dbg in a package's interface file, the compiler throws the following error and hangs:

Thread '<unnamed>' panicked at 'called `Option::unwrap()` on a `None` value', crates/compiler/mono/src/ir.rs:6826:18
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

view this post on Zulip Agus Zubiaga (Mar 24 2023 at 02:20):

Apparently, env.expectation_subs is None here: https://github.com/roc-lang/roc/blob/24e2c661870d9d7c54a5aa8750c334a837af1966/crates/compiler/mono/src/ir.rs#L6808-L6812

view this post on Zulip Brendan Hansknecht (Mar 24 2023 at 02:28):

I wonder if that is interface specific. I have seen similar errors a lot. That and sometimes debug just not printing. Definitely one of the easier to break features. I think i notice it most in rather nested code, especially if related to tasks.

view this post on Zulip Agus Zubiaga (Mar 24 2023 at 02:32):

Oh. I haven't noticed that. In this case the app's main is directly calling the function from the package's interface with the dbg usage in it.

view this post on Zulip Brendan Hansknecht (Mar 24 2023 at 02:52):

At least in my absolute minimal repro, it is working in an interface:

interface Interface
    exposes [someFunc]
    imports []

someFunc = \x ->
    dbg x
    x

So maybe not interface specific. Are you able to share example code where this happens or a repro?

view this post on Zulip Brendan Hansknecht (Mar 24 2023 at 02:59):

Oh, nevermind, I can repro.

view this post on Zulip Brendan Hansknecht (Mar 24 2023 at 03:00):

It takes an interface in a package specifically, not an interface in general.

view this post on Zulip Brendan Hansknecht (Mar 24 2023 at 03:05):

submitted #5185 as a minimal repro.

view this post on Zulip Agus Zubiaga (Mar 24 2023 at 03:47):

Nice

view this post on Zulip Agus Zubiaga (Mar 24 2023 at 04:00):

Found the root cause of the None in env.expectaction_subs: https://github.com/roc-lang/roc/blob/24e2c661870d9d7c54a5aa8750c334a837af1966/crates/compiler/load_internal/src/file.rs#L2748-L2753

            let should_include_expects = (!loc_expects.is_empty() || !loc_dbgs.is_empty()) && {
                let modules = state.arc_modules.lock();
                modules
                    .package_eq(module_id, state.root_id)
                    .expect("root or this module is not yet known - that's a bug!")
            };

view this post on Zulip Agus Zubiaga (Mar 24 2023 at 04:01):

!loc_dbgs.is_empty() is true because the dbg exists

view this post on Zulip Agus Zubiaga (Mar 24 2023 at 04:02):

but .package_eq(module_id, state.root_id) evaluates to false because the module is in a different package

view this post on Zulip Agus Zubiaga (Mar 24 2023 at 04:04):

When building applications, you probably don't want to include expects from packages, so that makes sense

view this post on Zulip Agus Zubiaga (Mar 24 2023 at 04:05):

However, we still need a way to use dbg and expect when building packages. Maybe this can be a CLI option?

view this post on Zulip Agus Zubiaga (Mar 24 2023 at 04:08):

Also, in normal operation, it shouldn't crash because a package contains a dbg or expect

view this post on Zulip Richard Feldman (Mar 24 2023 at 20:37):

this is an interesting design question...I've gone back and forth on this in the past, but what makes sense to me right now is:

view this post on Zulip Richard Feldman (Mar 24 2023 at 20:37):

expect is trickier because on the one hand it could be annoying if I get a third-party package that's crashing due to failed expects all the time...but on the other hand, wouldn't it be better if I could report that to them? :thinking:

view this post on Zulip Richard Feldman (Mar 24 2023 at 20:38):

my default thinking is that expect should just always work the same way no matter whether it's a package, and then we can revisit that if it's annoying in practice

view this post on Zulip Agus Zubiaga (Mar 24 2023 at 21:08):

Ah cool. So we just need to get rid of that package_eq check, then.

view this post on Zulip Agus Zubiaga (Mar 24 2023 at 21:09):

I tried it last night and dbg just started working from packages

view this post on Zulip Agus Zubiaga (Mar 24 2023 at 21:10):

Should I make a PR with that change?

view this post on Zulip Richard Feldman (Mar 24 2023 at 21:19):

sounds good to me! @Folkert de Vries any concerns?

view this post on Zulip Ayaz Hafiz (Mar 24 2023 at 21:21):

The one annoyance with this is that this will also mean “roc test” will run all tests under a package and all its dependencies, not just local to the module.

view this post on Zulip Ayaz Hafiz (Mar 24 2023 at 21:22):

That could be made into a separate check though

view this post on Zulip Richard Feldman (Mar 24 2023 at 21:56):

hm, aren't those separate?

view this post on Zulip Richard Feldman (Mar 24 2023 at 21:56):

like roc test doesn't have to run top-level expects in other packages

view this post on Zulip Richard Feldman (Mar 24 2023 at 21:56):

even if it still runs inline expects

view this post on Zulip Ayaz Hafiz (Mar 24 2023 at 22:19):

Right. I just mean that the implementation, I don't think it is enough to only get rid of the package_eq check.

view this post on Zulip Agus Zubiaga (Mar 24 2023 at 22:20):

Yeah, if I get rid of that check, roc test includes expects from packages

view this post on Zulip Agus Zubiaga (Mar 24 2023 at 22:21):

and this weird bug shows up if I have both dbgs and expects in a package, roc test hangs, but it works fine if only have one kind :oh_no:

view this post on Zulip Richard Feldman (Mar 25 2023 at 00:43):

Agus Zubiaga said:

Yeah, if I get rid of that check, roc test includes expects from packages

oh ok, so then the problem is that right after that code we're using should_include_expects to decide whether to include dbgs too

view this post on Zulip Richard Feldman (Mar 25 2023 at 00:43):

https://github.com/roc-lang/roc/blob/24e2c661870d9d7c54a5aa8750c334a837af1966/crates/compiler/load_internal/src/file.rs#L2758

view this post on Zulip Richard Feldman (Mar 25 2023 at 00:43):

so that line could be used in the else branch too, just with expectations: being empty

view this post on Zulip Richard Feldman (Mar 25 2023 at 00:44):

could go even further to have that under an else if !loc_dbgs.is_empty() { so we don't bother cloning solved_subs etc if there happen to be no dbgs


Last updated: Jul 06 2025 at 12:14 UTC