mercredi 8 novembre 2017

Force type parameter to be invariant when it has `out` declaration-site variance

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() {
    // This should fail to compile, but it compiles fine
    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.





Aucun commentaire:

Enregistrer un commentaire