Generic parameter use-site invariance modifier


#1

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 reasonable.

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.


#2

I also posted this question on Stack Overflow: https://stackoverflow.com/questions/47191898/force-type-parameter-to-be-invariant-at-use-site-when-it-is-covariant-at-declara