Stream: advent of code

Topic: {unknown: _field}


view this post on Zulip Aurélien Geron (Dec 03 2025 at 06:53):

Hi!
I'm trying to do day 1 of AoC 2025. I'm getting a compiler error that I really don't understand:

-- TYPE MISMATCH ---------------------------------

This expression is used in an unexpected way:
   ┌─ day01.roc:10:19
   │
10 │             num = num_str.to_i32()?
   │                   ^^^^^^^

It has the type:
    Str

But I expected it to be:
    { unknown: _field }

Found 1 error(s) and 0 warning(s) for day01.roc.

Roc crashed: non-exhaustive match

Here's my program:

app [main!] { pf: platform "https://github.com/lukewilliamboswell/roc-platform-template-zig/releases/download/0.3/98T93wthPgoBRLYtPTT4RBBsQunrfDG94gihPf1zYYmE.tar.zst" }

import pf.Stdout

parse_instruction = |chars| {
    match chars {
        [] => Err(ParsingError)
        [c, ..rest] => {
            num_str = Str.from_utf8(rest)?
            num = num_str.to_i32()?
            if c == 'L' { Ok(-num) } else { Ok(num) }
        }
    }
}


main! = |_args| {
    res = parse_instruction("L12".to_utf8())
    match res {
        Ok(num) => {
            Stdout.line!(num.to_str())
            Ok({})
        }
        _ => Err(Exit(1))
    }
}

view this post on Zulip Anton (Dec 03 2025 at 10:12):

I'll take a look

view this post on Zulip Anton (Dec 03 2025 at 16:07):

I got sidetracked by adding missing tests, I'm almost done though

view this post on Zulip Anton (Dec 03 2025 at 18:36):

Instead of num_str.to_i32() it needs to be I32.from_str(num_str).

view this post on Zulip Anton (Dec 03 2025 at 18:37):

I will make an issue for the bad error message

view this post on Zulip Aurélien Geron (Dec 04 2025 at 23:59):

I've solved both parts of AoC 2025 Day 01 using the old compiler, then I ported the code as best I could to the new compiler, and roc check day01.roc says there are no errors, but I get a segfault at runtime. I tried to activate the ref counting logs as instructed by @Luke Boswell , but I'm not sure I did it correctly because I don't understand how I can use this output. Here's the full program:

app [main!] { pf: platform "https://github.com/lukewilliamboswell/roc-platform-template-zig/releases/download/0.3/98T93wthPgoBRLYtPTT4RBBsQunrfDG94gihPf1zYYmE.tar.zst" }

import pf.Stdout

data =
    \\L50
    \\L12
    \\R13
    \\L1
    \\L5
    \\R5


parse_instruction: List(U8) -> Try(I32, _)
parse_instruction = |chars| {
    match chars {
        [] => Err(ParsingError)
        [c, .. as rest] => {
            num_str = Str.from_utf8(rest)?
            num = I32.from_str(num_str)?
            if c == 'L' { Ok(-num) } else { Ok(num) }
        }
    }
}

