https://kotlinlang.org logo
Title
s

spand

12/04/2019, 8:25 AM
Is there a particular reason objects cannot be autocast in this case:
sealed class Sc {
    object Foo : Sc()
}

fun (sc: Sc){
    when (sc){
        Sc.Foo -> sc // <-- type is still Sc here, not Foo
    }
}
Seems like a basic case but I couldnt even find an issue on youtrack about it
j

Jaymin.Kim

12/04/2019, 8:28 AM
how about
is Sc.Foo -> sc
?
s

spand

12/04/2019, 8:29 AM
Yes that is one way to fix it.. but it seems silly to have an expensive instance check instead of simple equality
j

Jaymin.Kim

12/04/2019, 8:31 AM
strange...
if (sc == Sc.Foo)
not working
if (sc === Sc.Foo)
working
d

dmitriy.novozhilov

12/04/2019, 8:32 AM
equals
can be overriden, so equality doesn't guarantees that
sc
is really
Sc.Foo
sealed class Sc {
    object Foo : Sc() {
        fun bar() {}
    }

    class FakeFoo : Sc() {
        override fun equals(other: Any?): Boolean {
            return true
        }
    }
}
fun foo(){
    val sc: Sc = Sc.FakeFoo()
    
    when (sc) {
        Sc.Foo -> sc
    }
    // this when is equal to such if 
    //   where `equals` is called
    if (sc == Sc.Foo) { // it's true
        sc
    }
}
d

diesieben07

12/04/2019, 8:36 AM
Also "instanceof is expensive" is a myth, at least on the JVM.
s

spand

12/04/2019, 8:36 AM
Ah yes. Makes sense except that doesnt when assume it isnt ? How else would it assert the exhaustiveness ?
k

Kroppeb

12/04/2019, 8:53 AM
If you know it's the object, then you can just use
Sc.Foo
instead of
sc
as a fix.
s

spand

12/04/2019, 8:56 AM
I have created a ticket about it: https://youtrack.jetbrains.com/issue/KT-35269