FIR: extend suspend conversion to intersection type
This commit is contained in:
committed by
TeamCityServer
parent
42ea4463ee
commit
2dfba10d84
+11
-16
@@ -400,8 +400,8 @@ internal class AdapterGenerator(
|
||||
return this
|
||||
}
|
||||
val expectedType = parameter?.returnTypeRef?.coneType ?: return this
|
||||
// Expect the expected type to be a suspend functional type, and the argument type is not a suspend functional type.
|
||||
if (!expectedType.isSuspendFunctionType(session) || argument.typeRef.coneType.isSuspendFunctionType(session)) {
|
||||
// Expect the expected type to be a suspend functional type.
|
||||
if (!expectedType.isSuspendFunctionType(session)) {
|
||||
return this
|
||||
}
|
||||
val expectedFunctionalType = expectedType.suspendFunctionTypeToFunctionType(session)
|
||||
@@ -424,22 +424,17 @@ internal class AdapterGenerator(
|
||||
|
||||
private fun findInvokeSymbol(expectedFunctionalType: ConeClassLikeType, argument: FirExpression): IrSimpleFunctionSymbol? {
|
||||
val argumentType = argument.typeRef.coneType
|
||||
// To avoid any remaining exotic types, e.g., intersection type, like it(FunctionN..., SuspendFunctionN...)
|
||||
if (argumentType !is ConeClassLikeType) {
|
||||
return null
|
||||
}
|
||||
val argumentTypeWithInvoke = argumentType.findSubtypeOfNonSuspendFunctionalType(session, expectedFunctionalType) ?: return null
|
||||
|
||||
if (argumentType.isSubtypeOfFunctionalType(session, expectedFunctionalType)) {
|
||||
return if (argumentType.isBuiltinFunctionalType(session)) {
|
||||
argumentType.findBaseInvokeSymbol(session, scopeSession)
|
||||
} else {
|
||||
argumentType.findContributedInvokeSymbol(session, scopeSession, expectedFunctionalType, shouldCalculateReturnTypesOfFakeOverrides = true)
|
||||
}?.let {
|
||||
declarationStorage.getIrFunctionSymbol(it) as? IrSimpleFunctionSymbol
|
||||
}
|
||||
return if (argumentTypeWithInvoke.isBuiltinFunctionalType(session)) {
|
||||
(argumentTypeWithInvoke as? ConeClassLikeType)?.findBaseInvokeSymbol(session, scopeSession)
|
||||
} else {
|
||||
argumentTypeWithInvoke.findContributedInvokeSymbol(
|
||||
session, scopeSession, expectedFunctionalType, shouldCalculateReturnTypesOfFakeOverrides = true
|
||||
)
|
||||
}?.let {
|
||||
declarationStorage.getIrFunctionSymbol(it) as? IrSimpleFunctionSymbol
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
private fun createAdapterFunctionForArgument(
|
||||
|
||||
@@ -247,36 +247,30 @@ private fun argumentTypeWithSuspendConversion(
|
||||
): ConeKotlinType? {
|
||||
// TODO: should refer to LanguageVersionSettings.SuspendConversion
|
||||
|
||||
// To avoid any remaining exotic types, e.g., intersection type, like it(FunctionN..., SuspendFunctionN...)
|
||||
if (argumentType !is ConeClassLikeType) {
|
||||
return null
|
||||
}
|
||||
|
||||
// Expect the expected type to be a suspend functional type, and the argument type is not a suspend functional type.
|
||||
if (!expectedType.isSuspendFunctionType(session) || argumentType.isSuspendFunctionType(session)) {
|
||||
// Expect the expected type to be a suspend functional type.
|
||||
if (!expectedType.isSuspendFunctionType(session)) {
|
||||
return null
|
||||
}
|
||||
|
||||
// We want to check the argument type against non-suspend functional type.
|
||||
val expectedFunctionalType = expectedType.suspendFunctionTypeToFunctionType(session)
|
||||
if (argumentType.isSubtypeOfFunctionalType(session, expectedFunctionalType)) {
|
||||
return argumentType.findContributedInvokeSymbol(
|
||||
session,
|
||||
scopeSession,
|
||||
expectedFunctionalType,
|
||||
shouldCalculateReturnTypesOfFakeOverrides = false
|
||||
)?.let { invokeSymbol ->
|
||||
createFunctionalType(
|
||||
invokeSymbol.fir.valueParameters.map { it.returnTypeRef.coneType },
|
||||
null,
|
||||
invokeSymbol.fir.returnTypeRef.coneType,
|
||||
isSuspend = true,
|
||||
isKFunctionType = argumentType.isKFunctionType(session)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
val argumentTypeWithInvoke = argumentType.findSubtypeOfNonSuspendFunctionalType(session, expectedFunctionalType)
|
||||
|
||||
return argumentTypeWithInvoke?.findContributedInvokeSymbol(
|
||||
session,
|
||||
scopeSession,
|
||||
expectedFunctionalType,
|
||||
shouldCalculateReturnTypesOfFakeOverrides = false
|
||||
)?.let { invokeSymbol ->
|
||||
createFunctionalType(
|
||||
invokeSymbol.fir.valueParameters.map { it.returnTypeRef.coneType },
|
||||
null,
|
||||
invokeSymbol.fir.returnTypeRef.coneType,
|
||||
isSuspend = true,
|
||||
isKFunctionType = argumentType.isKFunctionType(session)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun Candidate.prepareCapturedType(argumentType: ConeKotlinType, context: ResolutionContext): ConeKotlinType {
|
||||
|
||||
@@ -97,6 +97,33 @@ fun ConeKotlinType.isSubtypeOfFunctionalType(session: FirSession, expectedFuncti
|
||||
return AbstractTypeChecker.isSubtypeOf(session.typeContext, this, expectedFunctionalType.replaceArgumentsWithStarProjections())
|
||||
}
|
||||
|
||||
fun ConeKotlinType.findSubtypeOfNonSuspendFunctionalType(session: FirSession, expectedFunctionalType: ConeClassLikeType): ConeKotlinType? {
|
||||
require(expectedFunctionalType.isBuiltinFunctionalType(session) && !expectedFunctionalType.isSuspendFunctionType(session))
|
||||
return when (this) {
|
||||
is ConeClassLikeType -> {
|
||||
// Expect the argument type is not a suspend functional type.
|
||||
if (isSuspendFunctionType(session) || !isSubtypeOfFunctionalType(session, expectedFunctionalType))
|
||||
null
|
||||
else
|
||||
this
|
||||
}
|
||||
is ConeIntersectionType -> {
|
||||
if (intersectedTypes.any { it.isSuspendFunctionType(session) })
|
||||
null
|
||||
else
|
||||
intersectedTypes.find { it.findSubtypeOfNonSuspendFunctionalType(session, expectedFunctionalType) != null }
|
||||
}
|
||||
is ConeTypeParameterType -> {
|
||||
val bounds = lookupTag.typeParameterSymbol.fir.bounds.map { it.coneType }
|
||||
if (bounds.any { it.isSuspendFunctionType(session) })
|
||||
null
|
||||
else
|
||||
bounds.find { it.findSubtypeOfNonSuspendFunctionalType(session, expectedFunctionalType) != null }
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
fun ConeClassLikeType.findBaseInvokeSymbol(session: FirSession, scopeSession: ScopeSession): FirFunctionSymbol<*>? {
|
||||
require(this.isBuiltinFunctionalType(session))
|
||||
val functionN = (lookupTag.toSymbol(session)?.fir as? FirClass<*>) ?: return null
|
||||
|
||||
Vendored
-1
@@ -3,7 +3,6 @@
|
||||
// WITH_COROUTINES
|
||||
// IGNORE_BACKEND: JVM, NATIVE, JS, JS_IR
|
||||
// IGNORE_BACKEND: JS_IR_ES6
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// IGNORE_LIGHT_ANALYSIS
|
||||
|
||||
import helpers.*
|
||||
|
||||
Reference in New Issue
Block a user