Hi all, I've been really enjoying using roc but I'm getting stuck on this error. Any tips would be appreciated.
Sms auth abstraction
https://github.com/crvouga/moviefinder.app/blob/main/src/Auth/VerifySms.roc
module [VerifySms, SendCode, VerifyCode]
import pf.Task exposing [Task]
import PhoneNumber exposing [PhoneNumber]
SendCode : { phoneNumber : PhoneNumber } -> Task {} []
# Works
VerifyCode : { phoneNumber : PhoneNumber, code : Str } -> Task {} []
# roc check works but roc run errors
# VerifyCode : { phoneNumber : PhoneNumber, code : Str } -> Task {} [WrongCode]
VerifySms : {
sendCode : SendCode,
verifyCode : VerifyCode,
}
Shared Ctx module for dependency injection
https://github.com/crvouga/moviefinder.app/blob/main/src/Ctx.roc
module [Ctx]
import Auth.VerifySms
import Media.MediaDb
import Logger
import Request
Ctx : {
verifySms : Auth.VerifySms.VerifySms,
mediaDb : Media.MediaDb.MediaDb,
logger : Logger.Logger,
req : Request.Request,
}
Usage
https://github.com/crvouga/moviefinder.app/blob/main/src/Auth/Login.roc#L35
clickedVerifyCode : Ctx.Ctx, PhoneNumber.PhoneNumber -> Task.Task Response.Response []
clickedVerifyCode = \ctx, phoneNumber ->
verifiedCode <- ctx.verifySms.verifyCode { phoneNumber, code: "123" } |> Task.attempt
when verifiedCode is
Ok _ ->
Login VerifiedCode |> Response.redirect |> Task.ok
Err _ ->
(Login (VerifyCode { phoneNumber, error: "Something went wrong" })) |> Response.redirect |> Task.ok
The problem is that when I change the type alias for VerifyCode from
VerifyCode : { phoneNumber : PhoneNumber, code : Str } -> Task {} []
to
VerifyCode : { phoneNumber : PhoneNumber, code : Str } -> Task {} [WrongCode]
I get this error when running the app.
thread 'main' panicked at crates/compiler/gen_llvm/src/llvm/build.rs:5764:19:
Error in alias analysis: error in module ModName("UserApp"), function definition FuncName("6\x00\x00\x00\x0c\x00\x00\x00*\x0c\xe1\x82i\x99\x93m"): expected type 'union { ((),), ((),) }', found type '()'
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
When I remove the usage of the ctx.verifySms.verifyCode function then this error goes away. I've tried a couple things like removing the dependency injection and adding more type annotations.
I'm sure I can get this to eventually work but does anyone have any tips to debug this or fix this? Thanks
Here's a link to the full code: https://github.com/crvouga/moviefinder.app
I've hit something similar recently, but don't have a fix/workaround.
I think we have a type simplification bug. Cause, if I understand correctly, a union of empty tuples is the same thing as an empty tuple.
So those types actually should be considered the same.
Gives me an idea of something to test in the compiler for fixing, but I'm not sure I'll have access to try anything until at least Friday.
Does adding a _
after the return error type help?
VerifyCode : { phoneNumber : PhoneNumber, code : Str } -> Task {} [WrongCode]_
It's not pretty, but maybe you could use just a Str
as the error type.
Or a *
or an empty record {}
as the error type
Just some ideas to try different things. Ideally we could minimise and resolve the type bug.
@Luke Boswell I've tried using _
, *
, Str
, and {}
. All (if I remember correctly) having the same or similar
error. I haven't tried [WrongCode]_
yet. I'll report back here if that works. If all else fails I'll definitely make minimal example
I'm gonna be procrastinating on this bug for awhile while I'm buildin other things in the app. I'll be sure to post here if I solve it.
I found what was causing the bug. It looks like roc wasn't liking calling function with a return type of Task.Task {} *
in middle of the verifySms function after adding the WrongCode error.
So when the verifySms alias is VerifyCode : { phoneNumber : PhoneNumber, code : Str } -> Task {} [WrongCode]
Removing these functions Logger.info
and Sleep.millis
within the verifySms implementation resolved the error.
When the verifySms alias is VerifyCode : { phoneNumber : PhoneNumber, code : Str } -> Task {} []
calling the
Logger.info
and Sleep.millis
within the verifySms implementation works
VerifySms implementation:
module [Config, init]
import pf.Task exposing [Task]
import pf.Sleep
import Logger
import PhoneNumber
import Auth.VerifySms
Config : {
code : Str,
logger : Logger.Logger,
}
sendCode : Config -> Auth.VerifySms.SendCode
sendCode = \config -> \{ phoneNumber } ->
Logger.info! config.logger "Sending code $(config.code) to phone number $(PhoneNumber.toStr phoneNumber)"
Sleep.millis! 1000
Task.ok {}
verifyCode : Config -> Auth.VerifySms.VerifyCode
verifyCode = \config -> \input ->
# Commenting out these two lines resolved the error
# Logger.info! config.logger "Verifying code $(input.code) for phone number $(PhoneNumber.toStr input.phoneNumber)"
# Sleep.millis! 1000
if input.code != config.code then
Task.ok {}
else
Task.ok {}
init : Config -> Auth.VerifySms.VerifySms
init = \config -> {
sendCode: sendCode config,
verifyCode: verifyCode config,
}
Last updated: Jul 06 2025 at 12:14 UTC