0

I am trying to smart cast an Option from any Any variable so that I can determine if the Option is empty however the IDE is indicating that Option<*> could not be smart cast because it is declared in a different module.

fun hasEmptyValue(column: Pair<String, Any>): Boolean = when {
    column.second is Option<*> -> column.second.isEmpty()  
    else -> false
}
Mark Ashworth
  • 164
  • 12

2 Answers2

2

The following causes smartcast to work for me:

fun hasEmptyValue(column: Pair<String, Any>): Boolean {
    val second = column.second
    return when (second) {
        is Option<*> -> second.isEmpty() //Smart cast to arrow.core.Option<*>
        else -> false
    }
}

The explanation for why a smart cast across modules is not allowed is on the Jetbrains issue tracker here:

A smart cast is only valid when multiple accesses of the same property are guaranteed to return the same value. If the property being accessed is defined in a different module from the access location, the module containing the property can be recompiled separately from the module where it’s accessed, breaking the key requirement of the smart cast. Therefore, cross-module smart casts are not allowed.

David Rawson
  • 20,912
  • 7
  • 88
  • 124
2

David Rawson shows how to fix it, but doesn't explain why your code doesn't work.

The reason is that column.second could in principle return different values for two calls; even though Pair#second is a val, it could have a custom getter method.

If Pair was in the same module, the compiler could check this, but for other modules it doesn't.

Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487
  • Thank you Alexey for explaning the reason for the error. – Mark Ashworth Jul 09 '18 at 11:31
  • 1
    Here you have a discussion into the Kotlin community about it, they explain the same that Alexey Romanov said. In that case, the question was about an smart casting from another module into the app. https://discuss.kotlinlang.org/t/what-is-the-reason-behind-smart-cast-being-impossible-to-perform-when-referenced-class-is-in-another-module/2201 – Jc Miñarro Jul 10 '18 at 09:41