I'm currently debugging this issue: https://github.com/roc-lang/roc/issues/6799
To that moment I found that there's nothing was exposed to host (LayoutProblem::Erroneous
for pf..mainForHost
is the root cause. If the main function has invalid types, it doesn't end up in host_specializations
), so no specializations as a result. Then, during alias analysis, we read bytes from an invalid position, expecting there's a function name, which leads to the arbitrary string in the logs #\x00\x00\x00\x00\x00\x00\x00z\x87\xceV\x11\xaaYs
Shouldn't we fail even sooner when find nothing was exposed? And then again if no specializations were fond?
As for the fix: should we generate fake specialization in this case? Or just skip alias analysis if no specializations were found?
Aside: I don't understand most of what I just said tbh :grinning_face_with_smiling_eyes: so here are some additional questions:
pf..mainForHost
is smth added at compile-time? what's the intuition for this function?morphic_lib
and why?I can answer some of those
mainForHost
is just the main function of the platform. In the early days we called this mainForHost and for most platforms this just stuck around. It's not a special name.
there is probably some technical difference between specialization and monomorphization, but we use them interchangeably. They get rid of some form of generics in some way.
alias analysis is trying to insert in-place mutation where it judges that that is safe, much like how when the reference count is one at runtime, or when you have a mutable reference in rust, when the compiler can determine that there is only one "user" of a value at compile time, then it can turn various (mostly list and string) operations into their in-place variants. This would happen anyway at runtime because of the refcount, but now it saves a branch and potentially allows for more optimizations
now, this final one is tricky. we use morphic lib (based on unpublished research that we got to play with) for alias analysis. However, it requires that we have a first-order language (no higher-order functions). That is in part what our lambda set approach is for (and it was developed by the same folks as morphic). But now that lambda sets just prove really hard in practice and we might want to - for now - go with a different approach, morphic can no longer be used either. That is sad but given * gestures widely * is probably the right move.
I think UserApp
and mainForHost
I mentioned are from here: https://github.com/roc-lang/roc/blob/f8c6786502bc253ab202a55e2bccdcc693e549c8/crates/compiler/alias_analysis/src/lib.rs#L25-L31
ah, those are there just for modelling of the alias analysis, they have no relation to the actual generated code.
the alias analysis needs an entry point, and we can't just pick the real main because of host-exposed closures and expects (which kind of act as independent entry points for this analysis). So we bundle everything together into one fake module, and call all entry points from a fake entry point function.
again, this has no effect on codegen, it's just for alias analysis
it's a mono problem. mainForHost
of the cli platform gets main
from the app. mainHost
is an entry point. But when a type mismatch is introduced in main
, it fails monomorphization. It's as simple as
app [main] {
pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.10.0/vNe6s9hWzoTZtFmNkvEICPErI9ptji_ySjicO6CkucY.tar.br",
}
main = 42
Interesting it even gets to mono and panics there? Shouldn't it fail type checking before ever getting to mono? Type variables are confusing it somehow?
It panics during alias analysis because no specializations were resolved or smth like that. I mean, the monomorphized module passed to alias analysis has no procedures.
It must be connected with InLayout(Error)
but I don’t understand the code yet
Last updated: Jul 06 2025 at 12:14 UTC