FIR: extend suspend conversion to intersection type
This commit is contained in:
committed by
TeamCityServer
parent
42ea4463ee
commit
2dfba10d84
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user