# Why can't sealed class be exhausted with upper bound generics?

**URL:** <https://discuss.kotlinlang.org/t/why-cant-sealed-class-be-exhausted-with-upper-bound-generics/9077>\
**Category:** Uncategorized\
**Created:** [August 16, 2018, 9:45am UTC](https://discuss.kotlinlang.org/t/why-cant-sealed-class-be-exhausted-with-upper-bound-generics/9077 "2018-08-16T09:45:53Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![wumo](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/wumo/32/3831_2.png) [@wumo](https://discuss.kotlinlang.org/u/wumo)\
**Post date:** [August 16, 2018, 9:45am UTC](https://discuss.kotlinlang.org/t/why-cant-sealed-class-be-exhausted-with-upper-bound-generics/9077/1 "2018-08-16T09:45:53Z")

</div>

See the code below:

```auto
sealed class A
class B : A()
class C : A()

fun <T : A> f(a: T): T {
  return when (a) {//Error: 'when' expression must be exhaustive, add necessary 'else' branch
    is B -> a
    is C -> a
  }
}

```

`a ` is of type `T` which is upper bounded by `A`, so a’s type should be subset of `B` and ‘C’, why the compiler still complains about exhaustiveness?

---

<div class="post-metadata">

**Author:** ![tieskedh](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/tieskedh/32/2816_2.png) [@tieskedh](https://discuss.kotlinlang.org/u/tieskedh)\
**Post date:** [August 16, 2018, 12:52pm UTC](https://discuss.kotlinlang.org/t/why-cant-sealed-class-be-exhausted-with-upper-bound-generics/9077/2 "2018-08-16T12:52:47Z")

</div>

probably because of the same reason the following code doesn’t work:

```
class A
fun <T : A> f(foo : T){
    val i = when(foo){
        is A -> 1
    }
}

```

thx @fatjoe79 for pointing out that my speculation below is not true.

My speculation:  
Generics only exist at compile-time and not at runtime (at runtime they are replaced with `Any?`).  
Probably the check if the when is exhaustive is done after the generics are replaced with `Any?`?

---

<div class="post-metadata">

**Author:** ![fatjoe79](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/fatjoe79/32/4221_2.png) [@fatjoe79](https://discuss.kotlinlang.org/u/fatjoe79)\
**Post date:** [August 16, 2018, 12:54pm UTC](https://discuss.kotlinlang.org/t/why-cant-sealed-class-be-exhausted-with-upper-bound-generics/9077/3 "2018-08-16T12:54:46Z")

</div>

But in this case the generic parameter is not erased to Any? Because of the upper bound it will be erased to A, won’t it?

In any way, we are talking about a compile-time error. It should be possible to evaluate this error BEFORE generics are erased.

All in all I believe it should be possible to fix this theoretically. But I don’t know how complicated it is to do.

---

<div class="post-metadata">

**Author:** ![gidds](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/gidds/32/10865_2.png) [@gidds](https://discuss.kotlinlang.org/u/gidds)\
**Post date:** [August 16, 2018, 3:41pm UTC](https://discuss.kotlinlang.org/t/why-cant-sealed-class-be-exhausted-with-upper-bound-generics/9077/5 "2018-08-16T15:41:45Z")

</div>

Even stranger: if you add a third ‘`is A -> a`’ branch to the `when`, then the compiler recognises that that condition is always true, but _still_ complains that it’s not exhaustive!

---

<div class="post-metadata">

**Author:** ![noo.blaster](https://avatars.discourse-cdn.com/v4/letter/n/ac91a4/32.png) [@noo.blaster](https://discuss.kotlinlang.org/u/noo.blaster)\
**Post date:** [August 17, 2018, 8:54am UTC](https://discuss.kotlinlang.org/t/why-cant-sealed-class-be-exhausted-with-upper-bound-generics/9077/6 "2018-08-17T08:54:49Z")

</div>

Casting to A works as a workaround (if you really need this):

```auto
sealed class A
class B : A()
class C : A()

fun <T : A> f(a: T): T {
  return when (a as A) {
    is B -> a
    is C -> a
  }
}

```

I think the compiler does not treat a as a A when you use upper bound (btw, you can have several upperbound so its more complex).

This is a minor compiler bug to me (and it looks like likned to type erasure).

---

<div class="post-metadata">

**Author:** ![Raman.Gupta](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/raman.gupta/32/1834_2.png) [@Raman.Gupta](https://discuss.kotlinlang.org/u/Raman.Gupta)\
**Post date:** [February 10, 2022, 8:18pm UTC](https://discuss.kotlinlang.org/t/why-cant-sealed-class-be-exhausted-with-upper-bound-generics/9077/7 "2022-02-10T20:18:07Z")

</div>

Sorry to bump an old topic, but for reference, vote for [https://youtrack.jetbrains.com/issue/KT-21908](https://youtrack.jetbrains.com/issue/KT-21908) to fix this issue.
