Skip to content

Exhaustiveness and lowering

A default arm matches every value not matched by an earlier arm. Arms are evaluated top to bottom; the first matching pattern with a true guard wins. An unguarded arm covers its case; a guarded arm does not.

Closed value/ref unions and enums are exhaustiveness-checked. Omitting a case without default produces a warning; default covers the remainder. A match over an abstract base whose in-assembly leaves are known is also checked as a closed hierarchy. Literal matches and matches over an open hierarchy require default to cover their open remainder.

ExhaustiveMatch = MatchWithEveryClosedCase | MatchWithDefault .

An exhaustive match whose every arm terminates satisfies definite-return analysis. A non-exhaustive match does not, even if every written arm returns. In expression position each arm yields one compatible result type.

Value-union matches lower to a tag comparison followed by payload loads; ref-union and type patterns lower to ordered CLR isinst tests; enums lower to integral dispatch; literal patterns lower to comparisons. Guards, nil patterns, and type patterns retain top-to-bottom linear order so a failing guard may continue to the next arm. Case-view bindings are binder projections and add no runtime allocation.