I'm struggling to use `when` with sealed classes -...
# multiplatform
r
I'm struggling to use
when
with sealed classes -- I'm getting an error about the when needing to be exhaustive... but it is? This only happens in my multiplatform code:
Copy code
sealed class Widget {
    data class Foo(val name: String) : Widget()
    data class Bar(val name: String) : Widget()

    fun example() {
        // ERROR: 'when' expression must be exhaustive, add necessary 'else' branch
        when (this) {
            is Foo -> {}
            is Bar -> {}
        }
    }
}
Any ideas?
g
Any chance you're using expect/actual with that sealed class? If so, the compiler doesn't know all subclasses at compile time (see the warning at https://kotlinlang.org/docs/sealed-classes.html#use-sealed-classes-with-when-expression).
f
Probably dumb question, is it really compile time error? I've seen this in IDEA lately but it was just a bug and it normally compiled.
r
@Gary Peck I'm not using expect/actual with this class (I'm literally seeing it with the exact code I pasted). I am using expect/actual elsewhere in the codebase though.
@Filip Wiesner Oh, you're right. It compiles. Ack.
👍 1
Except this is happening in a non-test, non-maven sourceset
I've "fixed" this error. For anyone who might stumble into this issue in the future, this is occurring when: 1. The source file lives in
commonMain/src/kotlin/
with a
package com.foo.bar
line at the top 2. The module is using the android library plugin + the kotlin multiplatform plugins, and has android and jvm targets, e.g.
kotlin { jvmToolchain(17); jvm(); androidTarget() }
3. The
android { namespace = "com.foo.bar" }
namespace is the same as the package at the top of the source file. Moving the source file into commonMain/src/kotlin/com/foo/bar/ causes the error to no longer appear. No idea why though.
👍 1
c
Ah, Android 😕 I guess it's confused because the folder names are important in Java and thus in Android?
👀 1
r
We have the same issue in an Android module which use a sealed class from a kmp lib published on maven. But the error disappears if we add the type explicitly 🤷 ko ->
when (val result = getProductDetailsUseCase(productId))
ok ->
when (val result: LBResult<ProductDetails> = getProductDetailsUseCase(productId))
In the same project, kmp modules dont have the issue with the same sealed class used.
n
Another reason why it map happen: Suppose you have file with
package com.foo.bar
in folder
src/commonMain/kotlin/Bar.kt
. And you have code generator like ksp which generates code into
build/generated/ksp/metadata/commonMain/kotlin/com/foo/bar/Bar.kt
. To fix this issue you have to create intermediate package folders in your you src code
src/commonMain/kotlin/com/foo/bar/Bar.kt
.