count_zeroes_with_clicks: I32, I32 -> I32
count_zeroes_with_clicks = |pos, new_pos| {
    div_floor = |i| {
        if i < 0 { (i + 1) // 100 - 1 } else { i // 100 }
    }

    incr = (div_floor(new_pos) - div_floor(pos)).abs()
    if new_pos < pos {
        incr + (if new_pos % 100 == 0 { 1 } else { 0 }) - (if pos % 100 == 0 { 1 } else { 0 })
    } else {
        incr
    }
}

compute_password: List(I32), I32, I32, Bool -> I32
compute_password = |instructions, pos, count, with_clicks| {
    match instructions {
        [] => count
        [inst, .. as rest] => {
            new_pos = pos + inst
            new_count =
                count
                +
                if with_clicks {
                    count_zeroes_with_clicks(pos, new_pos)
                } else if new_pos % 100 == 0 {
                    1
                } else {
                    0
                }
            rest->compute_password(new_pos, new_count, with_clicks)
        }
    }
}

map_try: List(a), (a -> Try(b, c)) -> Try(List(b), c)
map_try = |list, to_result_fun| {
    list->walk_try(
        [],
        |state, elem| {
            match to_result_fun(elem) {
                Ok(ok) => Ok(state.append(ok))
                Err(b) => Err(b)
            }
        }
    )
}

walk_try: List(a), s, (s, a -> Try(s, c)) -> Try(s, c)
walk_try = |list, init, func| {
    match list {
        [] => { Ok(init) }
        [val, .. as rest] => {
            maybe_state = func(init, val)
            match maybe_state {
                Ok(state) => walk_try(rest, state, func)
                Err(b) => Err(b)
            }
        }
    }
}

main!: List(Str) => Try({  }, [Exit(I32)])
main! = |_args| {
    lines_utf8 = data.split_on("\n").map(|s| s.to_utf8())
    maybe_instructions = lines_utf8->map_try(parse_instruction)
    match maybe_instructions {
        Ok(instructions) => {
            result1 = instructions->compute_password(50, 0, False)
            Stdout.line!(result1.to_str())

            result2 = instructions->compute_password(50, 0, True)
            Stdout.line!(result2.to_str())

            Ok({})
        }
        _ => {
            Stdout.line!("Error")
            Err(Exit(1))
        }
    }
}

Here's the output:

debug: [HOST] Building args...
debug: [ALLOC] ptr=0x1034c0008 size=40 align=8
debug: [ALLOC] ptr=0x1034e0008 size=137 align=8
debug: [HOST] args_list ptr=0x1034c0018 len=1
debug: [HOST] Calling roc__main_for_host...
error: Child process /Users/ageron/Library/Caches/roc/5931167c7313ef73dbb36e68e48b39cf/temp/roc-tmp-ZtoLGEfLd8V5hXupRG23Usp7b6PNT2Iz/roc_run_994723065 killed by signal: 11
error: Child process crashed with segmentation fault (SIGSEGV)

Thanks for your help.

view this post on Zulip Aurélien Geron (Apr 02 2026 at 00:46):

I just updated to the latest compiler (compiled from source). Sadly, I'm getting the same issue as before: roc check day01.roc passes without any problem, but when I run roc day01.roc, I get zero output and the exit code is 139.

I tried compiling with zig build test -Dtrace-refcount, as instructed, but there were 4 errors during the build:

[...]
[REFCOUNT] DECREF closure struct fields=0
[REFCOUNT] DECREF closure DONE ptr=0x115060128
[REFCOUNT] DECREF layout.tag=5 ptr=0x1150600f0
[REFCOUNT] DECREF struct ptr=0x1150600f0 fields=3
␃

======================================
First difference occurs on line 1:
expected:

^ (end of string)
found:
[REFCOUNT] INCREF list (copyToPtr) ptr=0x14c060018 len=1 rc=1 slice=0 elems_rc=0
^ ('\x5b')
/opt/homebrew/Cellar/zig/0.15.2/lib/zig/std/testing.zig:673:9: 0x1001c30a3 in expectEqualStrings (fx_platform_test)
        return error.TestExpectedEqual;
        ^
/Users/ageron/dev/software/roc/src/cli/test/fx_platform_test.zig:276:5: 0x1001c3ab7 in testRocTestSinglePass (fx_platform_test)
    try testing.expectEqualStrings("", run_result.stderr);
    ^
/Users/ageron/dev/software/roc/src/cli/test/fx_platform_test.zig:290:5: 0x1001c5b1b in test.fx platform expect with numeric literal (dev backend) (fx_platform_test)
    try testRocTestSinglePass("--opt=dev", "test/fx/expect_with_literal.roc");
    ^
error: while executing test 'fx_test_specs.test.find by path works', the following test command failed:
./.zig-cache/o/0f39b7360e6022731ad8853445efb7a7/fx_platform_test --cache-dir=./.zig-cache --seed=0x59791556 --listen=-

Build Summary: 111/114 steps succeeded; 1 failed; 3494/3510 tests passed; 12 skipped; 4 failed
test transitive failure
└─ tests_summary transitive failure
   └─ run test fx_platform_test 49/58 passed, 4 failed, 5 skipped

error: the following build command failed with exit code 1:
.zig-cache/o/7f41ba9e64948bf84032de38cf4b09b4/build /opt/homebrew/Cellar/zig/0.15.2/bin/zig /opt/homebrew/Cellar/zig/0.15.2/lib/zig /Users/ageron/dev/software/roc .zig-cache /Users/ageron/.cache/zig --seed 0x59791556 -Ze417d1370ce16f8a test -Dtrace-refcount

That said, it looks like the compiler is built successfully. But the problem remains: roc check day01.roc succeeds but not roc day01.roc (error 139). Here's the output:

PastedText.txt

Should I just wait until the new compiler is more stable or is there something I can do to fix this? Thanks! :folded_hands:

view this post on Zulip Luke Boswell (Apr 02 2026 at 00:47):

I'd wait until it's more stable for this specific issue. Sorry

view this post on Zulip Luke Boswell (Apr 02 2026 at 00:48):

The dev backend has had a lot of love... but it's all sitting on a branch and not ready to land yet

view this post on Zulip Luke Boswell (Apr 02 2026 at 00:50):

I know we've been saying close or soon now for a while... but we literally find issues at the very last minute and they tend to be material and require fixing upstream.

view this post on Zulip Aurélien Geron (Apr 02 2026 at 01:55):

Thanks @Luke Boswell , I can wait, no problem. Let me know if I can be of any help.

view this post on Zulip Luke Boswell (Apr 02 2026 at 02:00):

We have the "echo" platform up and running now which is designed for examples... if your interested someone needs to start tinkering with that and thinking about the exercism track again.

view this post on Zulip Luke Boswell (Apr 02 2026 at 02:00):

You can hit bugs with more complex apps ... but it should be pretty stable for simple things I think

view this post on Zulip Luke Boswell (Apr 02 2026 at 02:04):

$ cat test/echo/hello.roc
main! = |_args| {
    echo!("Hello, World!")
    Ok({})
}
$ roc test/echo/hello.roc
Hello, World!

view this post on Zulip Luke Boswell (Apr 02 2026 at 02:06):

It has a single effect that is imported by default echo! : Str => {}

view this post on Zulip Luke Boswell (Apr 02 2026 at 02:07):

and main is

main! : List(Str) => Try({}, [Exit(I8), ..])

view this post on Zulip Aurélien Geron (Apr 02 2026 at 02:38):

Thanks. I'm surprised there's no need for an app section, and no import pf.echo!. Is echo the default platform?

view this post on Zulip Luke Boswell (Apr 02 2026 at 02:39):

Yeah, it's a default platform that is always available for the purpose of tutorials and teaching Roc

view this post on Zulip Luke Boswell (Apr 02 2026 at 02:40):

The idea of not having the app header or import statements, is that we can introduce those concepts later when onboarding people.

view this post on Zulip Aurélien Geron (Apr 02 2026 at 02:41):

Cool, I like it!


Last updated: Apr 10 2026 at 12:38 UTC