# When expression on sealed interface requires unnecessary branches

**URL:** <https://discuss.kotlinlang.org/t/when-expression-on-sealed-interface-requires-unnecessary-branches/26143>\
**Category:** Support\
**Created:** [December 27, 2022, 2:34pm UTC](https://discuss.kotlinlang.org/t/when-expression-on-sealed-interface-requires-unnecessary-branches/26143 "2022-12-27T14:34:37Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![thumannw](https://avatars.discourse-cdn.com/v4/letter/t/3e96dc/32.png) [@thumannw](https://discuss.kotlinlang.org/u/thumannw)\
**Post date:** [December 27, 2022, 2:34pm UTC](https://discuss.kotlinlang.org/t/when-expression-on-sealed-interface-requires-unnecessary-branches/26143/1 "2022-12-27T14:34:37Z")

</div>

Consider the following split of a union model into interface and implementation:

```kotlin
sealed interface Model
interface Case0 : Model
interface Case1 : Model

sealed class ModelImpl : Model
object Case0Impl : ModelImpl(), Case0
object Case1Impl : ModelImpl(), Case1

fun createModel(): Model = Case0Impl

```

And here comes the usage:

```kotlin
fun main() {
    val model: Model = createModel()
    val res = when(model) {
        //...
    }
    println(res)
}

```

The when expression must be exhaustive. When triggering completion in IJ, it will insert the following branches:

```kotlin
val res = when(model) {
    is Case0 -> TODO()
    is Case1 -> TODO()
    Case0Impl -> TODO()
    Case1Impl -> TODO()
}

```

But the last two branches matching on the implementation can never be reached. When removing them, IJ is complaining with a non-exhaustive error (but it should be because Model and ModelImpl is sealed). It gets even worse when making the implementation classes private in the file. Then it seems to be impossible to write a non-trivial exhaustive when expression without else branch.

Is this a bug or am I missing something?

---

<div class="post-metadata">

**Author:** ![chipays](https://avatars.discourse-cdn.com/v4/letter/c/ad7895/32.png) [@chipays](https://discuss.kotlinlang.org/u/chipays)\
**Post date:** [December 27, 2022, 3:34pm UTC](https://discuss.kotlinlang.org/t/when-expression-on-sealed-interface-requires-unnecessary-branches/26143/2 "2022-12-27T15:34:51Z")

</div>

Seems to be a shortcoming of the compiler.

Consider the following code, which compiles without error:

```kotlin
sealed interface Model
interface Case0 : Model
interface Case1 : Model

object Case0Impl : Case0
object Case1Impl : Case1

val res = when(model){
    is Case0 -> TODO()
    is Case1 -> TODO()
}

```

However, this code will not compile, stating when is not exhaustive:

```auto
sealed interface Model
interface Case0 : Model
interface Case1 : Model

object Case0Impl : Model, Case0
object Case1Impl : Model, Case1

val res = when(model){
    is Case0 -> TODO()
    is Case1 -> TODO()
}

```

As such, it seems the compiler will only accept exhaustive when branches that have cases for all classes that **directly implement** a sealed class or interface.

We can prove this by introducing an extra, unnecessary check for `ModeImpl`:

```kotlin
val res = when(model){
    is Case0 -> TODO()
    is Case1 -> TODO()
    is ModelImpl -> TODO()
}

```

---

<div class="post-metadata">

**Author:** ![thumannw](https://avatars.discourse-cdn.com/v4/letter/t/3e96dc/32.png) [@thumannw](https://discuss.kotlinlang.org/u/thumannw)\
**Post date:** [December 27, 2022, 7:32pm UTC](https://discuss.kotlinlang.org/t/when-expression-on-sealed-interface-requires-unnecessary-branches/26143/3 "2022-12-27T19:32:35Z")

</div>

Thanks for the simplified reproducer. I created an issue here: [https://youtrack.jetbrains.com/issue/KT-55658](https://youtrack.jetbrains.com/issue/KT-55658)

---

<div class="post-metadata">

**Author:** ![arocnies](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/arocnies/32/5143_2.png) [@arocnies](https://discuss.kotlinlang.org/u/arocnies)\
**Post date:** [December 27, 2022, 8:41pm UTC](https://discuss.kotlinlang.org/t/when-expression-on-sealed-interface-requires-unnecessary-branches/26143/4 "2022-12-27T20:41:35Z")

</div>

Here’s a runnable example if anyone is interested.

```run-kotlin
sealed interface Model
interface Case0 : Model
interface Case1 : Model

// Try uncommenting to see error
object Case0Impl : Case0 //, Model
object Case1Impl : Case1 //, Model

fun main() {
    val model: Model = Case0Impl
    val res = when(model){
        is Case0 -> "1"
        is Case1 -> "2"
    }
    println(res)
}

```
