JVM IR: fix generic signatures of suspend function references
Using `kotlin.jvm.functions.Function{n+1}` (via
`getJvmSuspendFunctionClass`) for suspend functions was wrong in the
function reference lowering, because we didn't adapt the parameter types
by transforming the last type to Continuation and adding Object, and
generic signature ended up being incorrect.
Actually there was no need to use `kotlin.jvm.functions.Function{n+1}`
at all. We can just use the built-in
`kotlin.coroutines.SuspendFunction{n}` as a supertype, and it will be
mapped correctly later in codegen. It's not even needed to add the
`kotlin.coroutines.jvm.internal.SuspendFunction` marker manually, since
it's also handled by the codegen (see `IrTypeMapper.mapClassSignature`).
#KT-48732 Fixed
This commit is contained in:
+6
@@ -10464,6 +10464,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/callableReference/fromJava.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt48732_genericSignature.kt")
|
||||
public void testKt48732_genericSignature() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/callableReference/kt48732_genericSignature.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lambdaParameterUsed.kt")
|
||||
public void testLambdaParameterUsed() throws Exception {
|
||||
|
||||
+2
-5
@@ -380,9 +380,9 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
|
||||
private val functionSuperClass =
|
||||
samSuperType?.classOrNull
|
||||
?: if (irFunctionReference.isSuspend)
|
||||
context.ir.symbols.getJvmSuspendFunctionClass(argumentTypes.size)
|
||||
context.irBuiltIns.suspendFunctionN(argumentTypes.size).symbol
|
||||
else
|
||||
context.ir.symbols.getJvmFunctionClass(argumentTypes.size)
|
||||
context.irBuiltIns.functionN(argumentTypes.size).symbol
|
||||
private val superMethod =
|
||||
functionSuperClass.owner.getSingleAbstractMethod()
|
||||
?: throw AssertionError("Not a SAM class: ${functionSuperClass.owner.render()}")
|
||||
@@ -445,9 +445,6 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
|
||||
if (samSuperType == null)
|
||||
functionSuperClass.typeWith(parameterTypes)
|
||||
else null,
|
||||
if (irFunctionReference.isSuspend)
|
||||
context.ir.symbols.suspendFunctionInterface.defaultType
|
||||
else null,
|
||||
if (needToGenerateSamEqualsHashCodeMethods)
|
||||
context.ir.symbols.functionAdapter.defaultType
|
||||
else null,
|
||||
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
// TARGET_BACKEND: JVM
|
||||
// WITH_COROUTINES
|
||||
// WITH_RUNTIME
|
||||
|
||||
suspend fun id(x: String): String = x
|
||||
|
||||
val f: suspend (String) -> String = ::id
|
||||
|
||||
fun box(): String {
|
||||
val actual = f.javaClass.genericInterfaces.toList().toString()
|
||||
val expected = "[" +
|
||||
"kotlin.jvm.functions.Function2<java.lang.String, kotlin.coroutines.Continuation<? super java.lang.String>, java.lang.Object>, " +
|
||||
"interface kotlin.coroutines.jvm.internal.SuspendFunction" +
|
||||
"]"
|
||||
|
||||
return if (expected == actual) "OK" else "Fail: $actual"
|
||||
}
|
||||
+6
@@ -10386,6 +10386,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/callableReference/fromJava.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt48732_genericSignature.kt")
|
||||
public void testKt48732_genericSignature() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/callableReference/kt48732_genericSignature.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lambdaParameterUsed.kt")
|
||||
public void testLambdaParameterUsed() throws Exception {
|
||||
|
||||
+6
@@ -10464,6 +10464,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/callableReference/fromJava.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt48732_genericSignature.kt")
|
||||
public void testKt48732_genericSignature() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/callableReference/kt48732_genericSignature.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lambdaParameterUsed.kt")
|
||||
public void testLambdaParameterUsed() throws Exception {
|
||||
|
||||
+5
@@ -8191,6 +8191,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/callableReference/fromJava.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt48732_genericSignature.kt")
|
||||
public void testKt48732_genericSignature() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/callableReference/kt48732_genericSignature.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("lambdaParameterUsed.kt")
|
||||
public void testLambdaParameterUsed() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/callableReference/lambdaParameterUsed.kt");
|
||||
|
||||
Reference in New Issue
Block a user