What it means. A match expression on a sealed type omits one or more variants and has no default (case _ =>) fallback. The compiler lists exactly which variants are missing.
package main
sealed type Color {
case Red()
case Green()
case Blue()
}
func name(c Color) string = c match {
case Red() => "red"
case Green() => "green"
// missing: Blue
}
func main() {
Println(name(Red()))
}
error[GALA-E0002]: non-exhaustive match: missing cases: Blue
--> e0002.gala:10:5
|
10 | case Red() => "red"
| ^^^^ add the missing variant cases, or add a `case _ => ...` defa…
|
= hint: add the missing variant cases, or add a `case _ => ...` default to cover them
The caret marks the start of the match arms; the header names the variants you left out.
Cover every variant explicitly:
func name(c Color) string = c match {
case Red() => "red"
case Green() => "green"
case Blue() => "blue"
}
Or add a default when the remaining variants collapse to the same result:
func name(c Color) string = c match {
case Red() => "red"
case _ => "other"
}
Sealed types exist so the compiler can verify you have thought about every variant. A silent fall-through would carry the same risk as a Go switch with a forgotten case. GALA therefore requires either full coverage or an explicit acknowledgement (case _ =>) that some variants are grouped.
This is the payoff of sealing a hierarchy: add a variant later, and every non-exhaustive match in the codebase becomes a compile error instead of a runtime surprise.