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:
committed by
Space Team
parent
ca80ddb8ca
commit
44caa3cdd5
+1
-6
@@ -398,12 +398,7 @@ class MethodSignatureMapper(private val context: JvmBackendContext, private val
|
|||||||
// TODO get rid of 'caller' argument
|
// TODO get rid of 'caller' argument
|
||||||
fun mapToCallableMethod(expression: IrCall, caller: IrFunction?): IrCallableMethod {
|
fun mapToCallableMethod(expression: IrCall, caller: IrFunction?): IrCallableMethod {
|
||||||
val callee = expression.symbol.owner
|
val callee = expression.symbol.owner
|
||||||
val calleeParent = expression.superQualifierSymbol?.owner
|
val calleeParent = expression.superQualifierSymbol?.owner ?: callee.parentAsClass
|
||||||
?: 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 owner = typeMapper.mapOwner(calleeParent)
|
val owner = typeMapper.mapOwner(calleeParent)
|
||||||
|
|
||||||
val isInterface = calleeParent.isJvmInterface
|
val isInterface = calleeParent.isJvmInterface
|
||||||
|
|||||||
+4
-2
@@ -20,8 +20,10 @@ fun box(): String {
|
|||||||
|
|
||||||
// CHECK_BYTECODE_TEXT
|
// CHECK_BYTECODE_TEXT
|
||||||
// JVM_IR_TEMPLATES
|
// JVM_IR_TEMPLATES
|
||||||
// 0 java/util/Iterator.hasNext \(\)Z
|
// 1 java/util/Iterator.hasNext \(\)Z
|
||||||
// 0 java/util/Iterator.next \(\)Ljava/lang/Object;
|
// 0 java/util/Iterator.next \(\)Ljava/lang/Object;
|
||||||
// 1 MyUIntIterator.hasNext \(\)Z
|
// 0 MyUIntIterator.next \(\)Ljava/lang/Object;
|
||||||
|
// 0 MyUIntIterator.hasNext \(\)Z
|
||||||
// 1 public synthetic bridge next\(\)Ljava/lang/Object;
|
// 1 public synthetic bridge next\(\)Ljava/lang/Object;
|
||||||
// 2 MyUIntIterator.next-pVg5ArA \(\)I
|
// 2 MyUIntIterator.next-pVg5ArA \(\)I
|
||||||
|
// 0 INVOKEVIRTUAL kotlin/UInt.unbox-impl \(\)I
|
||||||
+1
-1
@@ -10,7 +10,7 @@
|
|||||||
// JVM_IR_TEMPLATES
|
// JVM_IR_TEMPLATES
|
||||||
// 12 java/lang/invoke/LambdaMetafactory
|
// 12 java/lang/invoke/LambdaMetafactory
|
||||||
// 1 (LOOKUP|TABLE)SWITCH
|
// 1 (LOOKUP|TABLE)SWITCH
|
||||||
// 24 java/lang/String\.equals
|
// 4 java/lang/String\.equals
|
||||||
|
|
||||||
// FILE: multipleTopLevelFunRefs.kt
|
// FILE: multipleTopLevelFunRefs.kt
|
||||||
import java.io.*
|
import java.io.*
|
||||||
|
|||||||
Reference in New Issue
Block a user