FIR: fix invoke lookup for SAM resolution

This commit is contained in:
Jinseong Jeon
2020-12-10 15:05:47 -08:00
committed by TeamCityServer
parent 3bca6ae893
commit 7df289746c
2 changed files with 31 additions and 3 deletions
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
import org.jetbrains.kotlin.resolve.calls.inference.addSubtypeConstraintIfCompatible
import org.jetbrains.kotlin.resolve.calls.inference.model.SimpleConstraintSystemConstraintPosition
import org.jetbrains.kotlin.types.AbstractTypeChecker
import org.jetbrains.kotlin.types.model.CaptureStatus
import org.jetbrains.kotlin.utils.addToStdlib.runIf
@@ -409,8 +410,35 @@ fun FirExpression.isFunctional(
val invokeSymbol =
coneType.findContributedInvokeSymbol(
session, scopeSession, classLikeExpectedFunctionType, shouldCalculateReturnTypesOfFakeOverrides = false
)
return invokeSymbol != null
) ?: return false
// Make sure the contributed `invoke` is indeed a wanted functional type by checking if types are compatible.
val expectedReturnType = classLikeExpectedFunctionType.returnType(session)!!.lowerBoundIfFlexible()
val returnTypeCompatible =
expectedReturnType is ConeTypeParameterType ||
AbstractTypeChecker.isSubtypeOf(
session.inferenceComponents.ctx,
invokeSymbol.fir.returnTypeRef.coneType,
expectedReturnType,
isFromNullabilityConstraint = false
)
if (!returnTypeCompatible) {
return false
}
if (invokeSymbol.fir.valueParameters.size != classLikeExpectedFunctionType.typeArguments.size - 1) {
return false
}
val parameterPairs =
invokeSymbol.fir.valueParameters.zip(classLikeExpectedFunctionType.valueParameterTypesIncludingReceiver(session))
return parameterPairs.all { (invokeParameter, expectedParameter) ->
val expectedParameterType = expectedParameter!!.lowerBoundIfFlexible()
expectedParameterType is ConeTypeParameterType ||
AbstractTypeChecker.isSubtypeOf(
session.inferenceComponents.ctx,
invokeParameter.returnTypeRef.coneType,
expectedParameterType,
isFromNullabilityConstraint = false
)
}
}
}
}
@@ -16,7 +16,7 @@ public interface MyListener<F extends MyFuture<?>> {
typealias Handler = (cause: Throwable?) -> Unit
fun <T> MyFuture<T>.setup() {
<!INAPPLICABLE_CANDIDATE!>addListener<!>(ListenerImpl<T, MyFuture<T>>())
addListener(ListenerImpl<T, MyFuture<T>>())
addListener { }
}