Exhaustive when Expressions

An is branch in when (if and when) smart-casts the subject (Smart Casts), and because the compiler knows every subtype of a sealed type, it checks that the branches cover them all, with no else. Compile this function together with Sealed.kt from Sealed Interfaces, forget two cases, and the build stops.

A when that misses two subtypes, with a guard condition (Missing.kt)Kotlin
fun describe(action: CartAction): String = when (action) {
  is Add if action.quantity > 5 -> "rejected: at most 5 copies"
  is Add -> "add ${action.quantity} x book ${action.bookId}"
  is Remove -> "remove book ${action.bookId}"
}
Output
$ kotlinc Sealed.kt Missing.kt -include-runtime -d Missing.jar
Missing.kt:1:44: error: 'when' expression must be exhaustive. Add the 'Checkout', 'Clear'
  branches or an 'else' branch.
fun describe(action: CartAction): String = when (action) {
                                           ^^^^

is Add if ... is a guard condition (stable since Kotlin 2.2.0): it matches only when the type test and the condition both hold, and it never counts toward exhaustiveness, so the plain is Add must follow. Since Kotlin 1.7.0 a when statement over a sealed, enum or Boolean subject must be exhaustive too. Don't silence the error with else ->: it would swallow every subtype added later, hiding the code a new case breaks.