Is it expected that the following snippet gives me...
# getting-started
t
Is it expected that the following snippet gives me an error indicating that then when must be exhaustive? As far as I can tell, the when is exhaustive here due to the condition above it. Is this a limitation of the current compiler or am I overlooking something?
Copy code
sealed interface Base {
    data class Foo(val foo: String) : Base
    data class Bar(val bar: String) : Base
    data class Baz(val baz: String) : Base
}

fun doThing(thing: Base) {
    if (thing is Base.Foo || thing is Base.Bar) {
        when (thing) {
            is Base.Foo -> thing.foo
            is Base.Bar -> thing.bar
            // Error: When expression must be exhaustive
        }
    }
}
s
The check for exhaustiveness is confined to the
when
block itself. The
if
statement doesn’t participate in the exhaustiveness check. It could narrow the type via a smart cast, but unfortunately the common supertype of
Base.Foo
and
Base.Bar
is still
Base
, so there’s nothing to narrow it to.
In other words, the
when
block has to cover all possible values of the type of its subject. And the compile-time type of the
when
subject is
Base
.
☝️ 1
Maybe when we have union types, it will be able to work the way you’re hoping 🤞!
t
Alright, that makes sense, thanks!
s
so is
when
now exhaustive even if it's a statement!?
s