I am building an extension function on KProperty1
. The function needs to accept an argument that extends the value type of property (R
), even though KProperty1
is covariant in the type parameter R
.
A slightly contrived example would be the following, though my use is more legitimate.
data class Data(val value: String)
fun <V> KProperty1<*, V>.setMagically(value: V) {
this.javaField?.set(null, value)
}
fun test() {
// I would like this to fail to compile
Data::value.setMagically(190)
}
It would seem that the compiler is inferring the type Any
for R
, which is totally valid, since KProperty1<*, String> : KProperty1<*, Any>
What I want is to say that for my particular case, I actually want V
to be invariant. I know you can use out
and in
as variance wideners, but I was unable to figure out how to specify that I want to override the covariant annotation on KProperty1
with invariance for this case.
It's worth noting that it works great with KMutableProperty1
, since that's invariant in R
. But my code needs to work with non-mutable properties as well.
For context, I'm building something that generates database queries, which is why I need the value to be a subclass of the property type, even though I'm not actually writing to the property, but this question is more general than my specific, property-handling case.
This is currently not possible in Kotlin. In fact, there is an internal annotation which enables this behavior (causes the compiler to report an error, if Any
is inferred although nowhere at the call site was it mentioned) and it's used in several places in kotlin-stdlib
, but using it outside of the standard library is still discouraged.
We have plans to make this annotation public. For more details, please check out KT-13198.