[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");
|
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
|
@Test
|
||||||
@TestMetadata("OverloadPriority.kt")
|
@TestMetadata("OverloadPriority.kt")
|
||||||
public void testOverloadPriority() throws Exception {
|
public void testOverloadPriority() throws Exception {
|
||||||
|
|||||||
+6
@@ -26028,6 +26028,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
|||||||
runTest("compiler/testData/diagnostics/tests/samConversions/kt17765.kt");
|
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
|
@Test
|
||||||
@TestMetadata("OverloadPriority.kt")
|
@TestMetadata("OverloadPriority.kt")
|
||||||
public void testOverloadPriority() throws Exception {
|
public void testOverloadPriority() throws Exception {
|
||||||
|
|||||||
+6
@@ -26028,6 +26028,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
|||||||
runTest("compiler/testData/diagnostics/tests/samConversions/kt17765.kt");
|
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
|
@Test
|
||||||
@TestMetadata("OverloadPriority.kt")
|
@TestMetadata("OverloadPriority.kt")
|
||||||
public void testOverloadPriority() throws Exception {
|
public void testOverloadPriority() throws Exception {
|
||||||
|
|||||||
+6
@@ -44497,6 +44497,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
|||||||
runTest("compiler/testData/codegen/box/sam/kt50171.kt");
|
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
|
@Test
|
||||||
@TestMetadata("nonInlinedSamWrapper.kt")
|
@TestMetadata("nonInlinedSamWrapper.kt")
|
||||||
public void testNonInlinedSamWrapper() throws Exception {
|
public void testNonInlinedSamWrapper() throws Exception {
|
||||||
|
|||||||
+13
-3
@@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.resolve.calls.components
|
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.isFunctionType
|
||||||
import org.jetbrains.kotlin.builtins.isFunctionTypeOrSubtype
|
import org.jetbrains.kotlin.builtins.isFunctionTypeOrSubtype
|
||||||
import org.jetbrains.kotlin.config.LanguageFeature
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
@@ -41,15 +43,23 @@ object SamTypeConversions : ParameterTypeConversion {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun conversionIsNeededBeforeSubtypingCheck(argument: KotlinCallArgument): Boolean {
|
override fun conversionIsNeededBeforeSubtypingCheck(
|
||||||
|
argument: KotlinCallArgument,
|
||||||
|
areSuspendOnlySamConversionsSupported: Boolean
|
||||||
|
): Boolean {
|
||||||
return when (argument) {
|
return when (argument) {
|
||||||
is SubKotlinCallArgument -> {
|
is SubKotlinCallArgument -> {
|
||||||
val stableType = argument.receiver.stableType
|
val stableType = argument.receiver.stableType
|
||||||
if (stableType.isFunctionType) return true
|
if (
|
||||||
|
stableType.isFunctionType ||
|
||||||
|
(areSuspendOnlySamConversionsSupported && stableType.isFunctionOrKFunctionTypeWithAnySuspendability)
|
||||||
|
) return true
|
||||||
|
|
||||||
hasNonAnalyzedLambdaAsReturnType(argument.callResult.subResolvedAtoms, stableType)
|
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
|
is LambdaKotlinCallArgument, is CallableReferenceKotlinCallArgument -> true
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-2
@@ -27,8 +27,12 @@ object SuspendTypeConversions : ParameterTypeConversion {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun conversionIsNeededBeforeSubtypingCheck(argument: KotlinCallArgument): Boolean =
|
override fun conversionIsNeededBeforeSubtypingCheck(
|
||||||
argument is SimpleKotlinCallArgument && argument.receiver.stableType.isFunctionType
|
argument: KotlinCallArgument,
|
||||||
|
areSuspendOnlySamConversionsSupported: Boolean
|
||||||
|
): Boolean =
|
||||||
|
argument is SimpleKotlinCallArgument &&
|
||||||
|
(argument.receiver.stableType.isFunctionType || argument.receiver.stableType.isKFunctionType)
|
||||||
|
|
||||||
override fun conversionIsNeededAfterSubtypingCheck(argument: KotlinCallArgument): Boolean =
|
override fun conversionIsNeededAfterSubtypingCheck(argument: KotlinCallArgument): Boolean =
|
||||||
argument is SimpleKotlinCallArgument && argument.receiver.stableType.isFunctionTypeOrSubtype
|
argument is SimpleKotlinCallArgument && argument.receiver.stableType.isFunctionTypeOrSubtype
|
||||||
|
|||||||
+4
-1
@@ -51,7 +51,10 @@ object UnitTypeConversions : ParameterTypeConversion {
|
|||||||
isUnit() || isDynamic() || isNothing()
|
isUnit() || isDynamic() || isNothing()
|
||||||
|
|
||||||
|
|
||||||
override fun conversionIsNeededBeforeSubtypingCheck(argument: KotlinCallArgument): Boolean =
|
override fun conversionIsNeededBeforeSubtypingCheck(
|
||||||
|
argument: KotlinCallArgument,
|
||||||
|
areSuspendOnlySamConversionsSupported: Boolean
|
||||||
|
): Boolean =
|
||||||
argument is SimpleKotlinCallArgument && argument.receiver.stableType.isFunctionType
|
argument is SimpleKotlinCallArgument && argument.receiver.stableType.isFunctionType
|
||||||
|
|
||||||
override fun conversionIsNeededAfterSubtypingCheck(argument: KotlinCallArgument): Boolean {
|
override fun conversionIsNeededAfterSubtypingCheck(argument: KotlinCallArgument): Boolean {
|
||||||
|
|||||||
+8
-2
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.resolve.calls.components
|
package org.jetbrains.kotlin.resolve.calls.components
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
import org.jetbrains.kotlin.descriptors.ParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.ParameterDescriptor
|
||||||
import org.jetbrains.kotlin.resolve.calls.components.candidate.ResolutionCandidate
|
import org.jetbrains.kotlin.resolve.calls.components.candidate.ResolutionCandidate
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.KotlinCallArgument
|
import org.jetbrains.kotlin.resolve.calls.model.KotlinCallArgument
|
||||||
@@ -17,7 +18,7 @@ interface ParameterTypeConversion {
|
|||||||
expectedParameterType: UnwrappedType
|
expectedParameterType: UnwrappedType
|
||||||
): Boolean
|
): Boolean
|
||||||
|
|
||||||
fun conversionIsNeededBeforeSubtypingCheck(argument: KotlinCallArgument): Boolean
|
fun conversionIsNeededBeforeSubtypingCheck(argument: KotlinCallArgument, areSuspendOnlySamConversionsSupported: Boolean): Boolean
|
||||||
fun conversionIsNeededAfterSubtypingCheck(argument: KotlinCallArgument): Boolean
|
fun conversionIsNeededAfterSubtypingCheck(argument: KotlinCallArgument): Boolean
|
||||||
|
|
||||||
fun convertParameterType(
|
fun convertParameterType(
|
||||||
@@ -110,7 +111,12 @@ object TypeConversions {
|
|||||||
conversion: ParameterTypeConversion
|
conversion: ParameterTypeConversion
|
||||||
): ConversionData {
|
): ConversionData {
|
||||||
val conversionDefinitelyNotNeeded = conversion.conversionDefinitelyNotNeeded(candidate, argument, candidateExpectedType)
|
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(
|
ConversionData(
|
||||||
conversion.convertParameterType(candidate, argument, candidateParameter, candidateExpectedType),
|
conversion.convertParameterType(candidate, argument, candidateParameter, candidateExpectedType),
|
||||||
wasConversion = true,
|
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");
|
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
|
@Test
|
||||||
@TestMetadata("OverloadPriority.kt")
|
@TestMetadata("OverloadPriority.kt")
|
||||||
public void testOverloadPriority() throws Exception {
|
public void testOverloadPriority() throws Exception {
|
||||||
|
|||||||
+6
@@ -44497,6 +44497,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/sam/kt50171.kt");
|
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
|
@Test
|
||||||
@TestMetadata("nonInlinedSamWrapper.kt")
|
@TestMetadata("nonInlinedSamWrapper.kt")
|
||||||
public void testNonInlinedSamWrapper() throws Exception {
|
public void testNonInlinedSamWrapper() throws Exception {
|
||||||
|
|||||||
@@ -242,6 +242,7 @@ enum class LanguageFeature(
|
|||||||
ProhibitQualifiedAccessToUninitializedEnumEntry(KOTLIN_1_7, kind = BUG_FIX), // KT-41124
|
ProhibitQualifiedAccessToUninitializedEnumEntry(KOTLIN_1_7, kind = BUG_FIX), // KT-41124
|
||||||
ForbidRecursiveDelegateExpressions(KOTLIN_1_7, kind = BUG_FIX),
|
ForbidRecursiveDelegateExpressions(KOTLIN_1_7, kind = BUG_FIX),
|
||||||
KotlinFunInterfaceConstructorReference(KOTLIN_1_7),
|
KotlinFunInterfaceConstructorReference(KOTLIN_1_7),
|
||||||
|
SuspendOnlySamConversions(KOTLIN_1_7),
|
||||||
|
|
||||||
// 1.8
|
// 1.8
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user