Allow calling some pieces of the experimental coroutine API
- Calling suspend functions is allowed - Presence of suspend function type still makes declaration unusable unless it belongs to a value parameter as a top-level type containing less then three parameters Still, warning should be emitted because they will become unsupported in 1.4 #KT-25683 In Progress
This commit is contained in:
@@ -44,6 +44,7 @@ import org.jetbrains.kotlin.resolve.constants.StringValue
|
|||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedMemberDescriptor
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedMemberDescriptor
|
||||||
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedMemberDescriptor.CoroutinesCompatibilityMode.*
|
||||||
import org.jetbrains.kotlin.storage.StorageManager
|
import org.jetbrains.kotlin.storage.StorageManager
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.TypeUtils
|
import org.jetbrains.kotlin.types.TypeUtils
|
||||||
@@ -104,10 +105,14 @@ private data class DeprecatedByOverridden(private val deprecations: Collection<D
|
|||||||
}
|
}
|
||||||
|
|
||||||
private data class DeprecatedExperimentalCoroutine(
|
private data class DeprecatedExperimentalCoroutine(
|
||||||
override val target: DeclarationDescriptor
|
override val target: DeclarationDescriptor,
|
||||||
|
override val deprecationLevel: DeprecationLevelValue
|
||||||
) : Deprecation {
|
) : Deprecation {
|
||||||
override val deprecationLevel: DeprecationLevelValue = DeprecationLevelValue.ERROR
|
override val message: String? =
|
||||||
override val message: String? = "Experimental coroutine cannot be used with API version 1.3"
|
if (deprecationLevel == WARNING)
|
||||||
|
"Experimental coroutines support will be dropped in 1.4"
|
||||||
|
else
|
||||||
|
"Experimental coroutine cannot be used with API version 1.3"
|
||||||
}
|
}
|
||||||
|
|
||||||
private data class DeprecatedByVersionRequirement(
|
private data class DeprecatedByVersionRequirement(
|
||||||
@@ -300,7 +305,7 @@ class DeprecationResolver(
|
|||||||
|
|
||||||
fun addDeprecationIfPresent(target: DeclarationDescriptor) {
|
fun addDeprecationIfPresent(target: DeclarationDescriptor) {
|
||||||
val annotation = target.annotations.findAnnotation(KotlinBuiltIns.FQ_NAMES.deprecated)
|
val annotation = target.annotations.findAnnotation(KotlinBuiltIns.FQ_NAMES.deprecated)
|
||||||
?: target.annotations.findAnnotation(JAVA_DEPRECATED)
|
?: target.annotations.findAnnotation(JAVA_DEPRECATED)
|
||||||
if (annotation != null) {
|
if (annotation != null) {
|
||||||
val deprecatedByAnnotation = DeprecatedByAnnotation(annotation, target)
|
val deprecatedByAnnotation = DeprecatedByAnnotation(annotation, target)
|
||||||
val deprecation = when (target) {
|
val deprecation = when (target) {
|
||||||
@@ -323,7 +328,7 @@ class DeprecationResolver(
|
|||||||
useSiteTarget,
|
useSiteTarget,
|
||||||
KotlinBuiltIns.FQ_NAMES.deprecated
|
KotlinBuiltIns.FQ_NAMES.deprecated
|
||||||
)
|
)
|
||||||
?: Annotations.findUseSiteTargetedAnnotation(annotatedDescriptor.annotations, useSiteTarget, JAVA_DEPRECATED)
|
?: Annotations.findUseSiteTargetedAnnotation(annotatedDescriptor.annotations, useSiteTarget, JAVA_DEPRECATED)
|
||||||
if (annotation != null) {
|
if (annotation != null) {
|
||||||
result.add(DeprecatedByAnnotation(annotation, this))
|
result.add(DeprecatedByAnnotation(annotation, this))
|
||||||
}
|
}
|
||||||
@@ -353,10 +358,14 @@ class DeprecationResolver(
|
|||||||
return result.distinct()
|
return result.distinct()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getDeprecationByCoroutinesVersion(target: DeclarationDescriptor): DeprecatedExperimentalCoroutine? =
|
private fun getDeprecationByCoroutinesVersion(target: DeclarationDescriptor): DeprecatedExperimentalCoroutine? {
|
||||||
if (target is DeserializedMemberDescriptor && target.isExperimentalCoroutineInReleaseEnvironment)
|
if (target !is DeserializedMemberDescriptor) return null
|
||||||
DeprecatedExperimentalCoroutine(target)
|
return when (target.coroutinesExperimentalCompatibilityMode) {
|
||||||
else null
|
COMPATIBLE -> null
|
||||||
|
NEEDS_WRAPPER -> DeprecatedExperimentalCoroutine(target, WARNING)
|
||||||
|
INCOMPATIBLE -> DeprecatedExperimentalCoroutine(target, ERROR)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun getDeprecationByVersionRequirement(target: DeclarationDescriptor): List<DeprecatedByVersionRequirement> {
|
private fun getDeprecationByVersionRequirement(target: DeclarationDescriptor): List<DeprecatedByVersionRequirement> {
|
||||||
fun createVersion(version: String): MavenComparableVersion? = try {
|
fun createVersion(version: String): MavenComparableVersion? = try {
|
||||||
|
|||||||
+7
-20
@@ -1,27 +1,14 @@
|
|||||||
suspend fun dummy() {}
|
|
||||||
|
|
||||||
class C {
|
|
||||||
suspend fun dummy() = "OK"
|
|
||||||
}
|
|
||||||
|
|
||||||
class WithNested {
|
|
||||||
class Nested {
|
|
||||||
suspend fun dummy() = "OK"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class WithInner {
|
|
||||||
inner class Inner {
|
|
||||||
suspend fun dummy() = "OK"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val c: suspend () -> Unit = {}
|
val c: suspend () -> Unit = {}
|
||||||
|
|
||||||
class WithTypeParameter<T: suspend() -> Unit> {}
|
class WithTypeParameter<T: suspend() -> Unit> {}
|
||||||
|
|
||||||
fun returnsSuspend() : suspend() -> Unit = {}
|
fun returnsSuspend() : suspend() -> Unit = {}
|
||||||
|
|
||||||
fun builder(c: suspend () -> Unit) {}
|
|
||||||
|
|
||||||
fun <T: suspend () -> Unit> withTypeParameter() = {}
|
fun <T: suspend () -> Unit> withTypeParameter() = {}
|
||||||
|
|
||||||
|
fun suspendFunctionNested(x: List<suspend () -> Unit>) {}
|
||||||
|
fun suspendFunctionNestedInFunctionType(x: (suspend () -> Unit) -> Unit) {}
|
||||||
|
|
||||||
|
fun suspendFunctionType3(x: suspend (Int, Int, Int) -> Unit) {}
|
||||||
|
|
||||||
|
fun suspendVarargs(vararg x: suspend () -> Unit) {}
|
||||||
|
|||||||
compiler/testData/compileKotlinAgainstCustomBinaries/experimentalCoroutineCallFromRelease/output.txt
Vendored
+21
-20
@@ -1,29 +1,30 @@
|
|||||||
warning: language version 1.3 is experimental, there are no backwards compatibility guarantees for new language and library features
|
warning: language version 1.3 is experimental, there are no backwards compatibility guarantees for new language and library features
|
||||||
compiler/testData/compileKotlinAgainstCustomBinaries/experimentalCoroutineCallFromRelease/release.kt:2:5: error: using 'c: suspend () -> Unit' is an error. Experimental coroutine cannot be used with API version 1.3
|
warning: runtime JAR files in the classpath should have the same version. These files were found in the classpath:
|
||||||
c()
|
$DIST_DIR$/kotlin-stdlib-coroutines.jar (version 1.3)
|
||||||
^
|
$PROJECT_DIR$/lib/kotlin-stdlib.jar (version 1.2)
|
||||||
compiler/testData/compileKotlinAgainstCustomBinaries/experimentalCoroutineCallFromRelease/release.kt:3:5: error: using 'constructor WithTypeParameter<T : suspend () -> Unit>()' is an error. Experimental coroutine cannot be used with API version 1.3
|
$PROJECT_DIR$/lib/kotlin-script-runtime.jar (version 1.2)
|
||||||
|
$PROJECT_DIR$/lib/kotlin-reflect.jar (version 1.2)
|
||||||
|
warning: consider providing an explicit dependency on kotlin-reflect 1.3 to prevent strange errors
|
||||||
|
warning: some runtime JAR files in the classpath have an incompatible version. Consider removing them from the classpath
|
||||||
|
compiler/testData/compileKotlinAgainstCustomBinaries/experimentalCoroutineCallFromRelease/release.kt:2:5: error: using 'constructor WithTypeParameter<T : suspend () -> Unit>()' is an error. Experimental coroutine cannot be used with API version 1.3
|
||||||
WithTypeParameter<suspend () -> Unit>()
|
WithTypeParameter<suspend () -> Unit>()
|
||||||
^
|
^
|
||||||
compiler/testData/compileKotlinAgainstCustomBinaries/experimentalCoroutineCallFromRelease/release.kt:4:5: error: using 'returnsSuspend(): suspend () -> Unit' is an error. Experimental coroutine cannot be used with API version 1.3
|
compiler/testData/compileKotlinAgainstCustomBinaries/experimentalCoroutineCallFromRelease/release.kt:3:5: error: using 'returnsSuspend(): suspend () -> Unit' is an error. Experimental coroutine cannot be used with API version 1.3
|
||||||
returnsSuspend()
|
returnsSuspend()
|
||||||
^
|
^
|
||||||
compiler/testData/compileKotlinAgainstCustomBinaries/experimentalCoroutineCallFromRelease/release.kt:5:5: error: using 'builder(suspend () -> Unit): Unit' is an error. Experimental coroutine cannot be used with API version 1.3
|
compiler/testData/compileKotlinAgainstCustomBinaries/experimentalCoroutineCallFromRelease/release.kt:4:5: error: using 'withTypeParameter(): () -> Unit' is an error. Experimental coroutine cannot be used with API version 1.3
|
||||||
builder {}
|
|
||||||
^
|
|
||||||
compiler/testData/compileKotlinAgainstCustomBinaries/experimentalCoroutineCallFromRelease/release.kt:6:5: error: using 'withTypeParameter(): () -> Unit' is an error. Experimental coroutine cannot be used with API version 1.3
|
|
||||||
withTypeParameter<suspend () -> Unit>()
|
withTypeParameter<suspend () -> Unit>()
|
||||||
^
|
^
|
||||||
compiler/testData/compileKotlinAgainstCustomBinaries/experimentalCoroutineCallFromRelease/release.kt:8:5: error: using 'dummy(): Unit' is an error. Experimental coroutine cannot be used with API version 1.3
|
compiler/testData/compileKotlinAgainstCustomBinaries/experimentalCoroutineCallFromRelease/release.kt:6:5: error: using 'suspendFunctionNested(List<suspend () -> Unit>): Unit' is an error. Experimental coroutine cannot be used with API version 1.3
|
||||||
dummy()
|
suspendFunctionNested(listOf(suspend { }))
|
||||||
|
^
|
||||||
|
compiler/testData/compileKotlinAgainstCustomBinaries/experimentalCoroutineCallFromRelease/release.kt:7:5: error: using 'suspendFunctionNestedInFunctionType((suspend () -> Unit) -> Unit): Unit' is an error. Experimental coroutine cannot be used with API version 1.3
|
||||||
|
suspendFunctionNestedInFunctionType {}
|
||||||
|
^
|
||||||
|
compiler/testData/compileKotlinAgainstCustomBinaries/experimentalCoroutineCallFromRelease/release.kt:8:5: error: using 'suspendFunctionType3(suspend (Int, Int, Int) -> Unit): Unit' is an error. Experimental coroutine cannot be used with API version 1.3
|
||||||
|
suspendFunctionType3 { x, y, z -> }
|
||||||
|
^
|
||||||
|
compiler/testData/compileKotlinAgainstCustomBinaries/experimentalCoroutineCallFromRelease/release.kt:10:5: error: using 'suspendVarargs(vararg suspend () -> Unit): Unit' is an error. Experimental coroutine cannot be used with API version 1.3
|
||||||
|
suspendVarargs({}, {})
|
||||||
^
|
^
|
||||||
compiler/testData/compileKotlinAgainstCustomBinaries/experimentalCoroutineCallFromRelease/release.kt:9:9: error: using 'dummy(): String' is an error. Experimental coroutine cannot be used with API version 1.3
|
|
||||||
C().dummy()
|
|
||||||
^
|
|
||||||
compiler/testData/compileKotlinAgainstCustomBinaries/experimentalCoroutineCallFromRelease/release.kt:10:25: error: using 'dummy(): String' is an error. Experimental coroutine cannot be used with API version 1.3
|
|
||||||
WithNested.Nested().dummy()
|
|
||||||
^
|
|
||||||
compiler/testData/compileKotlinAgainstCustomBinaries/experimentalCoroutineCallFromRelease/release.kt:11:25: error: using 'dummy(): String' is an error. Experimental coroutine cannot be used with API version 1.3
|
|
||||||
WithInner().Inner().dummy()
|
|
||||||
^
|
|
||||||
COMPILATION_ERROR
|
COMPILATION_ERROR
|
||||||
|
|||||||
compiler/testData/compileKotlinAgainstCustomBinaries/experimentalCoroutineCallFromRelease/release.kt
Vendored
+5
-6
@@ -1,12 +1,11 @@
|
|||||||
suspend fun callRelease() {
|
suspend fun callRelease() {
|
||||||
c()
|
|
||||||
WithTypeParameter<suspend () -> Unit>()
|
WithTypeParameter<suspend () -> Unit>()
|
||||||
returnsSuspend()
|
returnsSuspend()
|
||||||
builder {}
|
|
||||||
withTypeParameter<suspend () -> Unit>()
|
withTypeParameter<suspend () -> Unit>()
|
||||||
|
|
||||||
dummy()
|
suspendFunctionNested(listOf(suspend { }))
|
||||||
C().dummy()
|
suspendFunctionNestedInFunctionType {}
|
||||||
WithNested.Nested().dummy()
|
suspendFunctionType3 { x, y, z -> }
|
||||||
WithInner().Inner().dummy()
|
|
||||||
|
suspendVarargs({}, {})
|
||||||
}
|
}
|
||||||
|
|||||||
+24
@@ -0,0 +1,24 @@
|
|||||||
|
suspend fun dummy() {}
|
||||||
|
|
||||||
|
class C {
|
||||||
|
suspend fun dummy() = "OK"
|
||||||
|
}
|
||||||
|
|
||||||
|
class WithNested {
|
||||||
|
class Nested {
|
||||||
|
suspend fun dummy() = "OK"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class WithInner {
|
||||||
|
inner class Inner {
|
||||||
|
suspend fun dummy() = "OK"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun builder(c: suspend () -> Unit) {}
|
||||||
|
fun builder2(c: suspend Int.(String) -> Unit) {}
|
||||||
|
|
||||||
|
fun (suspend (Int) -> Unit).start() {}
|
||||||
|
|
||||||
|
suspend fun suspendAcceptsSuspend(x: suspend () -> Unit) {}
|
||||||
+33
@@ -0,0 +1,33 @@
|
|||||||
|
warning: language version 1.3 is experimental, there are no backwards compatibility guarantees for new language and library features
|
||||||
|
warning: runtime JAR files in the classpath should have the same version. These files were found in the classpath:
|
||||||
|
$DIST_DIR$/kotlin-stdlib-coroutines.jar (version 1.3)
|
||||||
|
$PROJECT_DIR$/lib/kotlin-stdlib.jar (version 1.2)
|
||||||
|
$PROJECT_DIR$/lib/kotlin-script-runtime.jar (version 1.2)
|
||||||
|
$PROJECT_DIR$/lib/kotlin-reflect.jar (version 1.2)
|
||||||
|
warning: consider providing an explicit dependency on kotlin-reflect 1.3 to prevent strange errors
|
||||||
|
warning: some runtime JAR files in the classpath have an incompatible version. Consider removing them from the classpath
|
||||||
|
compiler/testData/compileKotlinAgainstCustomBinaries/experimentalCoroutineCallFromReleaseWarnings/release.kt:2:5: warning: 'builder(suspend () -> Unit): Unit' is deprecated. Experimental coroutines support will be dropped in 1.4
|
||||||
|
builder {}
|
||||||
|
^
|
||||||
|
compiler/testData/compileKotlinAgainstCustomBinaries/experimentalCoroutineCallFromReleaseWarnings/release.kt:3:5: warning: 'builder2(suspend Int.(String) -> Unit): Unit' is deprecated. Experimental coroutines support will be dropped in 1.4
|
||||||
|
builder2 { }
|
||||||
|
^
|
||||||
|
compiler/testData/compileKotlinAgainstCustomBinaries/experimentalCoroutineCallFromReleaseWarnings/release.kt:6:7: warning: 'start(): Unit' is deprecated. Experimental coroutines support will be dropped in 1.4
|
||||||
|
x.start()
|
||||||
|
^
|
||||||
|
compiler/testData/compileKotlinAgainstCustomBinaries/experimentalCoroutineCallFromReleaseWarnings/release.kt:8:5: warning: 'dummy(): Unit' is deprecated. Experimental coroutines support will be dropped in 1.4
|
||||||
|
dummy()
|
||||||
|
^
|
||||||
|
compiler/testData/compileKotlinAgainstCustomBinaries/experimentalCoroutineCallFromReleaseWarnings/release.kt:9:9: warning: 'dummy(): String' is deprecated. Experimental coroutines support will be dropped in 1.4
|
||||||
|
C().dummy()
|
||||||
|
^
|
||||||
|
compiler/testData/compileKotlinAgainstCustomBinaries/experimentalCoroutineCallFromReleaseWarnings/release.kt:10:25: warning: 'dummy(): String' is deprecated. Experimental coroutines support will be dropped in 1.4
|
||||||
|
WithNested.Nested().dummy()
|
||||||
|
^
|
||||||
|
compiler/testData/compileKotlinAgainstCustomBinaries/experimentalCoroutineCallFromReleaseWarnings/release.kt:11:25: warning: 'dummy(): String' is deprecated. Experimental coroutines support will be dropped in 1.4
|
||||||
|
WithInner().Inner().dummy()
|
||||||
|
^
|
||||||
|
compiler/testData/compileKotlinAgainstCustomBinaries/experimentalCoroutineCallFromReleaseWarnings/release.kt:13:5: warning: 'suspendAcceptsSuspend(suspend () -> Unit): Unit' is deprecated. Experimental coroutines support will be dropped in 1.4
|
||||||
|
suspendAcceptsSuspend {
|
||||||
|
^
|
||||||
|
OK
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
suspend fun callRelease() {
|
||||||
|
builder {}
|
||||||
|
builder2 { }
|
||||||
|
|
||||||
|
val x: suspend (Int) -> Unit = {}
|
||||||
|
x.start()
|
||||||
|
|
||||||
|
dummy()
|
||||||
|
C().dummy()
|
||||||
|
WithNested.Nested().dummy()
|
||||||
|
WithInner().Inner().dummy()
|
||||||
|
|
||||||
|
suspendAcceptsSuspend {
|
||||||
|
callRelease()
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
-3
@@ -24,14 +24,14 @@ fun builder(c: <!UNSUPPORTED!>suspend<!> () -> Unit) {}
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun test2() {
|
fun test2() {
|
||||||
kotlin.coroutines.experimental.<!DEPRECATION_ERROR, UNSUPPORTED!>buildSequence<!><Int> {
|
kotlin.coroutines.experimental.<!DEPRECATION, UNSUPPORTED!>buildSequence<!><Int> {
|
||||||
<!DEPRECATION_ERROR!>yield<!>(1)
|
<!DEPRECATION!>yield<!>(1)
|
||||||
}
|
}
|
||||||
kotlin.sequences.<!UNRESOLVED_REFERENCE!>buildSequence<!><Int> {
|
kotlin.sequences.<!UNRESOLVED_REFERENCE!>buildSequence<!><Int> {
|
||||||
<!UNRESOLVED_REFERENCE!>yield<!>(1)
|
<!UNRESOLVED_REFERENCE!>yield<!>(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
<!UNSUPPORTED!>suspend<!> fun test3(): Unit = kotlin.coroutines.experimental.<!DEPRECATION_ERROR!>suspendCoroutine<!> { _ -> Unit }
|
<!UNSUPPORTED!>suspend<!> fun test3(): Unit = kotlin.coroutines.experimental.<!DEPRECATION!>suspendCoroutine<!> { _ -> Unit }
|
||||||
|
|
||||||
<!UNSUPPORTED!>suspend<!> fun test4(): Unit = kotlin.coroutines.<!UNRESOLVED_REFERENCE!>suspendCoroutine<!> { <!CANNOT_INFER_PARAMETER_TYPE!>_<!> -> Unit }
|
<!UNSUPPORTED!>suspend<!> fun test4(): Unit = kotlin.coroutines.<!UNRESOLVED_REFERENCE!>suspendCoroutine<!> { <!CANNOT_INFER_PARAMETER_TYPE!>_<!> -> Unit }
|
||||||
@@ -79,6 +79,7 @@ public abstract class AbstractCliTest extends TestCaseWithTmpdir {
|
|||||||
.replace(testDataAbsoluteDir, TESTDATA_DIR)
|
.replace(testDataAbsoluteDir, TESTDATA_DIR)
|
||||||
.replace(FileUtil.toSystemIndependentName(testDataAbsoluteDir), TESTDATA_DIR)
|
.replace(FileUtil.toSystemIndependentName(testDataAbsoluteDir), TESTDATA_DIR)
|
||||||
.replace(PathUtil.getKotlinPathsForDistDirectory().getHomePath().getAbsolutePath(), "$PROJECT_DIR$")
|
.replace(PathUtil.getKotlinPathsForDistDirectory().getHomePath().getAbsolutePath(), "$PROJECT_DIR$")
|
||||||
|
.replace(PathUtil.getKotlinPathsForDistDirectory().getHomePath().getParentFile().getAbsolutePath(), "$DIST_DIR$")
|
||||||
.replace("expected version is " + JvmMetadataVersion.INSTANCE, "expected version is $ABI_VERSION$")
|
.replace("expected version is " + JvmMetadataVersion.INSTANCE, "expected version is $ABI_VERSION$")
|
||||||
.replace("expected version is " + JsMetadataVersion.INSTANCE, "expected version is $ABI_VERSION$")
|
.replace("expected version is " + JsMetadataVersion.INSTANCE, "expected version is $ABI_VERSION$")
|
||||||
.replace("\\", "/")
|
.replace("\\", "/")
|
||||||
|
|||||||
+9
-1
@@ -484,6 +484,14 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun testExperimentalCoroutineCallFromRelease() {
|
fun testExperimentalCoroutineCallFromRelease() {
|
||||||
|
doTestExperimentalCoroutineCallFromRelease()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testExperimentalCoroutineCallFromReleaseWarnings() {
|
||||||
|
doTestExperimentalCoroutineCallFromRelease()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun doTestExperimentalCoroutineCallFromRelease() {
|
||||||
val library = compileLibrary(
|
val library = compileLibrary(
|
||||||
"library",
|
"library",
|
||||||
additionalOptions = listOf("-language-version", "1.2"),
|
additionalOptions = listOf("-language-version", "1.2"),
|
||||||
@@ -492,7 +500,7 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration
|
|||||||
compileKotlin(
|
compileKotlin(
|
||||||
"release.kt",
|
"release.kt",
|
||||||
tmpdir,
|
tmpdir,
|
||||||
listOf(library),
|
listOf(library, ForTestCompileRuntime.coroutinesJarForTests()),
|
||||||
additionalOptions = listOf("-language-version", "1.3", "-api-version", "1.3")
|
additionalOptions = listOf("-language-version", "1.3", "-api-version", "1.3")
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+109
-12
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.serialization.deserialization
|
package org.jetbrains.kotlin.serialization.deserialization
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.builtins.isSuspendFunctionType
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget
|
||||||
@@ -17,7 +18,12 @@ import org.jetbrains.kotlin.metadata.ProtoBuf
|
|||||||
import org.jetbrains.kotlin.metadata.deserialization.*
|
import org.jetbrains.kotlin.metadata.deserialization.*
|
||||||
import org.jetbrains.kotlin.protobuf.MessageLite
|
import org.jetbrains.kotlin.protobuf.MessageLite
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorFactory
|
import org.jetbrains.kotlin.resolve.DescriptorFactory
|
||||||
|
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameOrNull
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.*
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedMemberDescriptor.CoroutinesCompatibilityMode
|
||||||
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
import org.jetbrains.kotlin.types.UnwrappedType
|
||||||
|
import org.jetbrains.kotlin.types.typeUtil.contains
|
||||||
|
|
||||||
class MemberDeserializer(private val c: DeserializationContext) {
|
class MemberDeserializer(private val c: DeserializationContext) {
|
||||||
private val annotationDeserializer = AnnotationDeserializer(c.components.moduleDescriptor, c.components.notFoundClasses)
|
private val annotationDeserializer = AnnotationDeserializer(c.components.moduleDescriptor, c.components.notFoundClasses)
|
||||||
@@ -130,12 +136,97 @@ class MemberDeserializer(private val c: DeserializationContext) {
|
|||||||
return property
|
return property
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun DeserializedMemberDescriptor.checkExperimentalCoroutine(typeDeserializer: TypeDeserializer): Boolean {
|
private fun DeserializedMemberDescriptor.checkExperimentalCoroutine(
|
||||||
// Calculate checkExperimentalCoroutine for type parameters
|
typeDeserializer: TypeDeserializer
|
||||||
typeDeserializer.ownTypeParameters.forEach { it.upperBounds }
|
): DeserializedMemberDescriptor.CoroutinesCompatibilityMode {
|
||||||
return typeDeserializer.experimentalSuspendFunctionTypeEncountered && versionAndReleaseCoroutinesMismatch()
|
if (!versionAndReleaseCoroutinesMismatch()) return CoroutinesCompatibilityMode.COMPATIBLE
|
||||||
|
|
||||||
|
forceUpperBoundsComputation(typeDeserializer)
|
||||||
|
|
||||||
|
return if (typeDeserializer.experimentalSuspendFunctionTypeEncountered)
|
||||||
|
CoroutinesCompatibilityMode.INCOMPATIBLE
|
||||||
|
else
|
||||||
|
CoroutinesCompatibilityMode.COMPATIBLE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun forceUpperBoundsComputation(typeDeserializer: TypeDeserializer) {
|
||||||
|
typeDeserializer.ownTypeParameters.forEach { it.upperBounds }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun DeserializedSimpleFunctionDescriptor.initializeWithCoroutinesExperimentalityStatus(
|
||||||
|
receiverParameterType: KotlinType?,
|
||||||
|
dispatchReceiverParameter: ReceiverParameterDescriptor?,
|
||||||
|
typeParameters: List<TypeParameterDescriptor>,
|
||||||
|
unsubstitutedValueParameters: List<ValueParameterDescriptor>,
|
||||||
|
unsubstitutedReturnType: KotlinType?,
|
||||||
|
modality: Modality?,
|
||||||
|
visibility: Visibility,
|
||||||
|
userDataMap: Map<out FunctionDescriptor.UserDataKey<*>, *>,
|
||||||
|
isSuspend: Boolean
|
||||||
|
) {
|
||||||
|
initialize(
|
||||||
|
receiverParameterType,
|
||||||
|
dispatchReceiverParameter,
|
||||||
|
typeParameters,
|
||||||
|
unsubstitutedValueParameters,
|
||||||
|
unsubstitutedReturnType,
|
||||||
|
modality,
|
||||||
|
visibility,
|
||||||
|
userDataMap,
|
||||||
|
computeExperimentalityModeForFunctions(
|
||||||
|
receiverParameterType,
|
||||||
|
unsubstitutedValueParameters,
|
||||||
|
typeParameters,
|
||||||
|
unsubstitutedReturnType,
|
||||||
|
isSuspend
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun DeserializedCallableMemberDescriptor.computeExperimentalityModeForFunctions(
|
||||||
|
extensionReceiverType: KotlinType?,
|
||||||
|
parameters: Collection<ValueParameterDescriptor>,
|
||||||
|
typeParameters: Collection<TypeParameterDescriptor>,
|
||||||
|
returnType: KotlinType?,
|
||||||
|
isSuspend: Boolean
|
||||||
|
): DeserializedMemberDescriptor.CoroutinesCompatibilityMode {
|
||||||
|
if (!versionAndReleaseCoroutinesMismatch()) return CoroutinesCompatibilityMode.COMPATIBLE
|
||||||
|
if (fqNameOrNull() == KOTLIN_SUSPEND_BUILT_IN_FUNCTION_FQ_NAME) return CoroutinesCompatibilityMode.COMPATIBLE
|
||||||
|
|
||||||
|
val types = parameters.map { it.type } + listOfNotNull(extensionReceiverType)
|
||||||
|
|
||||||
|
if (returnType?.containsSuspendFunctionType() == true) return CoroutinesCompatibilityMode.INCOMPATIBLE
|
||||||
|
if (typeParameters.any { typeParameter -> typeParameter.upperBounds.any { it.containsSuspendFunctionType() } }) {
|
||||||
|
return CoroutinesCompatibilityMode.INCOMPATIBLE
|
||||||
|
}
|
||||||
|
|
||||||
|
val maxFromParameters = types.map { type ->
|
||||||
|
when {
|
||||||
|
type.isSuspendFunctionType && type.arguments.size <= 3 ->
|
||||||
|
if (type.arguments.any { it.type.containsSuspendFunctionType() })
|
||||||
|
CoroutinesCompatibilityMode.INCOMPATIBLE
|
||||||
|
else
|
||||||
|
CoroutinesCompatibilityMode.NEEDS_WRAPPER
|
||||||
|
|
||||||
|
type.containsSuspendFunctionType() -> CoroutinesCompatibilityMode.INCOMPATIBLE
|
||||||
|
|
||||||
|
else -> CoroutinesCompatibilityMode.COMPATIBLE
|
||||||
|
}
|
||||||
|
}.max() ?: CoroutinesCompatibilityMode.COMPATIBLE
|
||||||
|
|
||||||
|
return maxOf(
|
||||||
|
if (isSuspend)
|
||||||
|
CoroutinesCompatibilityMode.NEEDS_WRAPPER
|
||||||
|
else
|
||||||
|
CoroutinesCompatibilityMode.COMPATIBLE,
|
||||||
|
maxFromParameters
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun KotlinType.containsSuspendFunctionType() = contains(UnwrappedType::isSuspendFunctionType)
|
||||||
|
|
||||||
|
|
||||||
private fun DeserializedMemberDescriptor.versionAndReleaseCoroutinesMismatch(): Boolean =
|
private fun DeserializedMemberDescriptor.versionAndReleaseCoroutinesMismatch(): Boolean =
|
||||||
c.components.configuration.releaseCoroutines && versionRequirements.none {
|
c.components.configuration.releaseCoroutines && versionRequirements.none {
|
||||||
it.version == VersionRequirement.Version(1, 3) && it.kind == ProtoBuf.VersionRequirement.VersionKind.LANGUAGE_VERSION
|
it.version == VersionRequirement.Version(1, 3) && it.kind == ProtoBuf.VersionRequirement.VersionKind.LANGUAGE_VERSION
|
||||||
@@ -160,7 +251,7 @@ class MemberDeserializer(private val c: DeserializationContext) {
|
|||||||
)
|
)
|
||||||
val local = c.childContext(function, proto.typeParameterList)
|
val local = c.childContext(function, proto.typeParameterList)
|
||||||
|
|
||||||
function.initialize(
|
function.initializeWithCoroutinesExperimentalityStatus(
|
||||||
proto.receiverType(c.typeTable)?.let { local.typeDeserializer.type(it, receiverAnnotations) },
|
proto.receiverType(c.typeTable)?.let { local.typeDeserializer.type(it, receiverAnnotations) },
|
||||||
getDispatchReceiverParameter(),
|
getDispatchReceiverParameter(),
|
||||||
local.typeDeserializer.ownTypeParameters,
|
local.typeDeserializer.ownTypeParameters,
|
||||||
@@ -169,8 +260,7 @@ class MemberDeserializer(private val c: DeserializationContext) {
|
|||||||
ProtoEnumFlags.modality(Flags.MODALITY.get(flags)),
|
ProtoEnumFlags.modality(Flags.MODALITY.get(flags)),
|
||||||
ProtoEnumFlags.visibility(Flags.VISIBILITY.get(flags)),
|
ProtoEnumFlags.visibility(Flags.VISIBILITY.get(flags)),
|
||||||
emptyMap<FunctionDescriptor.UserDataKey<*>, Any?>(),
|
emptyMap<FunctionDescriptor.UserDataKey<*>, Any?>(),
|
||||||
(Flags.IS_SUSPEND.get(flags) && function.versionAndReleaseCoroutinesMismatch()) ||
|
Flags.IS_SUSPEND.get(flags)
|
||||||
function.checkExperimentalCoroutine(local.typeDeserializer)
|
|
||||||
)
|
)
|
||||||
function.isOperator = Flags.IS_OPERATOR.get(flags)
|
function.isOperator = Flags.IS_OPERATOR.get(flags)
|
||||||
function.isInfix = Flags.IS_INFIX.get(flags)
|
function.isInfix = Flags.IS_INFIX.get(flags)
|
||||||
@@ -227,11 +317,18 @@ class MemberDeserializer(private val c: DeserializationContext) {
|
|||||||
)
|
)
|
||||||
descriptor.returnType = classDescriptor.defaultType
|
descriptor.returnType = classDescriptor.defaultType
|
||||||
|
|
||||||
// Calculate isExperimentalCoroutineInReleaseEnvironment for type parameters
|
val doesClassContainIncompatibility =
|
||||||
descriptor.typeParameters.forEach { it.upperBounds }
|
(c.containingDeclaration as? DeserializedClassDescriptor)
|
||||||
descriptor.isExperimentalCoroutineInReleaseEnvironment = local.typeDeserializer.experimentalSuspendFunctionTypeEncountered ||
|
?.c?.typeDeserializer?.experimentalSuspendFunctionTypeEncountered == true
|
||||||
((c.containingDeclaration as? DeserializedClassDescriptor)?.c?.typeDeserializer?.experimentalSuspendFunctionTypeEncountered == true &&
|
&& descriptor.versionAndReleaseCoroutinesMismatch()
|
||||||
descriptor.versionAndReleaseCoroutinesMismatch())
|
|
||||||
|
descriptor.coroutinesExperimentalCompatibilityMode =
|
||||||
|
if (doesClassContainIncompatibility)
|
||||||
|
CoroutinesCompatibilityMode.INCOMPATIBLE
|
||||||
|
else descriptor.computeExperimentalityModeForFunctions(
|
||||||
|
null, descriptor.valueParameters, descriptor.typeParameters,
|
||||||
|
descriptor.returnType, isSuspend = false
|
||||||
|
)
|
||||||
|
|
||||||
return descriptor
|
return descriptor
|
||||||
}
|
}
|
||||||
|
|||||||
+23
-15
@@ -23,8 +23,6 @@ interface DeserializedMemberDescriptor : MemberDescriptor {
|
|||||||
|
|
||||||
val typeTable: TypeTable
|
val typeTable: TypeTable
|
||||||
|
|
||||||
val isExperimentalCoroutineInReleaseEnvironment: Boolean
|
|
||||||
|
|
||||||
val versionRequirementTable: VersionRequirementTable
|
val versionRequirementTable: VersionRequirementTable
|
||||||
|
|
||||||
val versionRequirements: List<VersionRequirement>
|
val versionRequirements: List<VersionRequirement>
|
||||||
@@ -33,6 +31,14 @@ interface DeserializedMemberDescriptor : MemberDescriptor {
|
|||||||
// Information about the origin of this callable's container (class or package part on JVM) or null if there's no such information.
|
// Information about the origin of this callable's container (class or package part on JVM) or null if there's no such information.
|
||||||
// TODO: merge with sourceElement of containingDeclaration
|
// TODO: merge with sourceElement of containingDeclaration
|
||||||
val containerSource: DeserializedContainerSource?
|
val containerSource: DeserializedContainerSource?
|
||||||
|
|
||||||
|
val coroutinesExperimentalCompatibilityMode: CoroutinesCompatibilityMode
|
||||||
|
|
||||||
|
enum class CoroutinesCompatibilityMode {
|
||||||
|
COMPATIBLE,
|
||||||
|
NEEDS_WRAPPER,
|
||||||
|
INCOMPATIBLE
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface DeserializedContainerSource : SourceElement {
|
interface DeserializedContainerSource : SourceElement {
|
||||||
@@ -66,7 +72,7 @@ class DeserializedSimpleFunctionDescriptor(
|
|||||||
source ?: SourceElement.NO_SOURCE
|
source ?: SourceElement.NO_SOURCE
|
||||||
) {
|
) {
|
||||||
|
|
||||||
override var isExperimentalCoroutineInReleaseEnvironment: Boolean = false
|
override var coroutinesExperimentalCompatibilityMode = DeserializedMemberDescriptor.CoroutinesCompatibilityMode.COMPATIBLE
|
||||||
private set
|
private set
|
||||||
|
|
||||||
fun initialize(
|
fun initialize(
|
||||||
@@ -78,7 +84,7 @@ class DeserializedSimpleFunctionDescriptor(
|
|||||||
modality: Modality?,
|
modality: Modality?,
|
||||||
visibility: Visibility,
|
visibility: Visibility,
|
||||||
userDataMap: Map<out FunctionDescriptor.UserDataKey<*>, *>,
|
userDataMap: Map<out FunctionDescriptor.UserDataKey<*>, *>,
|
||||||
isExperimentalCoroutineInReleaseEnvironment: Boolean
|
isExperimentalCoroutineInReleaseEnvironment: DeserializedMemberDescriptor.CoroutinesCompatibilityMode
|
||||||
): SimpleFunctionDescriptorImpl {
|
): SimpleFunctionDescriptorImpl {
|
||||||
return super.initialize(
|
return super.initialize(
|
||||||
receiverParameterType,
|
receiverParameterType,
|
||||||
@@ -90,7 +96,7 @@ class DeserializedSimpleFunctionDescriptor(
|
|||||||
visibility,
|
visibility,
|
||||||
userDataMap
|
userDataMap
|
||||||
).also {
|
).also {
|
||||||
this.isExperimentalCoroutineInReleaseEnvironment = isExperimentalCoroutineInReleaseEnvironment
|
this.coroutinesExperimentalCompatibilityMode = isExperimentalCoroutineInReleaseEnvironment
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,7 +111,9 @@ class DeserializedSimpleFunctionDescriptor(
|
|||||||
return DeserializedSimpleFunctionDescriptor(
|
return DeserializedSimpleFunctionDescriptor(
|
||||||
newOwner, original as SimpleFunctionDescriptor?, annotations, newName ?: name, kind,
|
newOwner, original as SimpleFunctionDescriptor?, annotations, newName ?: name, kind,
|
||||||
proto, nameResolver, typeTable, versionRequirementTable, containerSource, source
|
proto, nameResolver, typeTable, versionRequirementTable, containerSource, source
|
||||||
)
|
).also {
|
||||||
|
it.coroutinesExperimentalCompatibilityMode = coroutinesExperimentalCompatibilityMode
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,16 +140,16 @@ class DeserializedPropertyDescriptor(
|
|||||||
containingDeclaration, original, annotations, modality, visibility, isVar, name, kind, SourceElement.NO_SOURCE,
|
containingDeclaration, original, annotations, modality, visibility, isVar, name, kind, SourceElement.NO_SOURCE,
|
||||||
isLateInit, isConst, isExpect, false, isExternal, isDelegated
|
isLateInit, isConst, isExpect, false, isExternal, isDelegated
|
||||||
) {
|
) {
|
||||||
override var isExperimentalCoroutineInReleaseEnvironment: Boolean = false
|
override var coroutinesExperimentalCompatibilityMode = DeserializedMemberDescriptor.CoroutinesCompatibilityMode.COMPATIBLE
|
||||||
private set
|
private set
|
||||||
|
|
||||||
fun initialize(
|
fun initialize(
|
||||||
getter: PropertyGetterDescriptorImpl?,
|
getter: PropertyGetterDescriptorImpl?,
|
||||||
setter: PropertySetterDescriptor?,
|
setter: PropertySetterDescriptor?,
|
||||||
isExperimentalCoroutineInReleaseEnvironment: Boolean
|
isExperimentalCoroutineInReleaseEnvironment: DeserializedMemberDescriptor.CoroutinesCompatibilityMode
|
||||||
) {
|
) {
|
||||||
super.initialize(getter, setter)
|
super.initialize(getter, setter)
|
||||||
.also { this.isExperimentalCoroutineInReleaseEnvironment = isExperimentalCoroutineInReleaseEnvironment }
|
.also { this.coroutinesExperimentalCompatibilityMode = isExperimentalCoroutineInReleaseEnvironment }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createSubstitutedCopy(
|
override fun createSubstitutedCopy(
|
||||||
@@ -176,7 +184,7 @@ class DeserializedClassConstructorDescriptor(
|
|||||||
) : DeserializedCallableMemberDescriptor,
|
) : DeserializedCallableMemberDescriptor,
|
||||||
ClassConstructorDescriptorImpl(containingDeclaration, original, annotations, isPrimary, kind, source ?: SourceElement.NO_SOURCE) {
|
ClassConstructorDescriptorImpl(containingDeclaration, original, annotations, isPrimary, kind, source ?: SourceElement.NO_SOURCE) {
|
||||||
|
|
||||||
override var isExperimentalCoroutineInReleaseEnvironment: Boolean = false
|
override var coroutinesExperimentalCompatibilityMode = DeserializedMemberDescriptor.CoroutinesCompatibilityMode.COMPATIBLE
|
||||||
internal set
|
internal set
|
||||||
|
|
||||||
override fun createSubstitutedCopy(
|
override fun createSubstitutedCopy(
|
||||||
@@ -190,7 +198,7 @@ class DeserializedClassConstructorDescriptor(
|
|||||||
return DeserializedClassConstructorDescriptor(
|
return DeserializedClassConstructorDescriptor(
|
||||||
newOwner as ClassDescriptor, original as ConstructorDescriptor?, annotations, isPrimary, kind,
|
newOwner as ClassDescriptor, original as ConstructorDescriptor?, annotations, isPrimary, kind,
|
||||||
proto, nameResolver, typeTable, versionRequirementTable, containerSource, source
|
proto, nameResolver, typeTable, versionRequirementTable, containerSource, source
|
||||||
).also { it.isExperimentalCoroutineInReleaseEnvironment = isExperimentalCoroutineInReleaseEnvironment }
|
).also { it.coroutinesExperimentalCompatibilityMode = coroutinesExperimentalCompatibilityMode }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isExternal(): Boolean = false
|
override fun isExternal(): Boolean = false
|
||||||
@@ -222,14 +230,14 @@ class DeserializedTypeAliasDescriptor(
|
|||||||
private lateinit var typeConstructorParameters: List<TypeParameterDescriptor>
|
private lateinit var typeConstructorParameters: List<TypeParameterDescriptor>
|
||||||
private lateinit var defaultTypeImpl: SimpleType
|
private lateinit var defaultTypeImpl: SimpleType
|
||||||
|
|
||||||
override var isExperimentalCoroutineInReleaseEnvironment: Boolean = false
|
override var coroutinesExperimentalCompatibilityMode = DeserializedMemberDescriptor.CoroutinesCompatibilityMode.COMPATIBLE
|
||||||
private set
|
private set
|
||||||
|
|
||||||
fun initialize(
|
fun initialize(
|
||||||
declaredTypeParameters: List<TypeParameterDescriptor>,
|
declaredTypeParameters: List<TypeParameterDescriptor>,
|
||||||
underlyingType: SimpleType,
|
underlyingType: SimpleType,
|
||||||
expandedType: SimpleType,
|
expandedType: SimpleType,
|
||||||
isExperimentalCoroutineInReleaseEnvironment: Boolean
|
isExperimentalCoroutineInReleaseEnvironment: DeserializedMemberDescriptor.CoroutinesCompatibilityMode
|
||||||
) {
|
) {
|
||||||
initialize(declaredTypeParameters)
|
initialize(declaredTypeParameters)
|
||||||
this.underlyingType = underlyingType
|
this.underlyingType = underlyingType
|
||||||
@@ -237,7 +245,7 @@ class DeserializedTypeAliasDescriptor(
|
|||||||
typeConstructorParameters = computeConstructorTypeParameters()
|
typeConstructorParameters = computeConstructorTypeParameters()
|
||||||
defaultTypeImpl = computeDefaultType()
|
defaultTypeImpl = computeDefaultType()
|
||||||
constructors = getTypeAliasConstructors()
|
constructors = getTypeAliasConstructors()
|
||||||
this.isExperimentalCoroutineInReleaseEnvironment = isExperimentalCoroutineInReleaseEnvironment
|
this.coroutinesExperimentalCompatibilityMode = isExperimentalCoroutineInReleaseEnvironment
|
||||||
}
|
}
|
||||||
|
|
||||||
override val classDescriptor: ClassDescriptor?
|
override val classDescriptor: ClassDescriptor?
|
||||||
@@ -255,7 +263,7 @@ class DeserializedTypeAliasDescriptor(
|
|||||||
declaredTypeParameters,
|
declaredTypeParameters,
|
||||||
substitutor.safeSubstitute(underlyingType, Variance.INVARIANT).asSimpleType(),
|
substitutor.safeSubstitute(underlyingType, Variance.INVARIANT).asSimpleType(),
|
||||||
substitutor.safeSubstitute(expandedType, Variance.INVARIANT).asSimpleType(),
|
substitutor.safeSubstitute(expandedType, Variance.INVARIANT).asSimpleType(),
|
||||||
isExperimentalCoroutineInReleaseEnvironment
|
coroutinesExperimentalCompatibilityMode
|
||||||
)
|
)
|
||||||
|
|
||||||
return substituted
|
return substituted
|
||||||
|
|||||||
+2
-2
@@ -3,7 +3,7 @@ import libO.*
|
|||||||
|
|
||||||
suspend fun newMain() {
|
suspend fun newMain() {
|
||||||
newFoo()
|
newFoo()
|
||||||
<error descr="[DEPRECATION_ERROR] Using 'oldFoo(): Unit' is an error. Experimental coroutine cannot be used with API version 1.3">oldFoo</error>()
|
<warning descr="[DEPRECATION] 'oldFoo(): Unit' is deprecated. Experimental coroutines support will be dropped in 1.4">oldFoo</warning>()
|
||||||
|
|
||||||
// TODO: actually, it's a bug
|
// TODO: actually, it's a bug
|
||||||
oldMain()
|
oldMain()
|
||||||
@@ -14,5 +14,5 @@ fun newMain2() {
|
|||||||
newMain()
|
newMain()
|
||||||
}
|
}
|
||||||
|
|
||||||
<error descr="[DEPRECATION_ERROR] Using 'oldFoo(): Unit' is an error. Experimental coroutine cannot be used with API version 1.3"><error descr="[ILLEGAL_SUSPEND_FUNCTION_CALL] Suspend function 'oldFoo' should be called only from a coroutine or another suspend function">oldFoo</error></error>()
|
<error descr="[ILLEGAL_SUSPEND_FUNCTION_CALL] Suspend function 'oldFoo' should be called only from a coroutine or another suspend function">oldFoo</error>()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user