Support suspend conversion in callable reference adaptation
#KT-15917 In Progress
This commit is contained in:
+15
@@ -23011,6 +23011,11 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte
|
||||
runTest("compiler/testData/diagnostics/tests/suspendConversion/basicSuspendConversion.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("basicSuspendConversionForCallableReference.kt")
|
||||
public void testBasicSuspendConversionForCallableReference() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/suspendConversion/basicSuspendConversionForCallableReference.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("basicSuspendConversionGenerics.kt")
|
||||
public void testBasicSuspendConversionGenerics() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/suspendConversion/basicSuspendConversionGenerics.kt");
|
||||
@@ -23025,6 +23030,16 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte
|
||||
public void testSuspendConversionDisabled() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/suspendConversion/suspendConversionDisabled.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("suspendConversionWithFunInterfaces.kt")
|
||||
public void testSuspendConversionWithFunInterfaces() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/suspendConversion/suspendConversionWithFunInterfaces.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("suspendConversionWithReferenceAdaptation.kt")
|
||||
public void testSuspendConversionWithReferenceAdaptation() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/suspendConversion/suspendConversionWithReferenceAdaptation.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/syntheticExtensions")
|
||||
|
||||
+22
-3
@@ -75,9 +75,14 @@ class CallableReferenceAdaptation(
|
||||
val argumentTypes: Array<KotlinType>,
|
||||
val coercionStrategy: CoercionStrategy,
|
||||
val defaults: Int,
|
||||
val mappedArguments: Map<ValueParameterDescriptor, ResolvedCallArgument>
|
||||
val mappedArguments: Map<ValueParameterDescriptor, ResolvedCallArgument>,
|
||||
val suspendConversionStrategy: SuspendConversionStrategy
|
||||
)
|
||||
|
||||
enum class SuspendConversionStrategy {
|
||||
SUSPEND_CONVERSION, NO_CONVERSION
|
||||
}
|
||||
|
||||
/**
|
||||
* cases: class A {}, class B { companion object }, object C, enum class D { E }
|
||||
* A::foo <-> Type
|
||||
@@ -332,10 +337,21 @@ class CallableReferencesCandidateFactory(
|
||||
else
|
||||
mappedArguments
|
||||
|
||||
val suspendConversionStrategy =
|
||||
if (
|
||||
callComponents.languageVersionSettings.supportsFeature(LanguageFeature.SuspendConversion) &&
|
||||
!descriptor.isSuspend && expectedType?.isSuspendFunctionType == true
|
||||
) {
|
||||
SuspendConversionStrategy.SUSPEND_CONVERSION
|
||||
} else {
|
||||
SuspendConversionStrategy.NO_CONVERSION
|
||||
}
|
||||
|
||||
return CallableReferenceAdaptation(
|
||||
@Suppress("UNCHECKED_CAST") (mappedArgumentTypes as Array<KotlinType>),
|
||||
coercion, defaults,
|
||||
adaptedArguments
|
||||
adaptedArguments,
|
||||
suspendConversionStrategy
|
||||
)
|
||||
}
|
||||
|
||||
@@ -428,9 +444,12 @@ class CallableReferencesCandidateFactory(
|
||||
descriptorReturnType
|
||||
}
|
||||
|
||||
val suspendConversionStrategy = callableReferenceAdaptation?.suspendConversionStrategy
|
||||
val isSuspend = descriptor.isSuspend || suspendConversionStrategy == SuspendConversionStrategy.SUSPEND_CONVERSION
|
||||
|
||||
return callComponents.reflectionTypes.getKFunctionType(
|
||||
Annotations.EMPTY, null, argumentsAndReceivers, null,
|
||||
returnType, descriptor.builtIns, descriptor.isSuspend
|
||||
returnType, descriptor.builtIns, isSuspend
|
||||
) to callableReferenceAdaptation
|
||||
}
|
||||
else -> return ErrorUtils.createErrorType("Unsupported descriptor type: $descriptor") to null
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
// !LANGUAGE: +SuspendConversion
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
|
||||
fun foo1(f: suspend () -> Unit) {}
|
||||
fun bar1() {}
|
||||
|
||||
fun <T> foo2(e: T, f: suspend (T) -> Unit) {}
|
||||
fun bar2(x: Int) {}
|
||||
fun bar2(s: String) {}
|
||||
|
||||
fun test() {
|
||||
<!INAPPLICABLE_CANDIDATE!>foo1<!>(::bar1)
|
||||
|
||||
<!INAPPLICABLE_CANDIDATE!>foo2<!>(42, <!UNRESOLVED_REFERENCE!>::bar2<!>)
|
||||
<!INAPPLICABLE_CANDIDATE!>foo2<!>("str", <!UNRESOLVED_REFERENCE!>::bar2<!>)
|
||||
|
||||
<!INAPPLICABLE_CANDIDATE!>foo2<!>(42, ::bar1)
|
||||
}
|
||||
Vendored
+18
@@ -0,0 +1,18 @@
|
||||
// !LANGUAGE: +SuspendConversion
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
|
||||
fun foo1(f: suspend () -> Unit) {}
|
||||
fun bar1() {}
|
||||
|
||||
fun <T> foo2(e: T, f: suspend (T) -> Unit) {}
|
||||
fun bar2(x: Int) {}
|
||||
fun bar2(s: String) {}
|
||||
|
||||
fun test() {
|
||||
foo1(::bar1)
|
||||
|
||||
foo2(42, ::bar2)
|
||||
foo2("str", ::bar2)
|
||||
|
||||
foo2(42, <!TYPE_MISMATCH!>::bar1<!>)
|
||||
}
|
||||
compiler/testData/diagnostics/tests/suspendConversion/basicSuspendConversionForCallableReference.txt
Vendored
+8
@@ -0,0 +1,8 @@
|
||||
package
|
||||
|
||||
public fun bar1(): kotlin.Unit
|
||||
public fun bar2(/*0*/ x: kotlin.Int): kotlin.Unit
|
||||
public fun bar2(/*0*/ s: kotlin.String): kotlin.Unit
|
||||
public fun foo1(/*0*/ f: suspend () -> kotlin.Unit): kotlin.Unit
|
||||
public fun </*0*/ T> foo2(/*0*/ e: T, /*1*/ f: suspend (T) -> kotlin.Unit): kotlin.Unit
|
||||
public fun test(): kotlin.Unit
|
||||
Vendored
+21
@@ -0,0 +1,21 @@
|
||||
// !LANGUAGE: +SuspendConversion
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
|
||||
fun interface SuspendRunnable {
|
||||
suspend fun invoke()
|
||||
}
|
||||
|
||||
fun foo1(s: SuspendRunnable) {}
|
||||
fun bar1() {}
|
||||
|
||||
fun bar2(s: String = ""): Int = 0
|
||||
|
||||
fun bar3() {}
|
||||
suspend fun bar3(s: String = ""): Int = 0
|
||||
|
||||
fun test() {
|
||||
<!INAPPLICABLE_CANDIDATE!>foo1<!>(::bar1)
|
||||
<!INAPPLICABLE_CANDIDATE!>foo1<!>(::bar2)
|
||||
|
||||
<!INAPPLICABLE_CANDIDATE!>foo1<!>(<!UNRESOLVED_REFERENCE!>::bar3<!>) // Should be ambiguity
|
||||
}
|
||||
Vendored
+21
@@ -0,0 +1,21 @@
|
||||
// !LANGUAGE: +SuspendConversion
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
|
||||
fun interface SuspendRunnable {
|
||||
suspend fun invoke()
|
||||
}
|
||||
|
||||
fun foo1(s: SuspendRunnable) {}
|
||||
fun bar1() {}
|
||||
|
||||
fun bar2(s: String = ""): Int = 0
|
||||
|
||||
fun bar3() {}
|
||||
suspend fun bar3(s: String = ""): Int = 0
|
||||
|
||||
fun test() {
|
||||
foo1(::bar1)
|
||||
foo1(::bar2)
|
||||
|
||||
foo1(::bar3) // Should be ambiguity
|
||||
}
|
||||
Vendored
+15
@@ -0,0 +1,15 @@
|
||||
package
|
||||
|
||||
public fun bar1(): kotlin.Unit
|
||||
public fun bar2(/*0*/ s: kotlin.String = ...): kotlin.Int
|
||||
public fun bar3(): kotlin.Unit
|
||||
public suspend fun bar3(/*0*/ s: kotlin.String = ...): kotlin.Int
|
||||
public fun foo1(/*0*/ s: SuspendRunnable): kotlin.Unit
|
||||
public fun test(): kotlin.Unit
|
||||
|
||||
public fun interface SuspendRunnable {
|
||||
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 abstract suspend fun invoke(): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
// !LANGUAGE: +SuspendConversion
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
|
||||
fun unitCoercion(f: suspend () -> Unit) {}
|
||||
fun foo(): Int = 0
|
||||
|
||||
fun defaults(f: suspend (Int) -> String) {}
|
||||
fun bar(i: Int, l: Long = 42L): String = ""
|
||||
|
||||
fun varargs(f: suspend (Int, Int, Int) -> String) {}
|
||||
fun baz(vararg ints: Int): String = ""
|
||||
|
||||
fun unitCoercionAndDefaults(f: suspend () -> Unit) {}
|
||||
fun all(s: String = ""): Int = 0
|
||||
|
||||
fun test() {
|
||||
<!INAPPLICABLE_CANDIDATE!>unitCoercion<!>(::foo)
|
||||
<!INAPPLICABLE_CANDIDATE!>defaults<!>(::bar)
|
||||
<!INAPPLICABLE_CANDIDATE!>varargs<!>(::baz)
|
||||
<!INAPPLICABLE_CANDIDATE!>unitCoercionAndDefaults<!>(::all)
|
||||
}
|
||||
Vendored
+21
@@ -0,0 +1,21 @@
|
||||
// !LANGUAGE: +SuspendConversion
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
|
||||
fun unitCoercion(f: suspend () -> Unit) {}
|
||||
fun foo(): Int = 0
|
||||
|
||||
fun defaults(f: suspend (Int) -> String) {}
|
||||
fun bar(i: Int, l: Long = 42L): String = ""
|
||||
|
||||
fun varargs(f: suspend (Int, Int, Int) -> String) {}
|
||||
fun baz(vararg ints: Int): String = ""
|
||||
|
||||
fun unitCoercionAndDefaults(f: suspend () -> Unit) {}
|
||||
fun all(s: String = ""): Int = 0
|
||||
|
||||
fun test() {
|
||||
unitCoercion(::foo)
|
||||
defaults(::bar)
|
||||
varargs(::baz)
|
||||
unitCoercionAndDefaults(::all)
|
||||
}
|
||||
Vendored
+11
@@ -0,0 +1,11 @@
|
||||
package
|
||||
|
||||
public fun all(/*0*/ s: kotlin.String = ...): kotlin.Int
|
||||
public fun bar(/*0*/ i: kotlin.Int, /*1*/ l: kotlin.Long = ...): kotlin.String
|
||||
public fun baz(/*0*/ vararg ints: kotlin.Int /*kotlin.IntArray*/): kotlin.String
|
||||
public fun defaults(/*0*/ f: suspend (kotlin.Int) -> kotlin.String): kotlin.Unit
|
||||
public fun foo(): kotlin.Int
|
||||
public fun test(): kotlin.Unit
|
||||
public fun unitCoercion(/*0*/ f: suspend () -> kotlin.Unit): kotlin.Unit
|
||||
public fun unitCoercionAndDefaults(/*0*/ f: suspend () -> kotlin.Unit): kotlin.Unit
|
||||
public fun varargs(/*0*/ f: suspend (kotlin.Int, kotlin.Int, kotlin.Int) -> kotlin.String): kotlin.Unit
|
||||
@@ -23093,6 +23093,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTestWithFirVali
|
||||
runTest("compiler/testData/diagnostics/tests/suspendConversion/basicSuspendConversion.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("basicSuspendConversionForCallableReference.kt")
|
||||
public void testBasicSuspendConversionForCallableReference() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/suspendConversion/basicSuspendConversionForCallableReference.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("basicSuspendConversionGenerics.kt")
|
||||
public void testBasicSuspendConversionGenerics() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/suspendConversion/basicSuspendConversionGenerics.kt");
|
||||
@@ -23107,6 +23112,16 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTestWithFirVali
|
||||
public void testSuspendConversionDisabled() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/suspendConversion/suspendConversionDisabled.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("suspendConversionWithFunInterfaces.kt")
|
||||
public void testSuspendConversionWithFunInterfaces() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/suspendConversion/suspendConversionWithFunInterfaces.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("suspendConversionWithReferenceAdaptation.kt")
|
||||
public void testSuspendConversionWithReferenceAdaptation() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/suspendConversion/suspendConversionWithReferenceAdaptation.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/syntheticExtensions")
|
||||
|
||||
Generated
+15
@@ -23013,6 +23013,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
|
||||
runTest("compiler/testData/diagnostics/tests/suspendConversion/basicSuspendConversion.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("basicSuspendConversionForCallableReference.kt")
|
||||
public void testBasicSuspendConversionForCallableReference() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/suspendConversion/basicSuspendConversionForCallableReference.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("basicSuspendConversionGenerics.kt")
|
||||
public void testBasicSuspendConversionGenerics() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/suspendConversion/basicSuspendConversionGenerics.kt");
|
||||
@@ -23027,6 +23032,16 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
|
||||
public void testSuspendConversionDisabled() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/suspendConversion/suspendConversionDisabled.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("suspendConversionWithFunInterfaces.kt")
|
||||
public void testSuspendConversionWithFunInterfaces() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/suspendConversion/suspendConversionWithFunInterfaces.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("suspendConversionWithReferenceAdaptation.kt")
|
||||
public void testSuspendConversionWithReferenceAdaptation() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/suspendConversion/suspendConversionWithReferenceAdaptation.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/syntheticExtensions")
|
||||
|
||||
Reference in New Issue
Block a user