diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/MutableConstraintStorage.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/MutableConstraintStorage.kt index da71678a849a8..4bcb3c3829df5 100644 --- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/MutableConstraintStorage.kt +++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/MutableConstraintStorage.kt @@ -130,14 +130,18 @@ class MutableVariableWithConstraints private constructor( fun addConstraint(constraint: Constraint, inferenceLogger: InferenceLogger?): Pair { val isLowerAndFlexibleTypeWithDefNotNullLowerBound = constraint.isLowerAndFlexibleTypeWithDefNotNullLowerBound() - for (previousConstraint in getConstraintsWithSameTypeHashCode(constraint)) { - if (previousConstraint.type == constraint.type - && previousConstraint.isNullabilityConstraint == constraint.isNullabilityConstraint + val previousConstraints = getConstraintsWithSameTypeHashCode(constraint) + + for (previousConstraint in previousConstraints) { + if (constraintMatchesTypeAndIsNullability(previousConstraint, constraint) && + newConstraintIsUseless(previousConstraint, constraint) ) { - if (newConstraintIsUseless(previousConstraint, constraint)) { - return previousConstraint to false - } + return previousConstraint to false + } + } + for (previousConstraint in previousConstraints) { + if (constraintMatchesTypeAndIsNullability(previousConstraint, constraint)) { val isMatchingForSimplification = when (previousConstraint.kind) { ConstraintKind.LOWER -> constraint.kind.isUpper() ConstraintKind.UPPER -> constraint.kind.isLower() @@ -217,6 +221,10 @@ class MutableVariableWithConstraints private constructor( clearGroupedConstraintCaches() } + private fun constraintMatchesTypeAndIsNullability(old: Constraint, new: Constraint): Boolean { + return old.type == new.type && old.isNullabilityConstraint == new.isNullabilityConstraint + } + private fun newConstraintIsUseless(old: Constraint, new: Constraint): Boolean { // Constraints from declared upper bound are quite special -- they aren't considered as a proper ones // In other words, user-defined constraints have "higher" priority and here we're trying not to loose them