[SOLVED] Improved exhaustiveness checks for when expressions with sealed classes in Kotlin 2.1.0

My company code moved finally up to Kotlin 2.1.0 (yay!) and I wanted to give a quick demo of the new features. The else branch in when when it was logically not needed was always bothering me, so I’m glad there is some improvement. However, this seems to work only one level deep:

// Kotlin 2.1.0
sealed interface Animal {
    interface Bird: Animal
    class Raven: Bird
    class Hawk: Bird
    interface Mammal: Animal
    class Lion: Mammal
    class Panda: Mammal
}

fun main() {
    val animal: Animal = listOf(Raven(), Hawk(), Lion(), Panda()).shuffled().first()
    println("selected ${animal.javaClass.simpleName}")

    when(animal) {
        is Bird -> println("flies")
        is Lion -> println("roars")
        is Panda -> println("eats shoots and leaves")
        // wants still an else branch...
    }
}

The code works as advertised when there is a Mammal branch instead of the sub class branches of Mammal, which is already a huge step in the right direction, but I don’t get why the problem wasn’t solved completely when they were already working on it. It doesn’t seem to be too difficult, right?

What are your thoughts?

Bird and Mammal can both be implemented by classes outside your module. What you actually want is to make them both sealed interfaces as well, then the code works as you expect

3 Likes

Maybe I’m missing something, but I thought you only needed to cover all cases when when is used as an expression. If it’s just used as a statement, I thought the compiler didn’t care if you cover all branches or not.

Thank you, that makes sense. I made somehow the wrong assumption that a class inside a sealed class is automatically sealed itself.

1 Like

It’s a new change!

Oh actually I do think I remember seeing something about this… not sure I love this change, but oh well.