Revert "Do not write version requirements for suspend functions"
This reverts commit 6807ed6642.
The reason is that Kotlin compilers until and including version 1.6.10
have code that detects obsolete coroutines via these version
requirements (see `versionAndReleaseCoroutinesMismatch`). Since Kotlin
1.6.10 can read metadata of version 1.7, the earliest we can drop these
version requirements is Kotlin 1.8.0.
This commit is contained in:
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.serialization
|
|||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.builtins.isSuspendFunctionType
|
import org.jetbrains.kotlin.builtins.isSuspendFunctionType
|
||||||
|
import org.jetbrains.kotlin.builtins.isSuspendFunctionTypeOrSubtype
|
||||||
import org.jetbrains.kotlin.builtins.transformSuspendFunctionToRuntimeFunctionType
|
import org.jetbrains.kotlin.builtins.transformSuspendFunctionToRuntimeFunctionType
|
||||||
import org.jetbrains.kotlin.config.LanguageFeature
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
@@ -330,6 +331,10 @@ class DescriptorSerializer private constructor(
|
|||||||
versionRequirementTable?.run {
|
versionRequirementTable?.run {
|
||||||
builder.addAllVersionRequirement(serializeVersionRequirements(descriptor))
|
builder.addAllVersionRequirement(serializeVersionRequirements(descriptor))
|
||||||
|
|
||||||
|
if (descriptor.isSuspendOrHasSuspendTypesInSignature()) {
|
||||||
|
builder.addVersionRequirement(writeVersionRequirementDependingOnCoroutinesVersion())
|
||||||
|
}
|
||||||
|
|
||||||
if (descriptor.hasInlineClassTypesInSignature()) {
|
if (descriptor.hasInlineClassTypesInSignature()) {
|
||||||
builder.addVersionRequirement(writeVersionRequirement(LanguageFeature.InlineClasses))
|
builder.addVersionRequirement(writeVersionRequirement(LanguageFeature.InlineClasses))
|
||||||
}
|
}
|
||||||
@@ -424,6 +429,10 @@ class DescriptorSerializer private constructor(
|
|||||||
versionRequirementTable?.run {
|
versionRequirementTable?.run {
|
||||||
builder.addAllVersionRequirement(serializeVersionRequirements(descriptor))
|
builder.addAllVersionRequirement(serializeVersionRequirements(descriptor))
|
||||||
|
|
||||||
|
if (descriptor.isSuspendOrHasSuspendTypesInSignature()) {
|
||||||
|
builder.addVersionRequirement(writeVersionRequirementDependingOnCoroutinesVersion())
|
||||||
|
}
|
||||||
|
|
||||||
if (descriptor.hasInlineClassTypesInSignature()) {
|
if (descriptor.hasInlineClassTypesInSignature()) {
|
||||||
builder.addVersionRequirement(writeVersionRequirement(LanguageFeature.InlineClasses))
|
builder.addVersionRequirement(writeVersionRequirement(LanguageFeature.InlineClasses))
|
||||||
}
|
}
|
||||||
@@ -464,6 +473,10 @@ class DescriptorSerializer private constructor(
|
|||||||
versionRequirementTable?.run {
|
versionRequirementTable?.run {
|
||||||
builder.addAllVersionRequirement(serializeVersionRequirements(descriptor))
|
builder.addAllVersionRequirement(serializeVersionRequirements(descriptor))
|
||||||
|
|
||||||
|
if (descriptor.isSuspendOrHasSuspendTypesInSignature()) {
|
||||||
|
builder.addVersionRequirement(writeVersionRequirementDependingOnCoroutinesVersion())
|
||||||
|
}
|
||||||
|
|
||||||
if (descriptor.hasInlineClassTypesInSignature()) {
|
if (descriptor.hasInlineClassTypesInSignature()) {
|
||||||
builder.addVersionRequirement(writeVersionRequirement(LanguageFeature.InlineClasses))
|
builder.addVersionRequirement(writeVersionRequirement(LanguageFeature.InlineClasses))
|
||||||
}
|
}
|
||||||
@@ -478,6 +491,15 @@ class DescriptorSerializer private constructor(
|
|||||||
return builder
|
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 {
|
private fun CallableMemberDescriptor.hasInlineClassTypesInSignature(): Boolean {
|
||||||
return allTypesFromSignature().any { type -> type.contains(UnwrappedType::isInlineClassType) }
|
return allTypesFromSignature().any { type -> type.contains(UnwrappedType::isInlineClassType) }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ class Outer {
|
|||||||
|
|
||||||
@RequireKotlin("1.3")
|
@RequireKotlin("1.3")
|
||||||
val x = ""
|
val x = ""
|
||||||
|
|
||||||
|
suspend fun s() {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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<Int, suspend () -> Unit>? = null
|
||||||
|
|
||||||
|
val (suspend () -> Unit).asyncVal: () -> Unit get() = {}
|
||||||
@@ -124,6 +124,23 @@ abstract class AbstractVersionRequirementTest : TestCaseWithTmpdir() {
|
|||||||
|
|
||||||
protected abstract fun loadModule(directory: File): ModuleDescriptor
|
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.<init>",
|
||||||
|
"test.async1",
|
||||||
|
"test.async2",
|
||||||
|
"test.async3",
|
||||||
|
"test.async4",
|
||||||
|
"test.asyncVal"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fun testDefinitelyNotNull() {
|
fun testDefinitelyNotNull() {
|
||||||
doTest(
|
doTest(
|
||||||
VersionRequirement.Version(1, 7), DeprecationLevel.ERROR, null, ProtoBuf.VersionRequirement.VersionKind.LANGUAGE_VERSION, null,
|
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.<init>",
|
"test.Outer.Inner.Deep.<init>",
|
||||||
"test.Outer.Inner.Deep.f",
|
"test.Outer.Inner.Deep.f",
|
||||||
"test.Outer.Inner.Deep.x",
|
"test.Outer.Inner.Deep.x",
|
||||||
|
"test.Outer.Inner.Deep.s",
|
||||||
"test.Outer.Nested.g",
|
"test.Outer.Nested.g",
|
||||||
"test.Outer.Companion"
|
"test.Outer.Companion"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ public final class SimpleClass<in T#0 /* A */> : kotlin/Any {
|
|||||||
// signature: <init>(I)V
|
// signature: <init>(I)V
|
||||||
public constructor(p: kotlin/Int /* = ... */)
|
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;
|
// signature: g(Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
protected final inline suspend fun <reified T#1 /* T */> g(crossinline a: kotlin/Function0<T#0>, noinline b: suspend kotlin/Function1<kotlin/coroutines/Continuation<T#1>, kotlin/Any?>): kotlin/Unit
|
protected final inline suspend fun <reified T#1 /* T */> g(crossinline a: kotlin/Function0<T#0>, noinline b: suspend kotlin/Function1<kotlin/coroutines/Continuation<T#1>, kotlin/Any?>): kotlin/Unit
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ public final value class A : kotlin/Any {
|
|||||||
// requires language version 1.3.0 (level=ERROR)
|
// requires language version 1.3.0 (level=ERROR)
|
||||||
public final value class B : kotlin/Any {
|
public final value class B : kotlin/Any {
|
||||||
|
|
||||||
|
// requires language version 1.3.0 (level=ERROR)
|
||||||
// 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;
|
// signature: constructor-impl(Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function1;
|
||||||
public constructor(f: suspend kotlin/Function1<kotlin/coroutines/Continuation<kotlin/Unit>, kotlin/Any?>)
|
public constructor(f: suspend kotlin/Function1<kotlin/coroutines/Continuation<kotlin/Unit>, kotlin/Any?>)
|
||||||
@@ -44,6 +45,7 @@ public final value class B : kotlin/Any {
|
|||||||
// signature: toString-impl(Lkotlin/jvm/functions/Function1;)Ljava/lang/String;
|
// signature: toString-impl(Lkotlin/jvm/functions/Function1;)Ljava/lang/String;
|
||||||
public open /* synthesized */ fun toString(): kotlin/String
|
public open /* synthesized */ fun toString(): kotlin/String
|
||||||
|
|
||||||
|
// requires language version 1.3.0 (level=ERROR)
|
||||||
// field: f:Lkotlin/jvm/functions/Function1;
|
// field: f:Lkotlin/jvm/functions/Function1;
|
||||||
private final val f: suspend kotlin/Function1<kotlin/coroutines/Continuation<kotlin/Unit>, kotlin/Any?>
|
private final val f: suspend kotlin/Function1<kotlin/coroutines/Continuation<kotlin/Unit>, kotlin/Any?>
|
||||||
private final get
|
private final get
|
||||||
|
|||||||
Reference in New Issue
Block a user