Every once in a while I get an error like the one below. Usually they seem to be because I had a syntax error in my code and I can fix them by finding the syntax error. This is the first time I've been stumped on one of them and I'm wondering if someone can help explain what this error means and how it can hopefully help me figure out what's wrong with my code.
Please file an issue here: https://github.com/roc-lang/roc/issues/new/choose
thread '<unnamed>' panicked at 'no lambda set found for (`22.IdentId(21)`, [
InLayout(
39,
),
InLayout(
250,
),
]): LambdaSet {
set: [
( 22.21, [InLayout(39), InLayout(106)]),
( 22.24, [InLayout(20), InLayout(21)]),
( 22.26, [InLayout(1)]),
],
args: [
InLayout(
1,
),
],
ret: InLayout(
1,
),
representation: InLayout(
83,
),
full_layout: InLayout(
95,
),
}', crates/compiler/mono/src/layout.rs:1506:17
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Can't give justice to the error, but in general would advise running roc check
before compiling your code. Not sure if it would find the issue in this case, but it tends to crash less and report more proper errors that can help fix code and syntax bugs.
I think I found the issue. I get that error when I have when Str.toU16 a is
but if I change it to when (Str.toU16 a) is
then it goes away. Can you not have expressions between when
and is
? Also, interestingly, running roc check
on the bad version gives me 0 errors and 0 warnings found in 352 ms.
Wait, now it's not working. What the heck. It was just working after that change. This is a weird one...
Ok, maybe it's actually when there is a recursive function call. Is that not allowed in Roc?
Here's the function that seems to be generating the error:
setVal : U16, U16, U8 -> Task {} []
setVal = \value, address, pin ->
_ <- await (Pca9685.setPinOffTicks address pin value)
_ <- await (Stdout.line "How is this?")
a <- await Stdin.line
if a == "next" then
addressStr = Num.toStr address
pinStr = Num.toStr pin
valueStr = Num.toStr value
Stdout.line "Set address \(addressStr) and pin \(pinStr) to value: \(valueStr)"
else
when Str.toU16 a is
Ok v -> setVal v address pin
Err _ -> Task.succeed {}
But if I change that second to last line to Ok _ -> Task.succeed {}
then it compiles just fine
Yep, after doing more testing it seems to be that recursion causes this error. I get something similar from the following:
main : Task {} []
main = test
test =
a <- await Stdin.line
if a == "done" then Task.succeed {} else test
But if I change the recursive test
call into Task.succeed {}
it compiles just fine
Recursive calls are most definitely allowed! In a functional language, recursion is the only way to express loops. This is a compiler bug.
I've seen this before in my work on virtual DOM. There was some work on these bugs a while ago but I don't know the current status. @Ayaz Hafiz might be able to offer some insight.
yeah stuff like this we’re actively trying to fix. I’ve been on a kick, but had to slow down for the past couple weeks for other priorities. I’ll diagnose this in the afternoon. Thanks for the report Nick!
Okay, this was a really challenging bug.. took me all day :woozy_face: but https://github.com/roc-lang/roc/pull/5028 should fix it
Wooohoo! That was fast! Thanks so much for hopping on this right away Ayaz
That fix worked Ayaz! I'm no longer getting the error I was before. I have a new one though. Anybody know what would be causing this guy?
thread 'main' panicked at 'Error in alias analysis: error in module ModName("UserApp"), function definition FuncName("\x04\x00\x00\x00\x18\x00\x00\x00j3\x1e\x91C\xfb\x16K"): expected type 'union { ((),), ((),) }', found type '()'', crates/compiler/gen_llvm/src/llvm/build.rs:4748:19
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
I definitely seen that plenty of times. assuming roc check
doesn't give a solution, these can be annoying to debug. I think I often resort to commenting out code to try and figure out what caused the issue. Maybe someone else has better advice.
Ya unfortunately roc check
gives nothing. I’ll give that a try, thanks
Do you have a debug build of the compiler? If so could you try running roc with the env var ROC_CHECK_IR=1 set and let us know if there is any output?
That gave the same error. So maybe I don’t have the debug build? How would I know? I built the compiler from source
try ROC_CHECK_MONO_IR
you'd need to build from source without passing --release
to cargo
that is the default, so probably your build is good
CFC3F0FE-2626-4642-84B5-90386CF6E7B9.jpg
Same thing. Am I doing this right?
hmm, maybe that printing only happens after alias analysis?
try it without --optimize
?
Same thing
2E9CE00A-BDFB-4D1B-9C17-A52DF0F096EB.jpg
I think I’m starting to figure it out though. If I comment out one of the platform functions that I added it goes away, so I must have messed something up there
He has the custom low memory profile, so that probably blocks it. He would have to enable debug asserts in the profile and recompile
How do I do that?
https://doc.rust-lang.org/cargo/reference/profiles.html#debug-assertions
I think you just add debug-assertions = true
under the profile on cargo.toml. of course this will lead to a full recompile.
So will be really slow
Ok, I've finally narrowed down the issue. This fails with the previously mentioned error:
main : Task {} []
main =
_ <- Task.await (Pca9685.setPinOffTicks 0x0040 1 500)
_ <- Task.attempt (Pca9685.setPrescale 0x0040 121)
Task.succeed {}
But if I comment out either of the lines with the Pca9685
call then it works, it just doesn't seem to like them both in the same file.
Suuupuer weird, any idea why that might be?
what do setPinOffTicks
/setPrescale look like?
Could you try running with ROC_PRINT_IR_AFTER_SPECIALIZATION=1
and dump what you get out into a gist? that might help too
Here's the code for those @Ayaz Hafiz
https://github.com/Billzabob/roc-clock/blob/main/src/Pca9685.roc#L18-L31
I'll add the debug-assertions to my Roc build and try that flag. Could be a bit though since it usually takes almost an hour to compile from scratch
CBE7FB8F-1A19-4529-BD66-95C3DF8641FF.jpg
Is this useful?
Guessing this means something is messed up in my I2c module?
Yes, that’s super useful!! Nice, thanks!
Not sure if this helps Ayaz, but I was able to finally figure out that it seemed to be caused by a call to Task.fromResult
. I changed it from this:
# ...
bytes <- await (I2c.readBytes address 1)
Task.fromResult (List.get bytes 0)
To just doing this for now:
#...
bytes <- await (I2c.readBytes address 1)
when bytes is
[h, ..] -> h
_ -> 0
It's obviously not as good this way, but it gets me past this bug for now and hopefully gives you some more useful info.
Thanks Nick. I have a hypothesis for what this is, will try to validate it later in the week. Thanks for all for your help here and work through the compiler bugs!
Last updated: Jul 05 2025 at 12:14 UTC