diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java index 1503489ad07..379b8e15c51 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java @@ -10259,6 +10259,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/coroutines/inlineClasses/genericParameterResult.kt"); } + @Test + @TestMetadata("kt47129.kt") + public void testKt47129() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/inlineClasses/kt47129.kt"); + } + @Test @TestMetadata("nonLocalReturn.kt") public void testNonLocalReturn() throws Exception { diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmSymbols.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmSymbols.kt index 0636bfe71e9..e8b678cb38c 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmSymbols.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmSymbols.kt @@ -250,6 +250,8 @@ class JvmSymbols( klass.inlineClassRepresentation = InlineClassRepresentation(Name.identifier("value"), irBuiltIns.anyNType as IrSimpleType) } + val resultOfAnyType: IrType = resultClassStub.typeWith(irBuiltIns.anyNType) + val continuationImplClass: IrClassSymbol = createClass(FqName("kotlin.coroutines.jvm.internal.ContinuationImpl"), classModality = Modality.ABSTRACT) { klass -> val continuationType = continuationClass.typeWith(irBuiltIns.anyNType) @@ -258,7 +260,7 @@ class JvmSymbols( addValueParameter(SUSPEND_FUNCTION_COMPLETION_PARAMETER_NAME, continuationType.makeNullable()) } klass.addFunction(INVOKE_SUSPEND_METHOD_NAME, irBuiltIns.anyNType, Modality.ABSTRACT).apply { - addValueParameter(SUSPEND_CALL_RESULT_NAME, resultClassStub.typeWith(irBuiltIns.anyNType)) + addValueParameter(SUSPEND_CALL_RESULT_NAME, resultOfAnyType) } } @@ -291,7 +293,7 @@ class JvmSymbols( ) } klass.addFunction(INVOKE_SUSPEND_METHOD_NAME, irBuiltIns.anyNType, Modality.ABSTRACT, DescriptorVisibilities.PROTECTED).apply { - addValueParameter(SUSPEND_CALL_RESULT_NAME, resultClassStub.typeWith(irBuiltIns.anyNType)) + addValueParameter(SUSPEND_CALL_RESULT_NAME, resultOfAnyType) } klass.addFunction(SUSPEND_FUNCTION_CREATE_METHOD_NAME, continuationClass.typeWith(irBuiltIns.unitType), Modality.OPEN).apply { addValueParameter(SUSPEND_FUNCTION_COMPLETION_PARAMETER_NAME, continuationClass.typeWith(irBuiltIns.nothingType)) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt index af6f6ea913f..003e737648b 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt @@ -934,10 +934,6 @@ class ExpressionCodegen( val (returnType, returnIrType) = owner.returnAsmAndIrTypes() val afterReturnLabel = Label() expression.value.accept(this, data).materializeAt(returnType, returnIrType) - // In case of non-local return from suspend lambda 'materializeAt' does not box return value, box it manually. - if (isNonLocalReturn && owner.isInvokeSuspendOfLambda() && expression.value.type.isKotlinResult()) { - StackValue.boxInlineClass(expression.value.type, mv, typeMapper) - } generateFinallyBlocksIfNeeded(returnType, afterReturnLabel, data, null) expression.markLineNumber(startOffset = true) if (isNonLocalReturn) { diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/PromisedValue.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/PromisedValue.kt index 43322addaed..3a6a23e50a4 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/PromisedValue.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/PromisedValue.kt @@ -5,7 +5,6 @@ package org.jetbrains.kotlin.backend.jvm.codegen -import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin import org.jetbrains.kotlin.backend.jvm.ir.eraseTypeParameters import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.* import org.jetbrains.kotlin.codegen.AsmUtil @@ -32,15 +31,8 @@ abstract class PromisedValue(val codegen: ExpressionCodegen, val type: Type, val val fromTypeRepresentation = erasedSourceType.getClass()!!.inlineClassRepresentation val toTypeRepresentation = erasedTargetType.getClass()!!.inlineClassRepresentation - // Boxing and unboxing kotlin.Result leads to CCE in generated code - val doNotCoerceKotlinResultInContinuation = - (codegen.irFunction.parentAsClass.origin == JvmLoweredDeclarationOrigin.CONTINUATION_CLASS || - (codegen.irFunction.parentAsClass.origin == JvmLoweredDeclarationOrigin.SUSPEND_LAMBDA && - !codegen.irFunction.isInvokeSuspendOfLambda())) - && (irType.isKotlinResult() || irTarget.isKotlinResult()) - // Coerce inline classes - if ((fromTypeRepresentation != null || toTypeRepresentation != null) && !doNotCoerceKotlinResultInContinuation) { + if (fromTypeRepresentation != null || toTypeRepresentation != null) { val isFromTypeUnboxed = fromTypeRepresentation?.underlyingType?.let(typeMapper::mapType) == type val isToTypeUnboxed = toTypeRepresentation?.underlyingType?.let(typeMapper::mapType) == target diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/AddContinuationLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/AddContinuationLowering.kt index e61c8339a56..d8a66fcdbaa 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/AddContinuationLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/AddContinuationLowering.kt @@ -105,7 +105,7 @@ private class AddContinuationLowering(context: JvmBackendContext) : SuspendLower val resultField = addField { origin = JvmLoweredDeclarationOrigin.CONTINUATION_CLASS_RESULT_FIELD name = Name.identifier(context.state.languageVersionSettings.dataFieldName()) - type = context.irBuiltIns.anyNType + type = context.ir.symbols.resultOfAnyType visibility = JavaDescriptorVisibilities.PACKAGE_VISIBILITY } val capturedThisField = dispatchReceiverParameter?.let { diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SuspendLambdaLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SuspendLambdaLowering.kt index 112ff2a8c73..39b15b27585 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SuspendLambdaLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SuspendLambdaLowering.kt @@ -340,7 +340,14 @@ private class SuspendLambdaLowering(context: JvmBackendContext) : SuspendLowerin } private fun IrBlockBodyBuilder.callInvokeSuspend(invokeSuspend: IrSimpleFunction, lambda: IrExpression): IrExpression = - irCallOp(invokeSuspend.symbol, invokeSuspend.returnType, lambda, irUnit()) + irCallOp(invokeSuspend.symbol, invokeSuspend.returnType, lambda, irCall( + this@SuspendLambdaLowering.context.ir.symbols.unsafeCoerceIntrinsic, + this@SuspendLambdaLowering.context.ir.symbols.resultOfAnyType + ).apply { + putTypeArgument(0, context.irBuiltIns.anyNType) + putTypeArgument(1, type) + putValueArgument(0, irUnit()) + }) private fun IrClass.addPrimaryConstructorForLambda(superClass: IrClass, arity: Int): IrConstructor = addConstructor { diff --git a/compiler/testData/codegen/box/coroutines/inlineClasses/kt47129.kt b/compiler/testData/codegen/box/coroutines/inlineClasses/kt47129.kt new file mode 100644 index 00000000000..7e0d450fce4 --- /dev/null +++ b/compiler/testData/codegen/box/coroutines/inlineClasses/kt47129.kt @@ -0,0 +1,17 @@ +// WITH_RUNTIME +import kotlin.coroutines.* + +fun runBlocking(c: suspend () -> T): T { + var res: T? = null + c.startCoroutine(Continuation(EmptyCoroutineContext) { + res = it.getOrThrow() + }) + return res!! +} + +fun box(): String = runBlocking { // Non-inline lambda; + run { // In it an inline lambda + val foo = { Result.success("OK") } // Unboxes Result. + foo().getOrNull()!! + } +} diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java index 2fccc5e932c..cc30256f030 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java @@ -10259,6 +10259,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/coroutines/inlineClasses/genericParameterResult.kt"); } + @Test + @TestMetadata("kt47129.kt") + public void testKt47129() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/inlineClasses/kt47129.kt"); + } + @Test @TestMetadata("nonLocalReturn.kt") public void testNonLocalReturn() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index bb079dcc8b0..bb7eeb1bfe1 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java @@ -10259,6 +10259,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/coroutines/inlineClasses/genericParameterResult.kt"); } + @Test + @TestMetadata("kt47129.kt") + public void testKt47129() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/inlineClasses/kt47129.kt"); + } + @Test @TestMetadata("nonLocalReturn.kt") public void testNonLocalReturn() throws Exception { diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index d74cdb1c8f9..c66fe55a33b 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -8109,6 +8109,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/coroutines/inlineClasses/genericParameterResult.kt"); } + @TestMetadata("kt47129.kt") + public void testKt47129() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/inlineClasses/kt47129.kt"); + } + @TestMetadata("nonLocalReturn.kt") public void testNonLocalReturn() throws Exception { runTest("compiler/testData/codegen/box/coroutines/inlineClasses/nonLocalReturn.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java index 844600d920e..6aabdad9305 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java @@ -7213,6 +7213,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes runTest("compiler/testData/codegen/box/coroutines/inlineClasses/genericParameterResult.kt"); } + @TestMetadata("kt47129.kt") + public void testKt47129() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/inlineClasses/kt47129.kt"); + } + @TestMetadata("nonLocalReturn.kt") public void testNonLocalReturn() throws Exception { runTest("compiler/testData/codegen/box/coroutines/inlineClasses/nonLocalReturn.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index eb584dafa71..1a00ea47577 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -6619,6 +6619,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/coroutines/inlineClasses/genericParameterResult.kt"); } + @TestMetadata("kt47129.kt") + public void testKt47129() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/inlineClasses/kt47129.kt"); + } + @TestMetadata("nonLocalReturn.kt") public void testNonLocalReturn() throws Exception { runTest("compiler/testData/codegen/box/coroutines/inlineClasses/nonLocalReturn.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 1fb8cea833a..219482468bf 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -6619,6 +6619,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/coroutines/inlineClasses/genericParameterResult.kt"); } + @TestMetadata("kt47129.kt") + public void testKt47129() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/inlineClasses/kt47129.kt"); + } + @TestMetadata("nonLocalReturn.kt") public void testNonLocalReturn() throws Exception { runTest("compiler/testData/codegen/box/coroutines/inlineClasses/nonLocalReturn.kt");