Stream: bugs

Topic: Where constraint alias with unbound argument fails to unify


view this post on Zulip Jonathan (Aug 20 2026 at 18:44):

(roc release-fast-24f0b476)
If you introduce an alias and use it in a where clause such that its argument is phantom (it is not pinned by other arguments or the return type) it fails to unify.
If you inline the constraint it compiles fine (#3), and if the argument in the alias is grounded it also compiles (#2)

#
#   ── ✗ type mismatch ─ Repro.roc:
#   phantom_alias : a -> {} where [a.Conv(b)]
#                                  ^^^^^^^^^
#   It has the type:    b
#   But you are trying to use it as:    b
Repro :: [].{
    a.Conv(b) :  where [a.conv : a -> b]

    # 1. Aliased with phantom `b`
    phantom_alias : a -> {} where [a.Conv(b)] # Error
    phantom_alias = |x| {
        _ = x.conv()
        {}
    }

    # 2. Aliased, but `b` is grounded in the return type
    grounded : a -> b where [a.Conv(b)] # Compiles
    grounded = |x| x.conv()

    # 3. Inline equivalent of #1
    phantom_inline : a -> {} where [a.conv : a -> b] # Compiles
    phantom_inline = |x| {
        _ = x.conv()
        {}
    }
}

view this post on Zulip Jonathan (Aug 20 2026 at 18:56):

Shared here as an experience report because this popped up as I was trying to wrap some basic-cli sqlite into a utility library to handle a specific database for a project. I made the library depend on basic-cli sqlite in all but name, as it is coupled to requiring the execute!, query_many! etc. functions. This means that I can put the decoders and validation in the library and my scripts can just insert and get, without having to pass in the wrapped effects for each script.

The downside is this means very long signatures that must be typed out for static dispatch. In trying to alias them and some of the constraints, I found that I couldn't alias the requirement to have query_many! available because query_many requires a decoder, and because my library handles the decoding, the type arguments for this decoding function don't appear in either the wrapped function arguments or return value, triggering the above bug.

view this post on Zulip Anton (Aug 21 2026 at 17:22):

I am looking at this

view this post on Zulip Anton (Aug 21 2026 at 17:28):

Nice and small fix: PR#10894


Last updated: Sep 03 2026 at 15:16 UTC