Do not write version requirements for suspend functions

Coroutines are a stable feature since 1.3. Version requirement on
suspend functions, or functions mentioning suspend function types in the
signature, was needed to prevent older compilers from reading metadata
that they can't properly use. It's not needed anymore because a newer
metadata version prevents older compilers from reading any metadata
altogether.

Also, computing isSuspendOrHasSuspendTypesInSignature took ~0.5% of
backend time on compilation of intellij (related to KT-48233).
This commit is contained in:
Alexander Udalov
2021-12-14 21:56:08 +01:00
parent 8863d48595
commit 6807ed6642
6 changed files with 0 additions and 61 deletions
@@ -8,7 +8,6 @@ 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.*
@@ -331,10 +330,6 @@ 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))
} }
@@ -429,10 +424,6 @@ 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))
} }
@@ -473,10 +464,6 @@ 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))
} }
@@ -491,15 +478,6 @@ 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,8 +12,6 @@ class Outer {
@RequireKotlin("1.3") @RequireKotlin("1.3")
val x = "" val x = ""
suspend fun s() {}
} }
} }
-16
View File
@@ -1,16 +0,0 @@
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,23 +124,6 @@ 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,
@@ -221,7 +204,6 @@ 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"
) )
-1
View File
@@ -8,7 +8,6 @@ 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
-2
View File
@@ -31,7 +31,6 @@ 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?>)
@@ -45,7 +44,6 @@ 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