JVM_IR: fix bound suspend-converted references
Note: inlining of adapted callable references is still suboptimal. #KT-42021 Fixed
This commit is contained in:
Generated
+5
@@ -2207,6 +2207,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/bound.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("boundExtension.kt")
|
||||
public void testBoundExtension() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/boundExtension.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("crossInline.kt")
|
||||
public void testCrossInline() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/crossInline.kt");
|
||||
|
||||
+10
-4
@@ -41,14 +41,20 @@ internal val functionReferencePhase = makeIrFilePhase(
|
||||
)
|
||||
|
||||
internal class FunctionReferenceLowering(private val context: JvmBackendContext) : FileLoweringPass, IrElementTransformerVoidWithContext() {
|
||||
// This pass ignores suspend function references and function references used in inline arguments to inline functions.
|
||||
// This pass ignores function references used as inline arguments. `InlineCallableReferenceToLambdaPhase`
|
||||
// converts them into lambdas instead, so that after inlining there is only a direct call left, with no
|
||||
// function reference classes needed.
|
||||
private val ignoredFunctionReferences = mutableSetOf<IrCallableReference<*>>()
|
||||
|
||||
private val IrFunctionReference.isIgnored: Boolean
|
||||
get() = (!type.isFunctionOrKFunction() || ignoredFunctionReferences.contains(this)) && !isSuspendFunctionReference()
|
||||
get() = (!type.isFunctionOrKFunction() && !isSuspendFunctionReference()) || ignoredFunctionReferences.contains(this)
|
||||
|
||||
// TODO: Currently, origin of callable references is null. Do we need to create one?
|
||||
private fun IrFunctionReference.isSuspendFunctionReference(): Boolean = isSuspend && origin == null
|
||||
// `suspend` function references are the same as non-`suspend` ones, just with a `suspend` invoke;
|
||||
// however, suspending lambdas require different generation implemented in AddContinuationLowering
|
||||
// because they are also their own continuation classes.
|
||||
// TODO: Currently, origin of callable references explicitly written in source code is null. Do we need to create one?
|
||||
private fun IrFunctionReference.isSuspendFunctionReference(): Boolean = isSuspend &&
|
||||
(origin == null || origin == IrStatementOrigin.ADAPTED_FUNCTION_REFERENCE)
|
||||
|
||||
override fun lower(irFile: IrFile) {
|
||||
ignoredFunctionReferences.addAll(IrInlineReferenceLocator.scan(context, irFile))
|
||||
|
||||
Vendored
-4
@@ -1,14 +1,10 @@
|
||||
// !LANGUAGE: +SuspendConversion
|
||||
// WITH_RUNTIME
|
||||
// WITH_COROUTINES
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
|
||||
import helpers.*
|
||||
import kotlin.coroutines.*
|
||||
import kotlin.coroutines.intrinsics.*
|
||||
|
||||
|
||||
fun runSuspend(c: suspend () -> Unit) {
|
||||
c.startCoroutine(EmptyContinuation)
|
||||
}
|
||||
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
// !LANGUAGE: +SuspendConversion
|
||||
// WITH_RUNTIME
|
||||
// WITH_COROUTINES
|
||||
import helpers.*
|
||||
import kotlin.coroutines.*
|
||||
import kotlin.coroutines.intrinsics.*
|
||||
|
||||
fun runSuspend(c: suspend () -> Unit) {
|
||||
c.startCoroutine(EmptyContinuation)
|
||||
}
|
||||
|
||||
class C {
|
||||
var test = "failed"
|
||||
}
|
||||
|
||||
fun C.foo() {
|
||||
test = "OK"
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val c = C()
|
||||
runSuspend(c::foo)
|
||||
return c.test
|
||||
}
|
||||
Vendored
-4
@@ -1,14 +1,10 @@
|
||||
// !LANGUAGE: +SuspendConversion
|
||||
// WITH_RUNTIME
|
||||
// WITH_COROUTINES
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
|
||||
import helpers.*
|
||||
import kotlin.coroutines.*
|
||||
import kotlin.coroutines.intrinsics.*
|
||||
|
||||
|
||||
fun runSuspend(c: suspend () -> Unit) {
|
||||
c.startCoroutine(EmptyContinuation)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// !LANGUAGE: +SuspendConversion
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// ^ TODO fix suspend coercion for bound function references in JVM_IR
|
||||
// FILE: suspendCovnersion.kt
|
||||
|
||||
fun checkNotEqual(x: Any, y: Any) {
|
||||
|
||||
+5
@@ -2227,6 +2227,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/bound.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("boundExtension.kt")
|
||||
public void testBoundExtension() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/boundExtension.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("crossInline.kt")
|
||||
public void testCrossInline() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/crossInline.kt");
|
||||
|
||||
+5
@@ -2227,6 +2227,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/bound.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("boundExtension.kt")
|
||||
public void testBoundExtension() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/boundExtension.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("crossInline.kt")
|
||||
public void testCrossInline() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/crossInline.kt");
|
||||
|
||||
+5
@@ -2207,6 +2207,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/bound.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("boundExtension.kt")
|
||||
public void testBoundExtension() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/boundExtension.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("crossInline.kt")
|
||||
public void testCrossInline() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/crossInline.kt");
|
||||
|
||||
Generated
+5
@@ -1612,6 +1612,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
|
||||
runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/bound.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("boundExtension.kt")
|
||||
public void testBoundExtension() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/boundExtension.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("crossInline.kt")
|
||||
public void testCrossInline() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/crossInline.kt");
|
||||
|
||||
Generated
+5
@@ -1612,6 +1612,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/bound.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("boundExtension.kt")
|
||||
public void testBoundExtension() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/boundExtension.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("crossInline.kt")
|
||||
public void testCrossInline() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/crossInline.kt");
|
||||
|
||||
+5
@@ -1612,6 +1612,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/bound.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("boundExtension.kt")
|
||||
public void testBoundExtension() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/boundExtension.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("crossInline.kt")
|
||||
public void testCrossInline() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/crossInline.kt");
|
||||
|
||||
Reference in New Issue
Block a user