Do not use dispatch receiver type when calculating method owner

Motivation of using dispatch receiver type when calculating method owner
was discussed here: https://github.com/JetBrains/kotlin/pull/3054

However, this is incompatible with type erasure of non-reified type
parameters on inlining (which will be done in future). Consider the
code:

```
inline fun <T> f(arr:  Array<T>, p: (T) -> Int): Int = p(arr[0])
fun box() = f(arrayOf("abacaba"), String::length)
```

After inlining and erasure, the type of `arr[0]` is `Any`. Thus, when
calculating owner of `String::length` we would have `Any` instead of
`String` if we used dispatch receiver type.

Note, that this change affects bytecode instruction that invokes
method, but does not change which method is being invoked.
This commit is contained in:
vladislav.grechko
2023-07-27 18:20:40 +02:00
committed by Space Team
parent ca80ddb8ca
commit 44caa3cdd5
3 changed files with 6 additions and 9 deletions
@@ -398,12 +398,7 @@ class MethodSignatureMapper(private val context: JvmBackendContext, private val
// TODO get rid of 'caller' argument
fun mapToCallableMethod(expression: IrCall, caller: IrFunction?): IrCallableMethod {
val callee = expression.symbol.owner
val calleeParent = expression.superQualifierSymbol?.owner
?: expression.dispatchReceiver?.type?.classOrNull?.owner?.let {
// Calling Object class methods on interfaces is permitted, but they're not interface methods.
if (it.isJvmInterface && callee.isMethodOfAny()) context.irBuiltIns.anyClass.owner else it
}
?: callee.parentAsClass // Static call or type parameter
val calleeParent = expression.superQualifierSymbol?.owner ?: callee.parentAsClass
val owner = typeMapper.mapOwner(calleeParent)
val isInterface = calleeParent.isJvmInterface