What it means. A match expression on a sealed type omits one or more variants, or covers one only in part, 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"
}
A variant counts as covered only when its cases match every value of its fields. Some(0) matches only one Some, and a case with an if guard covers nothing, since its guard may be false. The missing list then names the variant as Some(...):
package main
func describe(o Option[int]) string = o match {
case Some(0) => "zero"
case None() => "none"
}
func main() {
Println(describe(Some(3)))
}
error[GALA-E0002]: non-exhaustive match: missing cases: Some(...)
--> main.gala:4:5
|
4 | case Some(0) => "zero"
| ^^^^ add the missing variant cases, or add a `case _ => ...` defa…
|
= hint: add the missing variant cases, or add a `case _ => ...` default to cover them
Cover the rest of the variant with a case that matches all of it, such as case Some(_) => "other". Nested patterns count together: Some(Some(_)), Some(None()) and None() cover every Option[Option[int]].
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.