diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java index 3402d86a171..8635baa0733 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java @@ -230,6 +230,8 @@ public class ClosureCodegen extends MemberCodegen { erasedInterfaceFunction.getValueParameters(), erasedInterfaceFunction.getReturnType(), Modality.OPEN, erasedInterfaceFunction.getVisibility()); + descriptorForBridges.setSuspend(descriptor.isSuspend()); + DescriptorUtilsKt.setSingleOverridden(descriptorForBridges, erasedInterfaceFunction); codegen.generateBridges(descriptorForBridges); } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/coroutineCodegenUtil.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/coroutineCodegenUtil.kt index 66f58b563f1..311867acbe1 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/coroutineCodegenUtil.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/coroutineCodegenUtil.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.codegen.coroutines import com.intellij.openapi.project.Project import org.jetbrains.kotlin.backend.common.COROUTINE_SUSPENDED_NAME import org.jetbrains.kotlin.backend.common.isBuiltInSuspendCoroutineUninterceptedOrReturn +import org.jetbrains.kotlin.builtins.isBuiltinFunctionalClassDescriptor import org.jetbrains.kotlin.builtins.isBuiltinFunctionalType import org.jetbrains.kotlin.codegen.* import org.jetbrains.kotlin.codegen.binding.CodegenBinding @@ -263,7 +264,7 @@ fun getOrCreateJvmSuspendFunctionView( annotations = Annotations.EMPTY, name = CONTINUATION_PARAMETER_NAME, // Add j.l.Object to invoke(), because that is the type of parameters we have in FunctionN+1 - outType = if (function.containingDeclaration.safeAs()?.defaultType?.isBuiltinFunctionalType == true) + outType = if (function.containingDeclaration.safeAs()?.isBuiltinFunctionalClassDescriptor == true) function.builtIns.nullableAnyType else function.getContinuationParameterTypeOfSuspendFunction(isReleaseCoroutines), diff --git a/compiler/testData/codegen/box/funInterface/suspendFunInterfaceConversionCodegen.kt b/compiler/testData/codegen/box/funInterface/suspendFunInterfaceConversionCodegen.kt new file mode 100644 index 00000000000..311c70f7b83 --- /dev/null +++ b/compiler/testData/codegen/box/funInterface/suspendFunInterfaceConversionCodegen.kt @@ -0,0 +1,25 @@ +// !LANGUAGE: +NewInference +FunctionInterfaceConversion +SamConversionPerArgument +SamConversionForKotlinFunctions +// WITH_COROUTINES +// WITH_RUNTIME + +import helpers.* +import kotlin.coroutines.startCoroutine + +fun interface SuspendRunnable { + suspend fun invoke() +} + +fun run(r: SuspendRunnable) { + r::invoke.startCoroutine(EmptyContinuation) +} + +var result = "initial" + +suspend fun bar() { + result = "OK" +} + +fun box(): String { + run(::bar) + return result +} diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index a1ba0bbf2b8..8152c910ca2 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -11656,6 +11656,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { public void testReceiverEvaluatedOnce() throws Exception { runTest("compiler/testData/codegen/box/funInterface/receiverEvaluatedOnce.kt"); } + + @TestMetadata("suspendFunInterfaceConversionCodegen.kt") + public void testSuspendFunInterfaceConversionCodegen() throws Exception { + runTest("compiler/testData/codegen/box/funInterface/suspendFunInterfaceConversionCodegen.kt"); + } } @TestMetadata("compiler/testData/codegen/box/functions") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 541955f3f3b..d5ebb9aef6c 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -11656,6 +11656,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes public void testReceiverEvaluatedOnce() throws Exception { runTest("compiler/testData/codegen/box/funInterface/receiverEvaluatedOnce.kt"); } + + @TestMetadata("suspendFunInterfaceConversionCodegen.kt") + public void testSuspendFunInterfaceConversionCodegen() throws Exception { + runTest("compiler/testData/codegen/box/funInterface/suspendFunInterfaceConversionCodegen.kt"); + } } @TestMetadata("compiler/testData/codegen/box/functions") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java index c1cea02fe77..1febe0893c6 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java @@ -10506,6 +10506,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT public void testReceiverEvaluatedOnce() throws Exception { runTest("compiler/testData/codegen/box/funInterface/receiverEvaluatedOnce.kt"); } + + @TestMetadata("suspendFunInterfaceConversionCodegen.kt") + public void testSuspendFunInterfaceConversionCodegen() throws Exception { + runTest("compiler/testData/codegen/box/funInterface/suspendFunInterfaceConversionCodegen.kt"); + } } @TestMetadata("compiler/testData/codegen/box/functions") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index a52cde5fb74..0b16ca184b9 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -10506,6 +10506,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes public void testReceiverEvaluatedOnce() throws Exception { runTest("compiler/testData/codegen/box/funInterface/receiverEvaluatedOnce.kt"); } + + @TestMetadata("suspendFunInterfaceConversionCodegen.kt") + public void testSuspendFunInterfaceConversionCodegen() throws Exception { + runTest("compiler/testData/codegen/box/funInterface/suspendFunInterfaceConversionCodegen.kt"); + } } @TestMetadata("compiler/testData/codegen/box/functions") diff --git a/core/descriptors/src/org/jetbrains/kotlin/builtins/functionTypes.kt b/core/descriptors/src/org/jetbrains/kotlin/builtins/functionTypes.kt index a7815568b43..c25681247f9 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/builtins/functionTypes.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/builtins/functionTypes.kt @@ -65,10 +65,13 @@ val KotlinType.isFunctionOrSuspendFunctionType: Boolean get() = isFunctionType || isSuspendFunctionType val KotlinType.isBuiltinFunctionalType: Boolean + get() = constructor.declarationDescriptor?.isBuiltinFunctionalClassDescriptor == true + +val DeclarationDescriptor.isBuiltinFunctionalClassDescriptor: Boolean get() { - val kind = constructor.declarationDescriptor?.getFunctionalClassKind() - return kind == FunctionClassDescriptor.Kind.Function || - kind == FunctionClassDescriptor.Kind.SuspendFunction + val functionalClassKind = getFunctionalClassKind() + return functionalClassKind == FunctionClassDescriptor.Kind.Function || + functionalClassKind == FunctionClassDescriptor.Kind.SuspendFunction } fun isBuiltinFunctionClass(classId: ClassId): Boolean {