diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintIncorporator.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintIncorporator.kt index 6af600c7610..fe83dd060f2 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintIncorporator.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintIncorporator.kt @@ -38,6 +38,9 @@ class ConstraintIncorporator( fun addNewIncorporatedConstraint(typeVariable: TypeVariableMarker, type: KotlinTypeMarker, constraintContext: ConstraintContext) } + fun incorporateIntoOtherConstraints(c: Context, typeVariable: TypeVariableMarker, constraint: Constraint) = + c.insideOtherConstraint(typeVariable, constraint) + // \alpha is typeVariable, \beta -- other type variable registered in ConstraintStorage fun incorporate(c: Context, typeVariable: TypeVariableMarker, constraint: Constraint) { // we shouldn't incorporate recursive constraint -- It is too dangerous diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintInjector.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintInjector.kt index a4e4791f39d..5740135d8dc 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintInjector.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintInjector.kt @@ -19,8 +19,7 @@ package org.jetbrains.kotlin.resolve.calls.inference.components import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemOperation import org.jetbrains.kotlin.resolve.calls.inference.model.* -import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintKind.LOWER -import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintKind.UPPER +import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintKind.* import org.jetbrains.kotlin.resolve.calls.model.KotlinCallDiagnostic import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner @@ -56,7 +55,7 @@ class ConstraintInjector( } fun addInitialEqualityConstraint(c: Context, a: KotlinTypeMarker, b: KotlinTypeMarker, position: ConstraintPosition) { - val initialConstraint = InitialConstraint(a, b, ConstraintKind.EQUALITY, position) + val initialConstraint = InitialConstraint(a, b, EQUALITY, position) c.addInitialConstraint(initialConstraint) updateAllowedTypeDepth(c, a) updateAllowedTypeDepth(c, b) @@ -81,8 +80,11 @@ class ConstraintInjector( typeCheckerContext.runIsSubtypeOf(lowerType, upperType) var constraintsFromIsSubtype = true - while (possibleNewConstraints != null) { + if (incorporatePosition.from is FixVariableConstraintPosition && lowerType == incorporatePosition.initialConstraint.a) { + c.incorporateEqualityConstraintForFixingTypeVariable(incorporatePosition, typeCheckerContext) + } + while (possibleNewConstraints != null) { val constraintsToProcess = possibleNewConstraints possibleNewConstraints = null for ((typeVariable, constraint) in constraintsToProcess!!) { @@ -103,7 +105,7 @@ class ConstraintInjector( if (possibleNewConstraints == null || (contextOps != null && c.notFixedTypeVariables.all { typeVariable -> typeVariable.value.constraints.any { constraint -> - constraint.kind == ConstraintKind.EQUALITY && contextOps.isProperType(constraint.type) + constraint.kind == EQUALITY && contextOps.isProperType(constraint.type) } }) ) { @@ -117,6 +119,29 @@ class ConstraintInjector( c.maxTypeDepthFromInitialConstraints = max(c.maxTypeDepthFromInitialConstraints, initialType.typeDepth()) } + private fun Context.incorporateEqualityConstraintForFixingTypeVariable( + incorporatePosition: IncorporationConstraintPosition, + typeCheckerContext: TypeCheckerContext + ) { + if (incorporatePosition.from !is FixVariableConstraintPosition) return + + val typeToIncorporate = incorporatePosition.initialConstraint.b + + if (typeToIncorporate.isUninferredParameter() || typeToIncorporate.isError()) return + + constraintIncorporator.incorporateIntoOtherConstraints( + typeCheckerContext, + incorporatePosition.from.variable, + Constraint( + EQUALITY, + typeToIncorporate, + incorporatePosition, + derivedFrom = setOf(), + isNullabilityConstraint = false + ) + ) + } + private fun Context.shouldWeSkipConstraint( typeVariable: TypeVariableMarker, constraint: Constraint, diff --git a/compiler/testData/diagnostics/tests/inference/completion/postponedArgumentsAnalysis/lackOfDeepIncorporation.kt b/compiler/testData/diagnostics/tests/inference/completion/postponedArgumentsAnalysis/lackOfDeepIncorporation.kt index 70924486f1a..070d76e3361 100644 --- a/compiler/testData/diagnostics/tests/inference/completion/postponedArgumentsAnalysis/lackOfDeepIncorporation.kt +++ b/compiler/testData/diagnostics/tests/inference/completion/postponedArgumentsAnalysis/lackOfDeepIncorporation.kt @@ -30,7 +30,7 @@ class Foo { other1.product( other2.product( other3.product( - bar { d -> { c -> { b -> { a -> function(a, b, c, d) } } } } + bar { d -> { c -> { b -> { a -> function(a, b, c, d) } } } } ) ) ) @@ -43,9 +43,9 @@ class Foo { other1.product( other2.product( other3.product( - other4.product( + other4.product( bar { e -> { d -> { c -> { b -> { a -> function(a, b, c, d, e) } } } } } - ) + ) ) ) )