Kotlin Smartcast does not work for inline declaration

Viewed 72

For these classes:

open class User

class Admin(val name: String) : User()


This compiles:

fun main1() {
    val user: User
    user = Admin("John")
    user.name
}

This does not compile:

fun main2() {
    val user: User = Admin("John")
    user.name  // "Unresolved reference: name"
}


The only difference is whether to split declaration and initialization. Why is the compiler allowed to smartcast user to Admin in the first scenario but not in the second scenario?

1 Answers

This looks like intended behavior in my opinion. While in short code sample this is not confusing, if variable is declared as User it implies that class is being used and not one of its descendants.

In first example smart cast works within function scope. In second it doesn't even attempt to evaluate assigned type since field is already explicitly typed.

Consider following example to visualize why main1 compiles:

fun main(){
   val user : User
   if(condition) {
        user = Admin("Jon")
        user.name     // smart cast to "Admin" within if branch scope
   } else {
        user = User()
   }
   user.name // unresolved
}
Related