4

I'm trying to write an extension function that returns true if the value is not null or 0 and use a contract to guarantee to the compiler that if I return true, the value is non-null. However, it doesn't seem to be working with smart casting. It still won't compile when I try to pass the value into a function that takes a non-nullable Long.

I tried to compile this code and it would not work. I expected the id to be smart-casted to a Long from a Long? since the contract guarantees that if isValidId returns true then the passed in Long? is not null.

As you can see, the property is immutable, so I don't think that's the issue. I also added some more code below, because the problem appears to be specific to extension functions. It works when I pass ID as a traditional parameter.

fun test() {
    val id: Long? = null //5L
    if (id.isValidID()) {
      // It won't compile because the compiler says that id is a Long?
      // instead of smart casting it to a Long. doWithId requires a Long.
      doWithId(id) 
    }
  }

  fun doWithId(id: Long) {}

  @OptIn(ExperimentalContracts::class)
  fun Long?.isValidID(): Boolean {
    contract { returns(true) implies (this@isValidID != null) }
    return this != null && this != 0L
  }

Thanks!

EDIT: Oh! It works when it's not an extension function. Does anybody know how I can make extension functions work?

fun test() {
    val id: Long? = null
    if (isValidID(id)) {
      // This compiles now that I pass ID as a param instead of
      // passing it in an extension function.
      doWithId(id)
    }
  }

  fun doWithId(id: Long) {}

  @OptIn(ExperimentalContracts::class)
  fun isValidID(id: Long?): Boolean {
    contract { returns(true) implies (id != null) }
    return id != null && id != 0L
  }
rexar5
  • 470
  • 2
  • 10
  • 1
    Your example seems to work in [Kotlin Playground](https://pl.kotl.in/W00F34FzT). What version of Kotlin are you using? Are you targeting Kotlin/JVM, or something else? – aSemy Jan 19 '23 at 22:07
  • I am on Kotlin 1.8.20 and see the same error as OP – NSaran Aug 03 '23 at 17:04

0 Answers0