I am developing an application with the new roc compiler. I have some type modules that call common utility functions (i.e. different type modules reusing the same common functions). this seems to make roc test unhappy. is this by design? these are all pure functions
roc test shouldn't be unhappy about anything... have you found a bug?
i feel like I'm Doing It Wrong, but i've tried all kinds of things. let's say I have parse.roc with some pure functions defined, that take strings and return numbers. then a type module like Wager, that has a parse method (or function) which calls functions defined in parse.roc (ignore capitalization issues; i have been trying all kinds of different module organizations). what's the simplest thing that definitely should work?
the parse utility functions do things like parse_u32('1234') => U32 (let's say) and then Wager or several other types in different modules need to call parse_u32 on different things
this "parse utility file" has a few objectives: includes unit tests; is importable or callable from other files; these other files should have unit tests as well.
what's good new compiler application to reference? i have been using basic-cli (migrate-zig-compiler) but this is showing more platform-style organization
$ roc example_app.roc
dbg: Ok([1])
dbg: Ok([1, 2, 3])
dbg: Err(NotANumber)
dbg: Err(NotANumber)
dbg: Ok([4, 2])
$ roc test Parser.roc --verbose
All (4) tests passed in 37.1 ms.
PASS: Parser.roc:24
PASS: Parser.roc:25
PASS: Parser.roc:26
PASS: Parser.roc:27
# a Roc type module includes a single nominal type
Parser := {}.{
# this is an function associated with the Parser type
# e.g. "12" -> [1,2]
parse_digits : Str -> Try(List(U8), [NotANumber])
parse_digits = |str| {
bytes = Str.to_utf8(str)
bytes.fold(Ok([]), |acc, byte| {
match acc {
Err(e) => Err(e)
Ok(digits) => {
if '0' <= byte and byte <= '9' {
Ok(List.append(digits, byte - '0'))
} else {
Err(NotANumber)
}
}
}
})
}
}
expect Parser.parse_digits("12") == Ok([1,2])
expect Parser.parse_digits("abc") == Err(NotANumber)
expect Parser.parse_digits("123") == Ok([1,2,3])
expect Parser.parse_digits("1234") == Ok([1,2,3,4])
app [main!] { pf: platform "https://github.com/lukewilliamboswell/roc-platform-template-zig/releases/download/0.6/2BfGn4M9uWJNhDVeMghGeXNVDFijMfPsmmVeo6M4QjKX.tar.zst" }
import pf.Stdout
import Parser
main! = |_args| {
dbg Parser.parse_digits("1")
dbg Parser.parse_digits("123")
dbg Parser.parse_digits("NotADigit")
dbg Parser.parse_digits("0.1")
dbg Parser.parse_digits("42")
Ok({})
}
This should help! Taking rhe dogs for a walk rn ...
Rick Hull said:
what's good new compiler application to reference? i have been using
basic-cli(migrate-zig-compiler) but this is showing more platform-style organization
There isn't any examples or documentation yet -- aside from the bits and pieces in the langref/ ... the new compiler isn't a very friendly place for beginners right now and there are unimplemented or buggy things lurking around every corner.
The more we try and build real things though we can find the issues and fix them one by one... so it's very helpful when people try things out and report any issues or questions.
@Luke Boswell big help, thanks! we (me and claude) were using [].{...} not {}.{...} what are the implications?
Both should work...
[] is an empty tag union, {} is an empty record, both are zero sized types.
i think we found a bug, but compiler is like 10 days old; continuing to test and narrow down; will get the latest nightly
For now:
The bug is precisely: inside a {}.{...} type method at comptime, once a different method
is called on one parameter (e.g. a.to_u64()), subsequent access to the other parameter
(b) loses scope. to_str doesn't trigger it — likely because it's the same builtin method
called on both, so the comptime evaluator doesn't context-switch the same way.
grabbing a newer compiler to retest
https://gist.github.com/rickhull/289ef29265d182ada8accc81957fd93a # latest roc-nightly
Rick Hull said:
https://gist.github.com/rickhull/289ef29265d182ada8accc81957fd93a # latest roc-nightly
looks like a bug to me, can you make a GH issue?
we were able to repro a segfault repeatedly, at address 0xblahblah, supposedly ASCII 'tosh'; unable to repro for now
● Bash(roc test src/ParseUtil.roc --verbose 2>&1)
⎿ Error: Exit code 139
Segmentation fault (SIGSEGV) in the Roc compiler.
Fault address: 0x74736f68
Please report this issue at: https://github.com/roc-lang/roc/issues
● THERE IT IS! The segfault! When Value.parse_sexp (a type method) calls tokenize (a
module-level function with fold) at comptime IN THE SAME FILE, it segfaults!
But wait - spike/Value.roc works with the exact same structure. Let me compare the two
more carefully:
● This is a deep compiler bug. For now, we have a working version in spike/Value.roc and
the copy in ParseUtil_minimal.roc. The full ParseUtil.roc segfaults for reasons we
haven't identified yet.
Summary for you: We've hit a Roc compiler bug that causes segfaults when type methods
call module-level functions at comptime. We've identified that fold-based tokenize works
(avoiding for/var), but there's still a segfault in the full ParseUtil that doesn't
occur in the minimal spike/Value.roc version. We have working code we can build from,
but debugging the compiler bug itself would require more investigation.
it looks like there are 3 bugs, and initial suspicion is that they are all specific to roc test
If you log a GH issue with the files to minimally reproduce, that would be helpful.
It should be easy enough to fix I think. I'm looking at some other bugs rn
roc test hasn't had any love in months
It hasn't been upgraded to use the new coordinator, so that could be related here
Questions about the single-nominal-type-per-file syntax:
Builtin.roc as sort of a bible for this pattern, other than the special ProvidedByCompiler constructor?I'm wondering if a windows-specific bug I'm running into working on the glue command is actually a case of 2 not being treated as a compile error when it should be an error.
I recently added the error for not having a top level nominal type... I dont think I added one for multiple top level nominal types.
It should be an error
I would say Builtin.roc is probable the best example, aside from the annotation only parts the compiler implements internally
https://github.com/roc-lang/roc/issues/9117
https://github.com/roc-lang/roc/issues/9118
https://github.com/roc-lang/roc/issues/9119
For reference type modules should be named with an uppercase, like Bug3.roc not bug3.roc -- and match the name of the type they exposing
See https://github.com/roc-lang/roc/blob/main/langref/modules.md
this was just iterating on getting a minimal repro, not necessarily realistic; would it matter here?
The compiler shouldn't segfault, and should give helpful error messages... so if we find any situation where it doesn't that's a bug
I thought I'd mention that in case it unblocks you
I'm not sure how I would go about reproducing it, but without the error for multiple type declarations in a file, we get fun stack corruption on windows. Might be worth figuring out how to avoid that even if we won't hit this specific case any more.
Last updated: Feb 20 2026 at 12:27 UTC