[FE 1.0] Support suspend only SAM conversions

^KT-50477 Fixed
This commit is contained in:
Victor Petukhov
2022-01-12 18:45:47 +03:00
committed by teamcity
parent d2c0234895
commit 22b2554368
15 changed files with 157 additions and 8 deletions
@@ -26028,6 +26028,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
runTest("compiler/testData/diagnostics/tests/samConversions/kt17765.kt");
}
@Test
@TestMetadata("kt50477.kt")
public void testKt50477() throws Exception {
runTest("compiler/testData/diagnostics/tests/samConversions/kt50477.kt");
}
@Test
@TestMetadata("OverloadPriority.kt")
public void testOverloadPriority() throws Exception {
@@ -26028,6 +26028,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/tests/samConversions/kt17765.kt");
}
@Test
@TestMetadata("kt50477.kt")
public void testKt50477() throws Exception {
runTest("compiler/testData/diagnostics/tests/samConversions/kt50477.kt");
}
@Test
@TestMetadata("OverloadPriority.kt")
public void testOverloadPriority() throws Exception {
@@ -26028,6 +26028,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
runTest("compiler/testData/diagnostics/tests/samConversions/kt17765.kt");
}
@Test
@TestMetadata("kt50477.kt")
public void testKt50477() throws Exception {
runTest("compiler/testData/diagnostics/tests/samConversions/kt50477.kt");
}
@Test
@TestMetadata("OverloadPriority.kt")
public void testOverloadPriority() throws Exception {
@@ -44497,6 +44497,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/sam/kt50171.kt");
}
@Test
@TestMetadata("kt50477Enabled.kt")
public void testKt50477Enabled() throws Exception {
runTest("compiler/testData/codegen/box/sam/kt50477Enabled.kt");
}
@Test
@TestMetadata("nonInlinedSamWrapper.kt")
public void testNonInlinedSamWrapper() throws Exception {
@@ -5,6 +5,8 @@
package org.jetbrains.kotlin.resolve.calls.components
import org.jetbrains.kotlin.builtins.isFunctionOrKFunctionTypeWithAnySuspendability
import org.jetbrains.kotlin.builtins.isFunctionOrSuspendFunctionType
import org.jetbrains.kotlin.builtins.isFunctionType
import org.jetbrains.kotlin.builtins.isFunctionTypeOrSubtype
import org.jetbrains.kotlin.config.LanguageFeature
@@ -41,15 +43,23 @@ object SamTypeConversions : ParameterTypeConversion {
return false
}
override fun conversionIsNeededBeforeSubtypingCheck(argument: KotlinCallArgument): Boolean {
override fun conversionIsNeededBeforeSubtypingCheck(
argument: KotlinCallArgument,
areSuspendOnlySamConversionsSupported: Boolean
): Boolean {
return when (argument) {
is SubKotlinCallArgument -> {
val stableType = argument.receiver.stableType
if (stableType.isFunctionType) return true
if (
stableType.isFunctionType ||
(areSuspendOnlySamConversionsSupported && stableType.isFunctionOrKFunctionTypeWithAnySuspendability)
) return true
hasNonAnalyzedLambdaAsReturnType(argument.callResult.subResolvedAtoms, stableType)
}
is SimpleKotlinCallArgument -> argument.receiver.stableType.isFunctionType
is SimpleKotlinCallArgument -> argument.receiver.stableType.run {
isFunctionType || (areSuspendOnlySamConversionsSupported && isFunctionOrKFunctionTypeWithAnySuspendability)
}
is LambdaKotlinCallArgument, is CallableReferenceKotlinCallArgument -> true
else -> false
}
@@ -27,8 +27,12 @@ object SuspendTypeConversions : ParameterTypeConversion {
return false
}
override fun conversionIsNeededBeforeSubtypingCheck(argument: KotlinCallArgument): Boolean =
argument is SimpleKotlinCallArgument && argument.receiver.stableType.isFunctionType
override fun conversionIsNeededBeforeSubtypingCheck(
argument: KotlinCallArgument,
areSuspendOnlySamConversionsSupported: Boolean
): Boolean =
argument is SimpleKotlinCallArgument &&
(argument.receiver.stableType.isFunctionType || argument.receiver.stableType.isKFunctionType)
override fun conversionIsNeededAfterSubtypingCheck(argument: KotlinCallArgument): Boolean =
argument is SimpleKotlinCallArgument && argument.receiver.stableType.isFunctionTypeOrSubtype
@@ -51,7 +51,10 @@ object UnitTypeConversions : ParameterTypeConversion {
isUnit() || isDynamic() || isNothing()
override fun conversionIsNeededBeforeSubtypingCheck(argument: KotlinCallArgument): Boolean =
override fun conversionIsNeededBeforeSubtypingCheck(
argument: KotlinCallArgument,
areSuspendOnlySamConversionsSupported: Boolean
): Boolean =
argument is SimpleKotlinCallArgument && argument.receiver.stableType.isFunctionType
override fun conversionIsNeededAfterSubtypingCheck(argument: KotlinCallArgument): Boolean {
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.resolve.calls.components
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.descriptors.ParameterDescriptor
import org.jetbrains.kotlin.resolve.calls.components.candidate.ResolutionCandidate
import org.jetbrains.kotlin.resolve.calls.model.KotlinCallArgument
@@ -17,7 +18,7 @@ interface ParameterTypeConversion {
expectedParameterType: UnwrappedType
): Boolean
fun conversionIsNeededBeforeSubtypingCheck(argument: KotlinCallArgument): Boolean
fun conversionIsNeededBeforeSubtypingCheck(argument: KotlinCallArgument, areSuspendOnlySamConversionsSupported: Boolean): Boolean
fun conversionIsNeededAfterSubtypingCheck(argument: KotlinCallArgument): Boolean
fun convertParameterType(
@@ -110,7 +111,12 @@ object TypeConversions {
conversion: ParameterTypeConversion
): ConversionData {
val conversionDefinitelyNotNeeded = conversion.conversionDefinitelyNotNeeded(candidate, argument, candidateExpectedType)
return if (!conversionDefinitelyNotNeeded && conversion.conversionIsNeededBeforeSubtypingCheck(argument)) {
val areSuspendOnlySamConversionsSupported =
candidate.callComponents.languageVersionSettings.supportsFeature(LanguageFeature.SuspendOnlySamConversions)
return if (
!conversionDefinitelyNotNeeded &&
conversion.conversionIsNeededBeforeSubtypingCheck(argument, areSuspendOnlySamConversionsSupported)
) {
ConversionData(
conversion.convertParameterType(candidate, argument, candidateParameter, candidateExpectedType),
wasConversion = true,
+30
View File
@@ -0,0 +1,30 @@
// !LANGUAGE: +SuspendOnlySamConversions
// TARGET_BACKEND: JVM_IR
fun interface FI {
suspend fun call() // suspending now(!!!)
}
fun accept(fi: FI): Int = 1
suspend fun foo() {}
fun foo2() {}
fun box(): String {
val fi0: () -> Unit = {}
accept(fi0)
val fi: suspend () -> Unit = {} // Lambda of a suspending(!!!) functional type
accept(fi) // ERROR: Type mismatch. Required: FI Found: suspend () → Unit
accept(::foo)
val x1 = ::foo
accept(x1) // ERROR: Type mismatch. Required: FI Found: suspend () → Unit
accept(::foo2)
val x2 = ::foo2
accept(x2) // ERROR: Type mismatch. Required: FI Found: suspend () → Unit
return "OK"
}
@@ -0,0 +1,23 @@
// !LANGUAGE: -SuspendOnlySamConversions
fun interface FI {
suspend fun call() // suspending now(!!!)
}
fun accept(fi: FI): Int = TODO()
suspend fun foo() {}
fun foo2() {}
fun main() {
val fi: suspend () -> Unit = {} // Lambda of a suspending(!!!) functional type
accept(fi) // ERROR: Type mismatch. Required: FI Found: suspend () → Unit
accept(::foo)
val x1 = ::foo
accept(x1) // ERROR: Type mismatch. Required: FI Found: suspend () → Unit
accept(::foo2)
val x2 = ::foo2
accept(x2)
}
@@ -0,0 +1,23 @@
// !LANGUAGE: -SuspendOnlySamConversions
fun interface FI {
suspend fun call() // suspending now(!!!)
}
fun accept(fi: FI): Int = TODO()
suspend fun foo() {}
fun foo2() {}
fun main() {
val fi: suspend () -> Unit = {} // Lambda of a suspending(!!!) functional type
accept(<!TYPE_MISMATCH!>fi<!>) // ERROR: Type mismatch. Required: FI Found: suspend () → Unit
accept(::foo)
val x1 = ::foo
accept(<!TYPE_MISMATCH!>x1<!>) // ERROR: Type mismatch. Required: FI Found: suspend () → Unit
accept(::foo2)
val x2 = ::foo2
accept(x2)
}
@@ -0,0 +1,13 @@
package
public fun accept(/*0*/ fi: FI): kotlin.Int
public suspend fun foo(): kotlin.Unit
public fun foo2(): kotlin.Unit
public fun main(): kotlin.Unit
public fun interface FI {
public abstract suspend fun call(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -26040,6 +26040,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
runTest("compiler/testData/diagnostics/tests/samConversions/kt17765.kt");
}
@Test
@TestMetadata("kt50477.kt")
public void testKt50477() throws Exception {
runTest("compiler/testData/diagnostics/tests/samConversions/kt50477.kt");
}
@Test
@TestMetadata("OverloadPriority.kt")
public void testOverloadPriority() throws Exception {
@@ -44497,6 +44497,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/sam/kt50171.kt");
}
@Test
@TestMetadata("kt50477Enabled.kt")
public void testKt50477Enabled() throws Exception {
runTest("compiler/testData/codegen/box/sam/kt50477Enabled.kt");
}
@Test
@TestMetadata("nonInlinedSamWrapper.kt")
public void testNonInlinedSamWrapper() throws Exception {
@@ -242,6 +242,7 @@ enum class LanguageFeature(
ProhibitQualifiedAccessToUninitializedEnumEntry(KOTLIN_1_7, kind = BUG_FIX), // KT-41124
ForbidRecursiveDelegateExpressions(KOTLIN_1_7, kind = BUG_FIX),
KotlinFunInterfaceConstructorReference(KOTLIN_1_7),
SuspendOnlySamConversions(KOTLIN_1_7),
// 1.8