From 928fb94052510ecbdf1bbb5d3249cb3bcf44cea1 Mon Sep 17 00:00:00 2001 From: Dmitrii Gridin Date: Tue, 5 Mar 2024 15:45:58 +0100 Subject: [PATCH] [FIR] fix internal error on suspend conversion with not-computed return type ^KT-62836 Fixed --- ...CompilerTestFE10TestdataTestGenerated.java | 6 +++ ...sticCompilerFE10TestDataTestGenerated.java | 6 +++ ...eeOldFrontendDiagnosticsTestGenerated.java | 6 +++ ...siOldFrontendDiagnosticsTestGenerated.java | 6 +++ .../kotlin/fir/resolve/calls/Arguments.kt | 38 +++++++++---------- ...typeOfFunctionalTypeToSuspendConversion.kt | 2 - .../tests/suspendConversion/implicitInvoke.kt | 8 ++++ .../implicitInvokeFromChildClass.kt | 1 - .../implicitInvokeWithSpecificType.fir.kt | 3 +- .../implicitInvokeWithSpecificType.kt | 1 - .../test/runners/DiagnosticTestGenerated.java | 6 +++ 11 files changed, 58 insertions(+), 25 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/suspendConversion/implicitInvoke.kt diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java index e7eea69fd66..44e495a031d 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java @@ -38358,6 +38358,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia runTest("compiler/testData/diagnostics/tests/suspendConversion/chainedFunSuspendConversionForSimpleExpression.kt"); } + @Test + @TestMetadata("implicitInvoke.kt") + public void testImplicitInvoke() { + runTest("compiler/testData/diagnostics/tests/suspendConversion/implicitInvoke.kt"); + } + @Test @TestMetadata("implicitInvokeFromChildClass.kt") public void testImplicitInvokeFromChildClass() { diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java index 505ff95ea7a..217cf8882a1 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java @@ -38358,6 +38358,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated runTest("compiler/testData/diagnostics/tests/suspendConversion/chainedFunSuspendConversionForSimpleExpression.kt"); } + @Test + @TestMetadata("implicitInvoke.kt") + public void testImplicitInvoke() { + runTest("compiler/testData/diagnostics/tests/suspendConversion/implicitInvoke.kt"); + } + @Test @TestMetadata("implicitInvokeFromChildClass.kt") public void testImplicitInvokeFromChildClass() { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java index 9ea3f1f87a6..ef6d6390df6 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java @@ -35930,6 +35930,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir runTest("compiler/testData/diagnostics/tests/suspendConversion/chainedFunSuspendConversionForSimpleExpression.kt"); } + @Test + @TestMetadata("implicitInvoke.kt") + public void testImplicitInvoke() { + runTest("compiler/testData/diagnostics/tests/suspendConversion/implicitInvoke.kt"); + } + @Test @TestMetadata("implicitInvokeFromChildClass.kt") public void testImplicitInvokeFromChildClass() { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java index 185fe3f741a..af866d68d4a 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java @@ -36068,6 +36068,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia runTest("compiler/testData/diagnostics/tests/suspendConversion/chainedFunSuspendConversionForSimpleExpression.kt"); } + @Test + @TestMetadata("implicitInvoke.kt") + public void testImplicitInvoke() { + runTest("compiler/testData/diagnostics/tests/suspendConversion/implicitInvoke.kt"); + } + @Test @TestMetadata("implicitInvokeFromChildClass.kt") public void testImplicitInvokeFromChildClass() { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Arguments.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Arguments.kt index f2d30b176a7..ecd03f93905 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Arguments.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Arguments.kt @@ -24,7 +24,9 @@ import org.jetbrains.kotlin.fir.resolve.transformers.ensureResolvedTypeDeclarati import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag import org.jetbrains.kotlin.fir.types.* +import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl +import org.jetbrains.kotlin.fir.types.unwrapLowerBound import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.StandardClassIds @@ -287,8 +289,10 @@ fun Candidate.resolvePlainArgumentType( // If the argument is of functional type and the expected type is a suspend function type, we need to do "suspend conversion." if (expectedType != null) { - argumentTypeWithCustomConversion( - session, context.bodyResolveComponents.scopeSession, expectedType, argumentTypeForApplicabilityCheck + context.typeContext.argumentTypeWithCustomConversion( + session = session, + expectedType = expectedType, + argumentType = argumentTypeForApplicabilityCheck, )?.let { argumentTypeForApplicabilityCheck = it substitutor.substituteOrSelf(argumentTypeForApplicabilityCheck) @@ -301,11 +305,10 @@ fun Candidate.resolvePlainArgumentType( ) } -private fun argumentTypeWithCustomConversion( +private fun ConeInferenceContext.argumentTypeWithCustomConversion( session: FirSession, - scopeSession: ScopeSession, expectedType: ConeKotlinType, - argumentType: ConeKotlinType + argumentType: ConeKotlinType, ): ConeKotlinType? { // Expect the expected type to be a not regular functional type (e.g. suspend or custom) val expectedTypeKind = expectedType.functionTypeKind(session) ?: return null @@ -314,21 +317,18 @@ private fun argumentTypeWithCustomConversion( // We want to check the argument type against non-suspend functional type. val expectedFunctionType = expectedType.customFunctionTypeToSimpleFunctionType(session) - val argumentTypeWithInvoke = argumentType.findSubtypeOfBasicFunctionType(session, expectedFunctionType) + val argumentTypeWithInvoke = argumentType.findSubtypeOfBasicFunctionType(session, expectedFunctionType) ?: return null + val functionType = argumentTypeWithInvoke.unwrapLowerBound() + .fastCorrespondingSupertypes(expectedFunctionType.typeConstructor()) + ?.firstOrNull() as? ConeKotlinType ?: return null - return argumentTypeWithInvoke?.findContributedInvokeSymbol( - session, - scopeSession, - expectedFunctionType, - shouldCalculateReturnTypesOfFakeOverrides = false - )?.let { invokeSymbol -> - createFunctionType( - expectedTypeKind, - invokeSymbol.fir.valueParameters.map { it.returnTypeRef.coneType }, - null, - invokeSymbol.fir.returnTypeRef.coneType, - ) - } + val typeArguments = functionType.typeArguments.map { it.type ?: session.builtinTypes.nullableAnyType.type }.ifEmpty { return null } + return createFunctionType( + kind = expectedTypeKind, + parameters = typeArguments.subList(0, typeArguments.lastIndex), + receiverType = null, + rawReturnType = typeArguments.last(), + ) } internal fun prepareCapturedType(argumentType: ConeKotlinType, context: ResolutionContext): ConeKotlinType { diff --git a/compiler/testData/codegen/box/coroutines/suspendConversion/subtypeOfFunctionalTypeToSuspendConversion.kt b/compiler/testData/codegen/box/coroutines/suspendConversion/subtypeOfFunctionalTypeToSuspendConversion.kt index cf0065e0eb1..8977f79eca0 100644 --- a/compiler/testData/codegen/box/coroutines/suspendConversion/subtypeOfFunctionalTypeToSuspendConversion.kt +++ b/compiler/testData/codegen/box/coroutines/suspendConversion/subtypeOfFunctionalTypeToSuspendConversion.kt @@ -3,8 +3,6 @@ // WITH_COROUTINES // IGNORE_BACKEND: JVM, JS, JS_IR // IGNORE_BACKEND: JS_IR_ES6 -// IGNORE_REVERSED_RESOLVE -// KT-62836 import helpers.* import kotlin.coroutines.* diff --git a/compiler/testData/diagnostics/tests/suspendConversion/implicitInvoke.kt b/compiler/testData/diagnostics/tests/suspendConversion/implicitInvoke.kt new file mode 100644 index 00000000000..28e915613ac --- /dev/null +++ b/compiler/testData/diagnostics/tests/suspendConversion/implicitInvoke.kt @@ -0,0 +1,8 @@ +// FIR_IDENTICAL +fun box() = useSuspendFunInt(Test()) + +fun useSuspendFunInt(fn: suspend () -> String): String = "" + +open class Test : () -> String { + override fun invoke() = "OK" +} diff --git a/compiler/testData/diagnostics/tests/suspendConversion/implicitInvokeFromChildClass.kt b/compiler/testData/diagnostics/tests/suspendConversion/implicitInvokeFromChildClass.kt index cb8ca53bf05..1ace256c7cd 100644 --- a/compiler/testData/diagnostics/tests/suspendConversion/implicitInvokeFromChildClass.kt +++ b/compiler/testData/diagnostics/tests/suspendConversion/implicitInvokeFromChildClass.kt @@ -1,5 +1,4 @@ // FIR_IDENTICAL -// IGNORE_DIAGNOSTIC_API // ISSUE: KT-62836 fun box() { useSuspendFunInt(Child()) diff --git a/compiler/testData/diagnostics/tests/suspendConversion/implicitInvokeWithSpecificType.fir.kt b/compiler/testData/diagnostics/tests/suspendConversion/implicitInvokeWithSpecificType.fir.kt index 20c03c393b8..9044e323ea5 100644 --- a/compiler/testData/diagnostics/tests/suspendConversion/implicitInvokeWithSpecificType.fir.kt +++ b/compiler/testData/diagnostics/tests/suspendConversion/implicitInvokeWithSpecificType.fir.kt @@ -1,7 +1,6 @@ -// IGNORE_DIAGNOSTIC_API // ISSUE: KT-62836 fun box() { - useSuspendFunInt(Test()) + useSuspendFunInt(Test()) } fun useSuspendFunInt(fn: suspend () -> String): String = "" diff --git a/compiler/testData/diagnostics/tests/suspendConversion/implicitInvokeWithSpecificType.kt b/compiler/testData/diagnostics/tests/suspendConversion/implicitInvokeWithSpecificType.kt index 8e48af13d2d..d455c91db5f 100644 --- a/compiler/testData/diagnostics/tests/suspendConversion/implicitInvokeWithSpecificType.kt +++ b/compiler/testData/diagnostics/tests/suspendConversion/implicitInvokeWithSpecificType.kt @@ -1,4 +1,3 @@ -// IGNORE_DIAGNOSTIC_API // ISSUE: KT-62836 fun box() { useSuspendFunInt(Test()) diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index cc25a5a6697..25855f4c5ae 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -38358,6 +38358,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/suspendConversion/chainedFunSuspendConversionForSimpleExpression.kt"); } + @Test + @TestMetadata("implicitInvoke.kt") + public void testImplicitInvoke() { + runTest("compiler/testData/diagnostics/tests/suspendConversion/implicitInvoke.kt"); + } + @Test @TestMetadata("implicitInvokeFromChildClass.kt") public void testImplicitInvokeFromChildClass() {