[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
@@ -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,