Stream: compiler development

Topic: Inspect as builtin


view this post on Zulip Richard Feldman (Aug 11 2023 at 12:04):

I have a PR for making Inspect a builtin - it's getting this:

---- gen_records::optional_field_destructure_module stdout ----
thread 'gen_records::optional_field_destructure_module' panicked at 'wasm-ld: error: unknown file type: /tmp/nix-shell.zczC9A/.tmpxRLGKA/test_11934200539654871657.a

This can happen if multiple tests have the same input string', crates/compiler/test_gen/src/helpers/llvm.rs:505:13
stack backtrace:
   0: rust_begin_unwind
             at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/std/src/panicking.rs:578:5
   1: core::panicking::panic_fmt
             at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/core/src/panicking.rs:67:14
   2: test_gen::helpers::llvm::compile_to_wasm_bytes
   3: test_gen::helpers::llvm::assert_wasm_evals_to_help
   4: core::ops::function::FnOnce::call_once
   5: core::ops::function::FnOnce::call_once
             at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/core/src/ops/function.rs:250:5

anyone recognize this error?

view this post on Zulip Richard Feldman (Aug 11 2023 at 12:04):

the hint of "This can happen if multiple tests have the same input string" doesn't seem likely, since I didn't change any test names

view this post on Zulip Richard Feldman (Aug 11 2023 at 12:05):

separately from that test failure,

when I run roc check examples/inspect-logging.roc it passes, but roc build on it now panics with:

'more argument symbols than arguments (according to the layout) for Set.walk', crates/compiler/mono/src/ir.rs:3967:35

or sometimes:

'more argument symbols than arguments (according to the layout) for List.walk', crates/compiler/mono/src/ir.rs:3967:35

roc build succeeded on it when Inspect was in userpsace; it only started failing when I moved it into a builtin

view this post on Zulip Anton (Aug 11 2023 at 12:16):

wasm-ld: error: unknown file type is a common flaky error on nix apple silicon, I've restarted the workflow

view this post on Zulip Anton (Aug 11 2023 at 12:40):

It passed :)

view this post on Zulip Richard Feldman (Aug 11 2023 at 13:12):

nice, thanks! :smiley:

view this post on Zulip Richard Feldman (Aug 11 2023 at 13:12):

ok, so then there's just the roc build panic :thinking:

view this post on Zulip Richard Feldman (Aug 15 2023 at 06:56):

so https://github.com/roc-lang/roc/pull/5747 passes now. Looking ahead to the next step, these are all goals:

view this post on Zulip Richard Feldman (Aug 15 2023 at 06:57):

it's straightforward to have it be auto-derived for everything except opaque types, and then have opaque types be able to opt into it by just adding implements [Inspect] because that's basically how Encoding works, except this would auto-derive for functions too (which is straightforward)

view this post on Zulip Richard Feldman (Aug 15 2023 at 06:57):

the tricky part is having Inspect.inspect take * and still return something (namely, "<opaque>" or something like that) for opaque types that don't have Inspect

view this post on Zulip Richard Feldman (Aug 15 2023 at 06:58):

because it still needs to use their Inspect implementations if they actually have one

view this post on Zulip Richard Feldman (Aug 15 2023 at 07:02):

one idea is that we have Inspect.inspect be implemented as a RunLowLevel operation which looks at the specialized type, checks if it has the Inspect ability (somehow - I don't actually know if that's possible after specialization, but I assume if anyone knows it's @Ayaz Hafiz :big_smile:), calls the appropriate ability member if it does have the ability, and then if it doesn't have the ability, defaults to "<opaque>" because we know that's what it has to be if it doesn't have the Inspect ability

view this post on Zulip Richard Feldman (Aug 15 2023 at 07:02):

does that sound like a viable approach? Is there a better one?

view this post on Zulip Ayaz Hafiz (Aug 16 2023 at 04:47):

i think the best approach is implementing Inspect.inspect to be solved and code-gened in mono as any other function and ability member would. adding an auto-derived for every type would give resolution of the correct implementation for free.

view this post on Zulip Richard Feldman (Aug 16 2023 at 10:28):

as in, make the type of Inspect.inspect's argument have an ability constraint?

view this post on Zulip Richard Feldman (Aug 16 2023 at 10:31):

I'm not sure how that strategy would be able to distinguish between "this opaque type has been marked as implements Inspect and therefore we should auto derive an implementation that shows its internal contents" and "this opaque type has not been marked as implements Inspect and so we should still auto-derive an implementation, but this time the implementation does not reveal any internals of the opaque type"

view this post on Zulip Ayaz Hafiz (Aug 16 2023 at 14:01):

why wouldn't it be able to distinguish that? we already have that for all other abilities with opaques and structural types

view this post on Zulip Richard Feldman (Aug 16 2023 at 14:55):

we do? huh!

view this post on Zulip Richard Feldman (Aug 16 2023 at 14:56):

so just to be clear, this can work?

Foo := Str implements Inspect
Bar := Str

foo = Inspect.inspect (@Foo "blah") # foo = "blah"
bar = Inspect.inspect (@Bar "blah") # bar = "<opaque>"

...with Inspect.inspect's argument having an Inspect constraint?

view this post on Zulip Ayaz Hafiz (Aug 16 2023 at 15:40):

I don't see why not

view this post on Zulip Richard Feldman (Aug 16 2023 at 17:17):

well great! haha

view this post on Zulip Richard Feldman (Aug 29 2023 at 01:48):

@Ayaz Hafiz ok I added it to the obligation checker here: https://github.com/roc-lang/roc/pull/5775/files#diff-e91d42161e55644e56ab4625459a2e71ac01628a9ff67c0f030c0ff1db9bf3ab - and also in that (draft) PR I added some derive_key stuff...but the obligation checker part just says "there's an implementation there" as far as I can tell, but it doesn't say where

view this post on Zulip Richard Feldman (Aug 29 2023 at 01:49):

so I'm not sure where to put that, given that (as I understand it) the derive_key part is for when someone writes implements on the opaque type they're defining in order to opt into the derivation that actually renders the internals of the opaque type...or is that the ad-hoc one which gets rendered if they don't write implements at all?

view this post on Zulip Ayaz Hafiz (Aug 29 2023 at 02:57):

take a look at adding to https://github.com/roc-lang/roc/blob/263fb5632f8b73703d4362648f1e7115f893342b/crates/compiler/solve/src/specialize.rs#L614

view this post on Zulip Ayaz Hafiz (Aug 29 2023 at 14:01):

specifically opaques without a specific inspect impl should fall into https://github.com/roc-lang/roc/blob/263fb5632f8b73703d4362648f1e7115f893342b/crates/compiler/solve/src/specialize.rs#L663-L664 if you update builtin_module_with_unlisted_ability_impl


Last updated: Jul 06 2025 at 12:14 UTC