diff --git a/compiler/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializer.kt b/compiler/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializer.kt index 7fabc07f5c5..6bb22bfd09d 100644 --- a/compiler/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializer.kt +++ b/compiler/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializer.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.serialization import com.intellij.openapi.project.Project import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.isSuspendFunctionType +import org.jetbrains.kotlin.builtins.isSuspendFunctionTypeOrSubtype import org.jetbrains.kotlin.builtins.transformSuspendFunctionToRuntimeFunctionType import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.descriptors.* @@ -330,6 +331,10 @@ class DescriptorSerializer private constructor( versionRequirementTable?.run { builder.addAllVersionRequirement(serializeVersionRequirements(descriptor)) + if (descriptor.isSuspendOrHasSuspendTypesInSignature()) { + builder.addVersionRequirement(writeVersionRequirementDependingOnCoroutinesVersion()) + } + if (descriptor.hasInlineClassTypesInSignature()) { builder.addVersionRequirement(writeVersionRequirement(LanguageFeature.InlineClasses)) } @@ -424,6 +429,10 @@ class DescriptorSerializer private constructor( versionRequirementTable?.run { builder.addAllVersionRequirement(serializeVersionRequirements(descriptor)) + if (descriptor.isSuspendOrHasSuspendTypesInSignature()) { + builder.addVersionRequirement(writeVersionRequirementDependingOnCoroutinesVersion()) + } + if (descriptor.hasInlineClassTypesInSignature()) { builder.addVersionRequirement(writeVersionRequirement(LanguageFeature.InlineClasses)) } @@ -464,6 +473,10 @@ class DescriptorSerializer private constructor( versionRequirementTable?.run { builder.addAllVersionRequirement(serializeVersionRequirements(descriptor)) + if (descriptor.isSuspendOrHasSuspendTypesInSignature()) { + builder.addVersionRequirement(writeVersionRequirementDependingOnCoroutinesVersion()) + } + if (descriptor.hasInlineClassTypesInSignature()) { builder.addVersionRequirement(writeVersionRequirement(LanguageFeature.InlineClasses)) } @@ -478,6 +491,15 @@ class DescriptorSerializer private constructor( return builder } + private fun MutableVersionRequirementTable.writeVersionRequirementDependingOnCoroutinesVersion(): Int = + writeVersionRequirement(LanguageFeature.ReleaseCoroutines) + + private fun CallableMemberDescriptor.isSuspendOrHasSuspendTypesInSignature(): Boolean { + if (this is FunctionDescriptor && isSuspend) return true + + return allTypesFromSignature().any { type -> type.contains(UnwrappedType::isSuspendFunctionTypeOrSubtype) } + } + private fun CallableMemberDescriptor.hasInlineClassTypesInSignature(): Boolean { return allTypesFromSignature().any { type -> type.contains(UnwrappedType::isInlineClassType) } } diff --git a/compiler/testData/versionRequirement/nestedClassMembers.kt b/compiler/testData/versionRequirement/nestedClassMembers.kt index 56a703a9169..ad651b2c192 100644 --- a/compiler/testData/versionRequirement/nestedClassMembers.kt +++ b/compiler/testData/versionRequirement/nestedClassMembers.kt @@ -12,6 +12,8 @@ class Outer { @RequireKotlin("1.3") val x = "" + + suspend fun s() {} } } diff --git a/compiler/testData/versionRequirement/suspendFun.kt b/compiler/testData/versionRequirement/suspendFun.kt new file mode 100644 index 00000000000..6e3777d81b7 --- /dev/null +++ b/compiler/testData/versionRequirement/suspendFun.kt @@ -0,0 +1,16 @@ +package test + +suspend fun topLevel() {} + +class Foo { + constructor(block: suspend () -> Unit) + + suspend fun member() {} +} + +fun async1(block: suspend () -> Unit) {} +fun (suspend () -> Unit).async2() {} +fun async3(): suspend () -> Unit = null!! +fun async4(): Map Unit>? = null + +val (suspend () -> Unit).asyncVal: () -> Unit get() = {} diff --git a/compiler/tests/org/jetbrains/kotlin/serialization/AbstractVersionRequirementTest.kt b/compiler/tests/org/jetbrains/kotlin/serialization/AbstractVersionRequirementTest.kt index ee6b9d26228..be276585535 100644 --- a/compiler/tests/org/jetbrains/kotlin/serialization/AbstractVersionRequirementTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/serialization/AbstractVersionRequirementTest.kt @@ -124,6 +124,23 @@ abstract class AbstractVersionRequirementTest : TestCaseWithTmpdir() { protected abstract fun loadModule(directory: File): ModuleDescriptor + fun testSuspendFun() { + doTest( + VersionRequirement.Version(1, 3), DeprecationLevel.ERROR, null, ProtoBuf.VersionRequirement.VersionKind.LANGUAGE_VERSION, null, + customLanguageVersion = LanguageVersion.KOTLIN_1_3, + fqNamesWithRequirements = listOf( + "test.topLevel", + "test.Foo.member", + "test.Foo.", + "test.async1", + "test.async2", + "test.async3", + "test.async4", + "test.asyncVal" + ) + ) + } + fun testDefinitelyNotNull() { doTest( VersionRequirement.Version(1, 7), DeprecationLevel.ERROR, null, ProtoBuf.VersionRequirement.VersionKind.LANGUAGE_VERSION, null, @@ -204,6 +221,7 @@ abstract class AbstractVersionRequirementTest : TestCaseWithTmpdir() { "test.Outer.Inner.Deep.", "test.Outer.Inner.Deep.f", "test.Outer.Inner.Deep.x", + "test.Outer.Inner.Deep.s", "test.Outer.Nested.g", "test.Outer.Companion" ) diff --git a/libraries/tools/kotlinp/testData/SimpleClass.txt b/libraries/tools/kotlinp/testData/SimpleClass.txt index b63fda4f5a8..fb4d10a3e71 100644 --- a/libraries/tools/kotlinp/testData/SimpleClass.txt +++ b/libraries/tools/kotlinp/testData/SimpleClass.txt @@ -8,6 +8,7 @@ public final class SimpleClass : kotlin/Any { // signature: (I)V public constructor(p: kotlin/Int /* = ... */) + // requires language version 1.3.0 (level=ERROR) // signature: g(Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; protected final inline suspend fun g(crossinline a: kotlin/Function0, noinline b: suspend kotlin/Function1, kotlin/Any?>): kotlin/Unit diff --git a/libraries/tools/kotlinp/testData/ValueClass.txt b/libraries/tools/kotlinp/testData/ValueClass.txt index 34a76f8efe8..6392bcbf063 100644 --- a/libraries/tools/kotlinp/testData/ValueClass.txt +++ b/libraries/tools/kotlinp/testData/ValueClass.txt @@ -31,6 +31,7 @@ public final value class A : kotlin/Any { // requires language version 1.3.0 (level=ERROR) public final value class B : kotlin/Any { + // requires language version 1.3.0 (level=ERROR) // requires language version 1.3.0 (level=ERROR) // signature: constructor-impl(Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function1; public constructor(f: suspend kotlin/Function1, kotlin/Any?>) @@ -44,6 +45,7 @@ public final value class B : kotlin/Any { // signature: toString-impl(Lkotlin/jvm/functions/Function1;)Ljava/lang/String; public open /* synthesized */ fun toString(): kotlin/String + // requires language version 1.3.0 (level=ERROR) // field: f:Lkotlin/jvm/functions/Function1; private final val f: suspend kotlin/Function1, kotlin/Any?> private final get