I am trying to convert the functions read
and write
in my library to operator functions get
and set
, respectively. My functions use a reified generic type, they are also inline methods. (You can see my library here.)
The compiler has no issue letting me pass and I don't see why using non-operator functions the inference works just fine, yet using operators fails at runtime.
Exception in thread "main" java.lang.UnsupportedOperationException: This function has a reified type parameter and thus can only be inlined at compilation time, not called directly.
at kotlin.jvm.internal.Intrinsics.throwUndefinedForReified(Intrinsics.java:173)
at kotlin.jvm.internal.Intrinsics.throwUndefinedForReified(Intrinsics.java:167)
at kotlin.jvm.internal.Intrinsics.reifyJavaClass(Intrinsics.java:201)
The code is as follows:
operator inline fun <reified T> get(address: Long): T {
...
}
operator inline fun <reified T> get(address: Int): T = get(address.toLong())
operator inline fun <reified T> set(address: Long, data: T) {
...
}
operator inline fun <reified T> set(address: Int, data: T): Unit = set(address.toLong(), data)
The interesting part is that I can do this with infix functions just fine, for example:
class Example { infix inline fun <reified T> foo(bar: Int) = Any() as T }
fun main(args: Array<String>) {
val example = Example()
val foobar: Any = example foo 12345
}
I can also do this with other operators, for example both of these work:
operator inline fun <reified T> minus(bar: Int) = foo<T>(bar)
operator inline fun <reified T> plus(bar: Int) = foo<T>(bar)
I also noticed that even invoke
works correctly! This is strange since it seems both invoke
and get
would have identical implementations.
operator inline fun <reified T> invoke(bar: Int) = foo<T>(bar)
But if I add the following function to example: operator inline fun <reified T> get(bar: Int) = foo<T>(bar)
and then try the following call I run into the error: val get: Any = example[12345]
It's a bug: https://youtrack.jetbrains.com/issue/KT-9211
As a workaround, use .get(...)
instead of [...]