NI: take into account effective variance during adding constraints from LHS instead of only use site variance

^KT-39220 Fixed
This commit is contained in:
Victor Petukhov
2020-06-01 13:13:03 +03:00
parent 561c6747a6
commit 8d05253369
7 changed files with 315 additions and 8 deletions
@@ -22,10 +22,9 @@ import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor
import org.jetbrains.kotlin.resolve.calls.inference.model.*
import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.types.ErrorUtils
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.UnwrappedType
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.checker.convertVariance
import org.jetbrains.kotlin.types.model.TypeVariance
import org.jetbrains.kotlin.types.typeUtil.builtIns
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
@@ -280,11 +279,16 @@ private fun ConstraintSystemBuilder.addConstraintFromLHS(
val expectedTypeProjectionForLHS = expectedType.arguments.first()
val expectedTypeForLHS = expectedTypeProjectionForLHS.type
val constraintPosition = LHSArgumentConstraintPosition(argument, lhsResult.qualifier ?: lhsResult.unboundDetailedReceiver)
val expectedTypeVariance = expectedTypeProjectionForLHS.projectionKind.convertVariance()
val effectiveVariance = AbstractTypeChecker.effectiveVariance(
expectedType.constructor.parameters.first().variance.convertVariance(),
expectedTypeVariance
) ?: expectedTypeVariance
when (expectedTypeProjectionForLHS.projectionKind) {
Variance.INVARIANT -> addEqualityConstraint(lhsType, expectedTypeForLHS, constraintPosition)
Variance.IN_VARIANCE -> addSubtypeConstraint(expectedTypeForLHS, lhsType, constraintPosition)
Variance.OUT_VARIANCE -> addSubtypeConstraint(lhsType, expectedTypeForLHS, constraintPosition)
when (effectiveVariance) {
TypeVariance.INV -> addEqualityConstraint(lhsType, expectedTypeForLHS, constraintPosition)
TypeVariance.IN -> addSubtypeConstraint(expectedTypeForLHS, lhsType, constraintPosition)
TypeVariance.OUT -> addSubtypeConstraint(lhsType, expectedTypeForLHS, constraintPosition)
}
}