GALA-E0018 — Sealed variant type parameter cannot be inferred

What it means. A zero-argument constructor of a generic sealed type is used somewhere the parent type’s parameter cannot be pinned. The transpiler checks three signals before giving up:

  1. The enclosing match subject’s type (cmd match { case NoCmd() => … }).
  2. The enclosing function’s declared return type, when that type is concrete (Box[int]).
  3. A val / var type annotation supplying an expected type.

If none of those resolve the parameter, generated Go would contain a bare Variant{} literal whose type argument Go cannot deduce — producing an obscure cannot infer T far from the GALA source.


Code that triggers it

package main

sealed type Box[T any] {
    case Empty()
}

func main() {
    val x = Empty()   // no annotation, no enclosing type — T is unbound
    Println(x)
}

Compiler message

error[GALA-E0018]: cannot infer type parameter for sealed variant constructor "Empty()"
  --> e0018.gala:8:18
  |
8 |     val x = Empty()
  |                  ^ annotate the binding
  |
  = hint: annotate the binding (e.g. `val x Box[int] = Empty()`) or pass type args explicitly (`Empty[int]()`)

The hint is built from the variant’s own parent type, so it names the exact annotation to paste in.


How to fix it

Give the parameter a home. Annotate the binding:

val x Box[int] = Empty()

…or instantiate the constructor explicitly:

val x = Empty[int]()

When the constructor is an arm of a match against a value of the parent type, or the body of a function whose declared return type is concrete, the signal is already present and no annotation is needed:

func emptyInts() Box[int] = Empty()   // the concrete return type pins T

A generic return type does not count as a signal. func empty[T any]() Box[T] = Empty() still reports GALA-E0018, because T is itself unbound at the constructor — there is nothing to pin. Pass the argument explicitly (Empty[T]()) in that case.


Why the rule exists

GALA’s downward inference relies on a single expected-type signal flowing from the enclosing context. When that signal is absent, the transpiler would otherwise fall through to an untyped composite literal and let Go deduce — which fails confusingly and far from the source. Failing fast, with a hint naming the three resolving signals, points at the cheapest fix.

Scope. Only zero-argument constructors of generic sealed types. Variants of non-generic sealed types, and constructors whose arguments contribute to inference, are unaffected.