Jeff Gulbronson
08/31/2018, 4:47 PM@ExperimentalContracts
fun String?.trueIfNotNullOrEmpty(): Boolean {
contract {
returns(true) implies (this@trueIfNotNullOrEmpty != null)
}
return !isNullOrEmpty()
}
@ExperimentalContracts
fun foo() {
val maybeNull : String? = "foo"
val isNotNull = maybeNull.trueIfNotNullOrEmpty()
if (isNotNull) {
val definitelyNotNull : String = maybeNull
}
}
Intellij is saying I can’t assign maybeNull
to definitelyNotNull
, because it’s String
vs String?
. My contract seems right, it’s really just the inverse of what isNullOrEmpty
uses. Any idea where I went wrong? Sorry in advance if it’s blindingly obvious.dsavvinov
08/31/2018, 4:54 PMmaybeNull.trueIfNotNullOrEmpty()
into plain maybeNull != null
, and you still won't get smartcast.
Here's an issue for that: https://youtrack.jetbrains.com/issue/KT-25747Jeff Gulbronson
08/31/2018, 5:01 PMmaybeNull != null
wouldn’t work.
Interestingly I changed the contract to
contract {
returns(true) implies (this@trueIfNotNullOrEmpty is String)
}
And still no good, though I would’ve expected this one to work. I suppose contracts are new so I’m not 100% sure what should work and what shouldn’t.dsavvinov
08/31/2018, 5:34 PMisNull
. Compiler has to check that this boolean is initialized to something special, and keep in mind that if isNull == true
then maybeNull != null
(or maybeNull is String
, actual kind of smartcast is irrelevant). We don't do that at the moment
(sorry if I got you wrong -- if you've inlined isNull
variable and still don't get smartcast, then the issue is somewhere else. If you'll show complete code, we can continue digging here :) )Jeff Gulbronson
08/31/2018, 8:01 PMJeff Gulbronson
08/31/2018, 8:02 PMval
Jeff Gulbronson
08/31/2018, 8:03 PM