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 fea5427b4cf..ab5f15c2844 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 @@ -32016,6 +32016,18 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia runTest("compiler/testData/diagnostics/tests/subtyping/nestedLocalClasses.kt"); } + @Test + @TestMetadata("suspendExtFunctionTypeAsSuperType.kt") + public void testSuspendExtFunctionTypeAsSuperType() throws Exception { + runTest("compiler/testData/diagnostics/tests/subtyping/suspendExtFunctionTypeAsSuperType.kt"); + } + + @Test + @TestMetadata("suspendExtFunctionTypeAsSuperTypeRestrictionLifted.kt") + public void testSuspendExtFunctionTypeAsSuperTypeRestrictionLifted() throws Exception { + runTest("compiler/testData/diagnostics/tests/subtyping/suspendExtFunctionTypeAsSuperTypeRestrictionLifted.kt"); + } + @Test @TestMetadata("topLevelAnonymousObjects.kt") public void testTopLevelAnonymousObjects() throws Exception { 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 1490ed90802..c632124629e 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 @@ -32016,6 +32016,18 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated runTest("compiler/testData/diagnostics/tests/subtyping/nestedLocalClasses.kt"); } + @Test + @TestMetadata("suspendExtFunctionTypeAsSuperType.kt") + public void testSuspendExtFunctionTypeAsSuperType() throws Exception { + runTest("compiler/testData/diagnostics/tests/subtyping/suspendExtFunctionTypeAsSuperType.kt"); + } + + @Test + @TestMetadata("suspendExtFunctionTypeAsSuperTypeRestrictionLifted.kt") + public void testSuspendExtFunctionTypeAsSuperTypeRestrictionLifted() throws Exception { + runTest("compiler/testData/diagnostics/tests/subtyping/suspendExtFunctionTypeAsSuperTypeRestrictionLifted.kt"); + } + @Test @TestMetadata("topLevelAnonymousObjects.kt") public void testTopLevelAnonymousObjects() throws Exception { 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 a81583c91c9..f810a018eaf 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 @@ -32016,6 +32016,18 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir runTest("compiler/testData/diagnostics/tests/subtyping/nestedLocalClasses.kt"); } + @Test + @TestMetadata("suspendExtFunctionTypeAsSuperType.kt") + public void testSuspendExtFunctionTypeAsSuperType() throws Exception { + runTest("compiler/testData/diagnostics/tests/subtyping/suspendExtFunctionTypeAsSuperType.kt"); + } + + @Test + @TestMetadata("suspendExtFunctionTypeAsSuperTypeRestrictionLifted.kt") + public void testSuspendExtFunctionTypeAsSuperTypeRestrictionLifted() throws Exception { + runTest("compiler/testData/diagnostics/tests/subtyping/suspendExtFunctionTypeAsSuperTypeRestrictionLifted.kt"); + } + @Test @TestMetadata("topLevelAnonymousObjects.kt") public void testTopLevelAnonymousObjects() throws Exception { 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 7cd0578a4a6..9949b2ed945 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 @@ -32112,6 +32112,18 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia runTest("compiler/testData/diagnostics/tests/subtyping/nestedLocalClasses.kt"); } + @Test + @TestMetadata("suspendExtFunctionTypeAsSuperType.kt") + public void testSuspendExtFunctionTypeAsSuperType() throws Exception { + runTest("compiler/testData/diagnostics/tests/subtyping/suspendExtFunctionTypeAsSuperType.kt"); + } + + @Test + @TestMetadata("suspendExtFunctionTypeAsSuperTypeRestrictionLifted.kt") + public void testSuspendExtFunctionTypeAsSuperTypeRestrictionLifted() throws Exception { + runTest("compiler/testData/diagnostics/tests/subtyping/suspendExtFunctionTypeAsSuperTypeRestrictionLifted.kt"); + } + @Test @TestMetadata("topLevelAnonymousObjects.kt") public void testTopLevelAnonymousObjects() throws Exception { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index 42c74353186..f864472a8da 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -390,6 +390,8 @@ public interface Errors { DiagnosticFactory0 SUPERTYPE_NOT_A_CLASS_OR_INTERFACE = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 SUPERTYPE_IS_EXTENSION_FUNCTION_TYPE = DiagnosticFactory0.create(ERROR); + + DiagnosticFactory0 SUPERTYPE_IS_SUSPEND_EXTENSION_FUNCTION_TYPE = DiagnosticFactory0.create(WARNING); DiagnosticFactory0 SUPERTYPE_IS_SUSPEND_FUNCTION_TYPE = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 SUPERTYPE_IS_KSUSPEND_FUNCTION_TYPE = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 MIXING_SUSPEND_AND_NON_SUSPEND_SUPERTYPES = DiagnosticFactory0.create(ERROR); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java index 2dcb8b156a3..905f8e6ad3b 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -741,6 +741,7 @@ public class DefaultErrorMessages { MAP.put(MANY_CLASSES_IN_SUPERTYPE_LIST, "Only one class may appear in a supertype list"); MAP.put(SUPERTYPE_NOT_A_CLASS_OR_INTERFACE, "Only classes and interfaces may serve as supertypes"); MAP.put(SUPERTYPE_IS_EXTENSION_FUNCTION_TYPE, "Extension function type is not allowed as supertypes"); + MAP.put(SUPERTYPE_IS_SUSPEND_EXTENSION_FUNCTION_TYPE, "Suspend extension function type is not allowed as supertypes. Such code will become error in future releases."); MAP.put(SUPERTYPE_INITIALIZED_IN_INTERFACE, "Interfaces cannot initialize supertypes"); MAP.put(SUPERTYPE_IS_SUSPEND_FUNCTION_TYPE, "Suspend function type is allowed as a supertype only since version 1.6"); MAP.put(SUPERTYPE_IS_KSUSPEND_FUNCTION_TYPE, "KSuspendFunctionN interfaces are not allowed as supertypes"); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BodyResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BodyResolver.java index 6adbd9739f3..caafe6df309 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BodyResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BodyResolver.java @@ -591,6 +591,11 @@ public class BodyResolver { ) { trace.report(SUPERTYPE_IS_EXTENSION_FUNCTION_TYPE.on(typeReference)); } + else if (FunctionTypesKt.isSuspendExtensionFunctionType(supertype) && + !languageVersionSettings.supportsFeature(LanguageFeature.FunctionalTypeWithExtensionAsSupertype) && + languageVersionSettings.supportsFeature(LanguageFeature.SuspendFunctionAsSupertype)) { + trace.report(SUPERTYPE_IS_SUSPEND_EXTENSION_FUNCTION_TYPE.on(typeReference)); + } else if (FunctionTypesKt.isSuspendFunctionType(supertype) && !languageVersionSettings.supportsFeature(LanguageFeature.SuspendFunctionAsSupertype) ) { diff --git a/compiler/testData/diagnostics/tests/subtyping/suspendExtFunctionTypeAsSuperType.fir.kt b/compiler/testData/diagnostics/tests/subtyping/suspendExtFunctionTypeAsSuperType.fir.kt new file mode 100644 index 00000000000..0668ddf1bc6 --- /dev/null +++ b/compiler/testData/diagnostics/tests/subtyping/suspendExtFunctionTypeAsSuperType.fir.kt @@ -0,0 +1,24 @@ +class A : suspend Double.() -> Unit { + override suspend fun invoke(p1: Double) {} +} + +class B : suspend Int.(Double) -> Unit { + override suspend fun invoke(p1: Int, p2: Double) {} +} + +open class C {} + +abstract class A0 : suspend C.() -> Int +abstract class A1 : suspend C.(Int) -> Int +abstract class A2 : suspend C.(Int, String) -> Int + +open class D {} + +abstract class B0 : suspend D.() -> Int +abstract class B1 : suspend D.(C) -> Int +abstract class B2 : suspend D.(T, C) -> T + +interface E {} + +abstract class C0: C(), suspend Int.() -> Double +abstract class C1: C(), E, suspend Int.(C) -> Double \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/subtyping/suspendExtFunctionTypeAsSuperType.kt b/compiler/testData/diagnostics/tests/subtyping/suspendExtFunctionTypeAsSuperType.kt new file mode 100644 index 00000000000..2d5e25cc804 --- /dev/null +++ b/compiler/testData/diagnostics/tests/subtyping/suspendExtFunctionTypeAsSuperType.kt @@ -0,0 +1,24 @@ +class A : suspend Double.() -> Unit { + override suspend fun invoke(p1: Double) {} +} + +class B : suspend Int.(Double) -> Unit { + override suspend fun invoke(p1: Int, p2: Double) {} +} + +open class C {} + +abstract class A0 : suspend C.() -> Int +abstract class A1 : suspend C.(Int) -> Int +abstract class A2 : suspend C.(Int, String) -> Int + +open class D {} + +abstract class B0 : suspend D.() -> Int +abstract class B1 : suspend D.(C) -> Int +abstract class B2 : suspend D.(T, C) -> T + +interface E {} + +abstract class C0: C(), suspend Int.() -> Double +abstract class C1: C(), E, suspend Int.(C) -> Double diff --git a/compiler/testData/diagnostics/tests/subtyping/suspendExtFunctionTypeAsSuperTypeRestrictionLifted.kt b/compiler/testData/diagnostics/tests/subtyping/suspendExtFunctionTypeAsSuperTypeRestrictionLifted.kt new file mode 100644 index 00000000000..fda063735c9 --- /dev/null +++ b/compiler/testData/diagnostics/tests/subtyping/suspendExtFunctionTypeAsSuperTypeRestrictionLifted.kt @@ -0,0 +1,26 @@ +// FIR_IDENTICAL +// !LANGUAGE: +FunctionalTypeWithExtensionAsSupertype +class A : suspend Double.() -> Unit { + override suspend fun invoke(p1: Double) {} +} + +class B : suspend Int.(Double) -> Unit { + override suspend fun invoke(p1: Int, p2: Double) {} +} + +open class C {} + +abstract class A0 : suspend C.() -> Int +abstract class A1 : suspend C.(Int) -> Int +abstract class A2 : suspend C.(Int, String) -> Int + +open class D {} + +abstract class B0 : suspend D.() -> Int +abstract class B1 : suspend D.(C) -> Int +abstract class B2 : suspend D.(T, C) -> T + +interface E {} + +abstract class C0: C(), suspend Int.() -> Double +abstract class C1: C(), E, suspend Int.(C) -> Double 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 68254e76d5f..9c8f6df2e67 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 @@ -32884,6 +32884,18 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/subtyping/nestedLocalClasses.kt"); } + @Test + @TestMetadata("suspendExtFunctionTypeAsSuperType.kt") + public void testSuspendExtFunctionTypeAsSuperType() throws Exception { + runTest("compiler/testData/diagnostics/tests/subtyping/suspendExtFunctionTypeAsSuperType.kt"); + } + + @Test + @TestMetadata("suspendExtFunctionTypeAsSuperTypeRestrictionLifted.kt") + public void testSuspendExtFunctionTypeAsSuperTypeRestrictionLifted() throws Exception { + runTest("compiler/testData/diagnostics/tests/subtyping/suspendExtFunctionTypeAsSuperTypeRestrictionLifted.kt"); + } + @Test @TestMetadata("topLevelAnonymousObjects.kt") public void testTopLevelAnonymousObjects() throws Exception { diff --git a/core/descriptors/src/org/jetbrains/kotlin/builtins/functionTypes.kt b/core/descriptors/src/org/jetbrains/kotlin/builtins/functionTypes.kt index 1f0aee7f93d..3ed4677f943 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/builtins/functionTypes.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/builtins/functionTypes.kt @@ -104,6 +104,9 @@ val KotlinType.isNonExtensionFunctionType: Boolean val KotlinType.isExtensionFunctionType: Boolean get() = isFunctionType && isTypeAnnotatedWithExtensionFunctionType +val KotlinType.isSuspendExtensionFunctionType: Boolean + get() = isSuspendFunctionType && isTypeAnnotatedWithExtensionFunctionType + val KotlinType.isBuiltinExtensionFunctionalType: Boolean get() = isBuiltinFunctionalType && isTypeAnnotatedWithExtensionFunctionType