[FE 1.0] Support suspend only SAM conversions
^KT-50477 Fixed
This commit is contained in:
committed by
teamcity
parent
d2c0234895
commit
22b2554368
+6
@@ -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 {
|
||||
|
||||
+6
@@ -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 {
|
||||
|
||||
+6
@@ -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 {
|
||||
|
||||
+6
@@ -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 {
|
||||
|
||||
+13
-3
@@ -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
|
||||
}
|
||||
|
||||
+6
-2
@@ -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
|
||||
|
||||
+4
-1
@@ -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 {
|
||||
|
||||
+8
-2
@@ -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,
|
||||
|
||||
@@ -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
|
||||
}
|
||||
Generated
+6
@@ -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 {
|
||||
|
||||
+6
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user