JVM_IR: place suspend markers in faux lambdas around inline references
Otherwise, the assumption that coroutine codegen makes about every inlined function already having the markers breaks and it is no longer true that calls to inline lambdas do not require them.
This commit is contained in:
-1
@@ -102,7 +102,6 @@ internal fun IrFunction.shouldContainSuspendMarkers(): Boolean = !isInvokeSuspen
|
||||
origin != JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR &&
|
||||
origin != JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE &&
|
||||
origin != JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_TO_SYNTHETIC &&
|
||||
origin != JvmLoweredDeclarationOrigin.GENERATED_MEMBER_IN_CALLABLE_REFERENCE &&
|
||||
origin != IrDeclarationOrigin.BRIDGE &&
|
||||
origin != IrDeclarationOrigin.BRIDGE_SPECIAL &&
|
||||
origin != IrDeclarationOrigin.DELEGATED_MEMBER &&
|
||||
|
||||
+2
-3
@@ -12,7 +12,6 @@ import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.backend.common.lower.irBlock
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.IrInlineReferenceLocator
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.createJvmIrBuilder
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.irArray
|
||||
@@ -78,7 +77,7 @@ internal class InlineCallableReferenceToLambdaPhase(val context: JvmBackendConte
|
||||
return irBuilder.irBlock(expression, IrStatementOrigin.LAMBDA) {
|
||||
val function = buildFun {
|
||||
setSourceRange(expression)
|
||||
origin = JvmLoweredDeclarationOrigin.GENERATED_MEMBER_IN_CALLABLE_REFERENCE
|
||||
origin = IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA
|
||||
name = Name.identifier("stub_for_inline")
|
||||
visibility = Visibilities.LOCAL
|
||||
returnType = field.type
|
||||
@@ -135,7 +134,7 @@ internal class InlineCallableReferenceToLambdaPhase(val context: JvmBackendConte
|
||||
|
||||
val function = buildFun {
|
||||
setSourceRange(expression)
|
||||
origin = JvmLoweredDeclarationOrigin.GENERATED_MEMBER_IN_CALLABLE_REFERENCE
|
||||
origin = IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA
|
||||
name = Name.identifier("stub_for_inlining")
|
||||
visibility = Visibilities.LOCAL
|
||||
returnType = referencedFunction.returnType
|
||||
|
||||
+2
-2
@@ -46,7 +46,7 @@ private class TailCallOptimizationLowering(private val context: JvmBackendContex
|
||||
}, null)
|
||||
}
|
||||
|
||||
private fun IrExpression.coerceToUnit() = IrTypeOperatorCallImpl(
|
||||
private fun IrExpression.coerceToUnit() = if (type == context.irBuiltIns.unitType) this else IrTypeOperatorCallImpl(
|
||||
startOffset, endOffset, context.irBuiltIns.unitType, IrTypeOperator.IMPLICIT_COERCION_TO_UNIT, context.irBuiltIns.unitType, this
|
||||
)
|
||||
}
|
||||
@@ -75,7 +75,7 @@ private class TailCallOptimizationData(val function: IrSimpleFunction) {
|
||||
init {
|
||||
when (val body = function.body) {
|
||||
is IrBlockBody -> body.statements.findTailCall(returnsUnit)?.findCallsOnTailPositionWithoutImmediateReturn()
|
||||
is IrExpressionBody -> body.expression.findCallsOnTailPositionWithoutImmediateReturn()
|
||||
is IrExpressionBody -> body.expression.findCallsOnTailPositionWithoutImmediateReturn(immediateReturn = true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
// WITH_RUNTIME
|
||||
// WITH_COROUTINES
|
||||
// NO_CHECK_LAMBDA_INLINING
|
||||
// FILE: 1.kt
|
||||
import kotlin.coroutines.intrinsics.*
|
||||
import kotlin.coroutines.*
|
||||
|
||||
class Delayed(val run: suspend() -> Unit)
|
||||
|
||||
inline fun asyncThenAddK(crossinline block: suspend () -> Unit) =
|
||||
Delayed {
|
||||
block()
|
||||
result += "K"
|
||||
}
|
||||
|
||||
suspend fun pause(): Unit = suspendCoroutineUninterceptedOrReturn { cont ->
|
||||
cont.resume(Unit)
|
||||
COROUTINE_SUSPENDED
|
||||
}
|
||||
|
||||
var result = ""
|
||||
|
||||
suspend fun addO(): Unit {
|
||||
pause()
|
||||
result += "O"
|
||||
}
|
||||
|
||||
// FILE: 2.kt
|
||||
import kotlin.coroutines.intrinsics.*
|
||||
import kotlin.coroutines.*
|
||||
import helpers.*
|
||||
|
||||
fun box(): String {
|
||||
suspend { asyncThenAddK(::addO).run() }.startCoroutine(EmptyContinuation)
|
||||
return result
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// WITH_RUNTIME
|
||||
// WITH_COROUTINES
|
||||
// NO_CHECK_LAMBDA_INLINING
|
||||
// FILE: 1.kt
|
||||
import kotlin.coroutines.intrinsics.*
|
||||
import kotlin.coroutines.*
|
||||
|
||||
class Delayed(val run: suspend() -> Unit)
|
||||
|
||||
inline fun async(crossinline block: suspend () -> Unit) =
|
||||
Delayed { block() }
|
||||
|
||||
suspend fun pause(): Unit = suspendCoroutineUninterceptedOrReturn { cont ->
|
||||
cont.resume(Unit)
|
||||
COROUTINE_SUSPENDED
|
||||
}
|
||||
|
||||
var result = ""
|
||||
|
||||
suspend fun addOK(): Unit {
|
||||
pause()
|
||||
result += "OK"
|
||||
}
|
||||
|
||||
// FILE: 2.kt
|
||||
import kotlin.coroutines.intrinsics.*
|
||||
import kotlin.coroutines.*
|
||||
import helpers.*
|
||||
|
||||
fun box(): String {
|
||||
suspend { async(::addOK).run() }.startCoroutine(EmptyContinuation)
|
||||
return result
|
||||
}
|
||||
+10
@@ -3885,10 +3885,20 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxInline/suspend/callableReference"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
|
||||
}
|
||||
|
||||
@TestMetadata("nonTailCall.kt")
|
||||
public void testNonTailCall() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/suspend/callableReference/nonTailCall.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/suspend/callableReference/simple.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("unitReturn.kt")
|
||||
public void testUnitReturn() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/suspend/callableReference/unitReturn.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/boxInline/suspend/defaultParameter")
|
||||
|
||||
Generated
+10
@@ -3885,10 +3885,20 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxInline/suspend/callableReference"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
|
||||
}
|
||||
|
||||
@TestMetadata("nonTailCall.kt")
|
||||
public void testNonTailCall() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/suspend/callableReference/nonTailCall.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/suspend/callableReference/simple.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("unitReturn.kt")
|
||||
public void testUnitReturn() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/suspend/callableReference/unitReturn.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/boxInline/suspend/defaultParameter")
|
||||
|
||||
+10
@@ -3780,10 +3780,20 @@ public class IrBlackBoxInlineCodegenTestGenerated extends AbstractIrBlackBoxInli
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxInline/suspend/callableReference"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@TestMetadata("nonTailCall.kt")
|
||||
public void testNonTailCall() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/suspend/callableReference/nonTailCall.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/suspend/callableReference/simple.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("unitReturn.kt")
|
||||
public void testUnitReturn() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/suspend/callableReference/unitReturn.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/boxInline/suspend/defaultParameter")
|
||||
|
||||
Generated
+10
@@ -3780,10 +3780,20 @@ public class IrCompileKotlinAgainstInlineKotlinTestGenerated extends AbstractIrC
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxInline/suspend/callableReference"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@TestMetadata("nonTailCall.kt")
|
||||
public void testNonTailCall() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/suspend/callableReference/nonTailCall.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/suspend/callableReference/simple.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("unitReturn.kt")
|
||||
public void testUnitReturn() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/suspend/callableReference/unitReturn.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/boxInline/suspend/defaultParameter")
|
||||
|
||||
Generated
+10
@@ -3355,10 +3355,20 @@ public class IrJsCodegenInlineTestGenerated extends AbstractIrJsCodegenInlineTes
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxInline/suspend/callableReference"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||
}
|
||||
|
||||
@TestMetadata("nonTailCall.kt")
|
||||
public void testNonTailCall() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/suspend/callableReference/nonTailCall.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/suspend/callableReference/simple.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("unitReturn.kt")
|
||||
public void testUnitReturn() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/suspend/callableReference/unitReturn.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/boxInline/suspend/defaultParameter")
|
||||
|
||||
+10
@@ -3355,10 +3355,20 @@ public class JsCodegenInlineTestGenerated extends AbstractJsCodegenInlineTest {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxInline/suspend/callableReference"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true);
|
||||
}
|
||||
|
||||
@TestMetadata("nonTailCall.kt")
|
||||
public void testNonTailCall() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/suspend/callableReference/nonTailCall.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/suspend/callableReference/simple.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("unitReturn.kt")
|
||||
public void testUnitReturn() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/suspend/callableReference/unitReturn.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/boxInline/suspend/defaultParameter")
|
||||
|
||||
Reference in New Issue
Block a user