diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/PostponedArguments.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/PostponedArguments.kt index 6032aa49c46..35eff106053 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/PostponedArguments.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/PostponedArguments.kt @@ -106,7 +106,7 @@ private fun extraLambdaInfo( val isSuspend = expectedType?.isSuspendFunctionType ?: false val isFunctionSupertype = - expectedType != null && expectedType.isBuiltinFunctionalType//isNotNullOrNullableFunctionSupertype(expectedType) + expectedType != null && expectedType.lowerBoundIfFlexible().isBuiltinFunctionalType//isNotNullOrNullableFunctionSupertype(expectedType) val argumentAsFunctionExpression = argument//.safeAs() val typeVariable = TypeVariableForLambdaReturnType(argument, "_L") @@ -133,7 +133,9 @@ internal fun extractLambdaInfoFromFunctionalType( expectedTypeRef: FirTypeRef, argument: FirAnonymousFunction ): ResolvedLambdaAtom? { - if (expectedType == null || !expectedType.isBuiltinFunctionalType) return null + if (expectedType == null) return null + if (expectedType is ConeFlexibleType) return extractLambdaInfoFromFunctionalType(expectedType.lowerBound, expectedTypeRef, argument) + if (!expectedType.isBuiltinFunctionalType) return null val parameters = extractLambdaParameters(expectedType, argument) val argumentAsFunctionExpression = argument//.safeAs() @@ -193,4 +195,4 @@ class ResolvedLambdaAtom( override val inputTypes: Collection get() = receiver?.let { parameters + it } ?: parameters override val outputType: ConeKotlinType get() = returnType -} \ No newline at end of file +} diff --git a/compiler/fir/resolve/testData/diagnostics/j+k/FunctionTypeInJava.kt b/compiler/fir/resolve/testData/diagnostics/j+k/FunctionTypeInJava.kt new file mode 100644 index 00000000000..1d7751536d2 --- /dev/null +++ b/compiler/fir/resolve/testData/diagnostics/j+k/FunctionTypeInJava.kt @@ -0,0 +1,22 @@ +// WITH_RUNTIME +// FILE: JavaClass.java +public class JavaClass { + public static void foo1(kotlin.jvm.functions.Function0 x) {} + public static void foo2(kotlin.jvm.functions.Function1 x) {} + public static void foo3(kotlin.jvm.functions.Function1 x, T y) {} +} + +// FILE: main.kt + +fun main() { + JavaClass.foo1 { 123 } + + + JavaClass.foo2 { (it + 2).toString() } + JavaClass.foo2({ (it + 3).toString() }) + val y = { x: Int -> x.toString() } + JavaClass.foo2(y) + + + JavaClass.foo3({ (it + 4).toString() }, 5) +} diff --git a/compiler/fir/resolve/testData/diagnostics/j+k/FunctionTypeInJava.txt b/compiler/fir/resolve/testData/diagnostics/j+k/FunctionTypeInJava.txt new file mode 100644 index 00000000000..be502954ad8 --- /dev/null +++ b/compiler/fir/resolve/testData/diagnostics/j+k/FunctionTypeInJava.txt @@ -0,0 +1,24 @@ +FILE: main.kt + public final fun main(): R|kotlin/Unit| { + Q|JavaClass|.R|/JavaClass.foo1|( = foo1@fun (): R|ft!| { + Int(123) + } + ) + Q|JavaClass|.R|/JavaClass.foo2|( = foo2@fun (it: R|ft!|): R|ft!| { + R|/it|.R|kotlin/Int.plus|(Int(2)).R|kotlin/Any.toString|() + } + ) + Q|JavaClass|.R|/JavaClass.foo2|(foo2@fun (it: R|ft!|): R|ft!| { + R|/it|.R|kotlin/Int.plus|(Int(3)).R|kotlin/Any.toString|() + } + ) + lval y: R|kotlin/Function1| = fun (x: R|kotlin/Int|): R|kotlin/String| { + R|/x|.R|kotlin/Any.toString|() + } + + Q|JavaClass|.R|/JavaClass.foo2|(R|/y|) + Q|JavaClass|.R|/JavaClass.foo3||>(foo3@fun (it: R|ft|): R|ft!| { + R|/it|.R|kotlin/Int.plus|(Int(4)).R|kotlin/Any.toString|() + } + , Int(5)) + } diff --git a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/AbstractFirDiagnosticsTest.kt b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/AbstractFirDiagnosticsTest.kt index ed51a9ae177..dad451f500b 100644 --- a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/AbstractFirDiagnosticsTest.kt +++ b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/AbstractFirDiagnosticsTest.kt @@ -6,11 +6,16 @@ package org.jetbrains.kotlin.fir import org.jetbrains.kotlin.fir.declarations.FirFile +import org.jetbrains.kotlin.test.ConfigurationKind import org.jetbrains.kotlin.test.KotlinTestUtils import java.io.File abstract class AbstractFirDiagnosticsTest : AbstractFirDiagnosticsSmokeTest() { + override fun getConfigurationKind(): ConfigurationKind { + return ConfigurationKind.ALL + } + override fun checkResultingFirFiles( firFiles: MutableList, testDataFile: File diff --git a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java index cac777cc9d5..d36bd233663 100644 --- a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java +++ b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java @@ -46,6 +46,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest { runTest("compiler/fir/resolve/testData/diagnostics/j+k/complexFlexibleInference.kt"); } + @TestMetadata("FunctionTypeInJava.kt") + public void testFunctionTypeInJava() throws Exception { + runTest("compiler/fir/resolve/testData/diagnostics/j+k/FunctionTypeInJava.kt"); + } + @TestMetadata("KJKComplexHierarchy.kt") public void testKJKComplexHierarchy() throws Exception { runTest("compiler/fir/resolve/testData/diagnostics/j+k/KJKComplexHierarchy.kt");