Stream: compiler development

Topic: builtin contains a signature without implementation


view this post on Zulip Jasper Woudenberg (May 18 2024 at 11:58):

I could use some help with an error I'm running into, while working on adding the Sort ability.

This is my branch:
https://github.com/roc-lang/roc/compare/main...jwoudenberg:roc:main

This is the command I'm running: cargo test-gen-llvm -vvv

This is the error I get:

[roc_load 0.0.1] A builtin module contains a signature without implementation for `List.structuralCompare`

I managed to fix the error, by choosing 108 for the identId of List.structuralCompare. The error showed when I was using 91, which is the ident of the previous entry plus one. I'm trying to find out where that 108 is coming from.

Of potential interest: when I print the symbol I added for structuralCompare, I get this:

[roc_load 0.0.1] [crates/compiler/can/src/builtins.rs:114:1] Symbol::LIST_STRUCTURAL_COMPARE = `List.repeatHelp`

I don't know why it's thinking List.repeatHelp is involved.

Anyone got any ideas?

view this post on Zulip Jasper Woudenberg (Jun 16 2024 at 10:00):

The previous error still exists, but can be worked around. But I've ran into a different error trying to implement a code generation test that I'm hoping someone recognizes :).

This is the initial test I wrote (commit):

#[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev", feature = "gen-wasm"))]
fn compare_i64() {
    assert_evals_to!(
        indoc!(
            r#"
                i : I64
                i = 1

                j : I64
                j = 2

                when List.compare i j is
                    Equals -> 0
                    GreaterThan -> 1
                    LessThan -> 2
            "#
        ),
        2,
        i64
    );
}

Then I run it:

test_gen cargo test-gen-llvm gen_compare

It fails with this error: constructor must be known in the indexable type if we are exhautiveness checking

I'm not sure why exhaustiveness would be a problem, given the following type signature for compare:

Sort implements
    compare : a, a -> [LessThan, Equal, GreaterThan] where a implements Sort

One work around I tried is adding a fallback to the when statement:

                when List.compare i j is
                    Equals -> 0
                    GreaterThan -> 1
                    LessThan -> 2
                    _ -> 3

This results in the error: If resolving a specialization, the specialization must be known to typecheck.

As a third option I tried to avoid using a when statement entirely:

#[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev", feature = "gen-wasm"))]
fn compare_i64() {
    assert_evals_to!(
        indoc!(
            r#"
                i : I64
                i = 1

                j : I64
                j = 2

                List.compare i j == LessThan
            "#
        ),
        true,
        bool
    );
}

Another error:

assertion `left == right` failed: (LambdaSet([], ^<2861>), Func([<68>Opaque(`Num.Num`, [65], <65>Opaque(`Num.Integer`, [2854], <2854>Opaque(`Num.Signed64`, [], <2851>EmptyTagUnion))),<70>Opaque(`Num.Num`, [65], <65>Opaque(`Num.Integer`, [2854], <2854>Opaque(`Num.Signed64`, [], <2851>EmptyTagUnion))),], <2863=73>LambdaSet([], ^<2861>), <74>['Equal' , 'GreaterThan' , 'LessThan' , ]<Any(2865)>))
  left: 0
 right: 1
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

It doesn't matter by the way if I assert against false instead of true, the error is the same.

The error messages come from code in the specialization and exhaustiveness modules. I'm sort of hoping to avoid tracing the error through there, partly because I'm currently unfamiliar with that code, also because I assume the problem is with the code I wrote setting up the Sort ability in the PR, and not with specialization/exchaustiveness checking logic itself.

One blind spot in my understanding: I don't currently understand where the Num a types (or other primitive types) are hooked up with an implementation of Sort. I've not found that for the Eq ability either, which is used as an example for Sort. Maybe that's the piece that's missing?

Any ideas would be greatly appreciated, even vague ones with regards to a direction where I might take a look!

cc @Ben Plotke

view this post on Zulip Richard Feldman (Jun 16 2024 at 15:14):

hm, maybe @Folkert de Vries or @Ayaz Hafiz might know?

view this post on Zulip Ayaz Hafiz (Jun 16 2024 at 15:20):

how have you defined the implementation for compare for numbers?

view this post on Zulip Jasper Woudenberg (Jun 16 2024 at 15:42):

I am not sure.

There's a structuralCompare function, and it has an implementation for int comparisons in gen_llvm. Comparisons for other types and other backends aren't in yet, I was hoping I might be able to test what we have before adding those.

There's no explicit implementation of Sort in Num.roc, do I need to add one? There's none for Eq either (what I've been using as a template for this feature).

view this post on Zulip Ayaz Hafiz (Jun 16 2024 at 15:55):

I don't know why it's thinking List.repeatHelp is involved.

This is probably because the numbering is out of order

        90 LIST_COMPARE: "compare"
        unexposed 108 LIST_STRUCTURAL_COMPARE: "structuralCompare"

it should go 90->91

view this post on Zulip Ayaz Hafiz (Jun 16 2024 at 15:56):

I think the reason you're seeing the other error is because you have not instructed the compiler to lower calls from compare to structuralCompare

view this post on Zulip Ayaz Hafiz (Jun 16 2024 at 15:56):

compare has no implementation so things blow up

view this post on Zulip Ayaz Hafiz (Jun 16 2024 at 15:56):

https://github.com/roc-lang/roc/pull/4290 might be helpful as a template

view this post on Zulip Jasper Woudenberg (Jun 16 2024 at 17:13):

Ayaz Hafiz said:

I don't know why it's thinking List.repeatHelp is involved.

This is probably because the numbering is out of order

it should go 90->91

Using 108 is the workaround for getting rid of the List.repeatHelp error. I had it 91 originally, and that's when the error was happening!

view this post on Zulip Jasper Woudenberg (Jun 16 2024 at 17:23):

Ayaz Hafiz said:

https://github.com/roc-lang/roc/pull/4290 might be helpful as a template

Thank you!


Last updated: Jul 06 2025 at 12:14 UTC