[FIR] fix internal error on suspend conversion with not-computed return type

^KT-62836 Fixed
This commit is contained in:
Dmitrii Gridin
2024-03-05 15:45:58 +01:00
committed by Space Team
parent f4096ae8e9
commit 928fb94052
11 changed files with 58 additions and 25 deletions
@@ -24,7 +24,9 @@ import org.jetbrains.kotlin.fir.resolve.transformers.ensureResolvedTypeDeclarati
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
import org.jetbrains.kotlin.fir.types.unwrapLowerBound
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.StandardClassIds
@@ -287,8 +289,10 @@ fun Candidate.resolvePlainArgumentType(
// If the argument is of functional type and the expected type is a suspend function type, we need to do "suspend conversion."
if (expectedType != null) {
argumentTypeWithCustomConversion(
session, context.bodyResolveComponents.scopeSession, expectedType, argumentTypeForApplicabilityCheck
context.typeContext.argumentTypeWithCustomConversion(
session = session,
expectedType = expectedType,
argumentType = argumentTypeForApplicabilityCheck,
)?.let {
argumentTypeForApplicabilityCheck = it
substitutor.substituteOrSelf(argumentTypeForApplicabilityCheck)
@@ -301,11 +305,10 @@ fun Candidate.resolvePlainArgumentType(
)
}
private fun argumentTypeWithCustomConversion(
private fun ConeInferenceContext.argumentTypeWithCustomConversion(
session: FirSession,
scopeSession: ScopeSession,
expectedType: ConeKotlinType,
argumentType: ConeKotlinType
argumentType: ConeKotlinType,
): ConeKotlinType? {
// Expect the expected type to be a not regular functional type (e.g. suspend or custom)
val expectedTypeKind = expectedType.functionTypeKind(session) ?: return null
@@ -314,21 +317,18 @@ private fun argumentTypeWithCustomConversion(
// We want to check the argument type against non-suspend functional type.
val expectedFunctionType = expectedType.customFunctionTypeToSimpleFunctionType(session)
val argumentTypeWithInvoke = argumentType.findSubtypeOfBasicFunctionType(session, expectedFunctionType)
val argumentTypeWithInvoke = argumentType.findSubtypeOfBasicFunctionType(session, expectedFunctionType) ?: return null
val functionType = argumentTypeWithInvoke.unwrapLowerBound()
.fastCorrespondingSupertypes(expectedFunctionType.typeConstructor())
?.firstOrNull() as? ConeKotlinType ?: return null
return argumentTypeWithInvoke?.findContributedInvokeSymbol(
session,
scopeSession,
expectedFunctionType,
shouldCalculateReturnTypesOfFakeOverrides = false
)?.let { invokeSymbol ->
createFunctionType(
expectedTypeKind,
invokeSymbol.fir.valueParameters.map { it.returnTypeRef.coneType },
null,
invokeSymbol.fir.returnTypeRef.coneType,
)
}
val typeArguments = functionType.typeArguments.map { it.type ?: session.builtinTypes.nullableAnyType.type }.ifEmpty { return null }
return createFunctionType(
kind = expectedTypeKind,
parameters = typeArguments.subList(0, typeArguments.lastIndex),
receiverType = null,
rawReturnType = typeArguments.last(),
)
}
internal fun prepareCapturedType(argumentType: ConeKotlinType, context: ResolutionContext): ConeKotlinType {