[NI] Fix lambda return type when expected type is not functional type
Introduce a fresh type variable for lambda return type. We can't set expected lambda return type to 'Any?', because we can't infer the actual type from return expressions in lambda in that case.
This commit is contained in:
committed by
Mikhail Zarechenskiy
parent
f637ebe9ff
commit
f578d07b00
+14
-3
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.resolve.calls.components.CreateDescriptorWithFreshTy
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.addSubtypeConstraintIfCompatible
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ArgumentConstraintPosition
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.TypeVariableForLambdaReturnType
|
||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
|
||||
import org.jetbrains.kotlin.types.UnwrappedType
|
||||
@@ -82,7 +83,7 @@ internal object CheckArguments : ResolutionPart {
|
||||
}
|
||||
|
||||
// if expected type isn't function type, then may be it is Function<R>, Any or just `T`
|
||||
fun processLambdaArgument(
|
||||
private fun processLambdaArgument(
|
||||
kotlinCall: KotlinCall,
|
||||
csBuilder: ConstraintSystemBuilder,
|
||||
argument: LambdaKotlinCallArgument,
|
||||
@@ -117,7 +118,7 @@ internal object CheckArguments : ResolutionPart {
|
||||
parameters = argument.parametersTypes?.map { it ?: builtIns.nothingType } ?: emptyList()
|
||||
returnType = (argument as? FunctionExpression)?.returnType ?:
|
||||
expectedType.arguments.singleOrNull()?.type?.unwrap()?.takeIf { isFunctionSupertype } ?:
|
||||
builtIns.nullableAnyType
|
||||
createFreshTypeVariableForLambdaReturnType(csBuilder, argument, builtIns)
|
||||
|
||||
// what about case where expected type is type variable? In old TY such cases was not supported. => do nothing for now. todo design
|
||||
}
|
||||
@@ -130,7 +131,17 @@ internal object CheckArguments : ResolutionPart {
|
||||
return null
|
||||
}
|
||||
|
||||
fun checkCallableExpectedType(
|
||||
private fun createFreshTypeVariableForLambdaReturnType(
|
||||
csBuilder: ConstraintSystemBuilder,
|
||||
argument: LambdaKotlinCallArgument,
|
||||
builtIns: KotlinBuiltIns
|
||||
): UnwrappedType {
|
||||
val typeVariable = TypeVariableForLambdaReturnType(argument, builtIns, "_L")
|
||||
csBuilder.registerVariable(typeVariable)
|
||||
return typeVariable.defaultType
|
||||
}
|
||||
|
||||
private fun checkCallableExpectedType(
|
||||
csBuilder: ConstraintSystemBuilder,
|
||||
argument: CallableReferenceKotlinCallArgument,
|
||||
expectedType: UnwrappedType
|
||||
|
||||
+7
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.resolve.calls.model.KotlinCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.LambdaKotlinCallArgument
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.types.*
|
||||
@@ -55,3 +56,9 @@ class TypeVariableFromCallableDescriptor(
|
||||
val originalTypeParameter: TypeParameterDescriptor,
|
||||
val call: KotlinCall? = null
|
||||
) : NewTypeVariable(originalTypeParameter.builtIns, originalTypeParameter.name.identifier)
|
||||
|
||||
class TypeVariableForLambdaReturnType(
|
||||
val lambdaArgument: LambdaKotlinCallArgument,
|
||||
builtIns: KotlinBuiltIns,
|
||||
name: String
|
||||
) : NewTypeVariable(builtIns, name)
|
||||
Reference in New Issue
Block a user