NI: do explicit incorporation of type of fixing type variable into other constraints
^KT-37380 Fixed
This commit is contained in:
+3
@@ -38,6 +38,9 @@ class ConstraintIncorporator(
|
|||||||
fun addNewIncorporatedConstraint(typeVariable: TypeVariableMarker, type: KotlinTypeMarker, constraintContext: ConstraintContext)
|
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
|
// \alpha is typeVariable, \beta -- other type variable registered in ConstraintStorage
|
||||||
fun incorporate(c: Context, typeVariable: TypeVariableMarker, constraint: Constraint) {
|
fun incorporate(c: Context, typeVariable: TypeVariableMarker, constraint: Constraint) {
|
||||||
// we shouldn't incorporate recursive constraint -- It is too dangerous
|
// we shouldn't incorporate recursive constraint -- It is too dangerous
|
||||||
|
|||||||
+30
-5
@@ -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.ConstraintSystemOperation
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.*
|
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.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintKind.UPPER
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.KotlinCallDiagnostic
|
import org.jetbrains.kotlin.resolve.calls.model.KotlinCallDiagnostic
|
||||||
import org.jetbrains.kotlin.types.*
|
import org.jetbrains.kotlin.types.*
|
||||||
import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner
|
import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner
|
||||||
@@ -56,7 +55,7 @@ class ConstraintInjector(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun addInitialEqualityConstraint(c: Context, a: KotlinTypeMarker, b: KotlinTypeMarker, position: ConstraintPosition) {
|
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)
|
c.addInitialConstraint(initialConstraint)
|
||||||
updateAllowedTypeDepth(c, a)
|
updateAllowedTypeDepth(c, a)
|
||||||
updateAllowedTypeDepth(c, b)
|
updateAllowedTypeDepth(c, b)
|
||||||
@@ -81,8 +80,11 @@ class ConstraintInjector(
|
|||||||
typeCheckerContext.runIsSubtypeOf(lowerType, upperType)
|
typeCheckerContext.runIsSubtypeOf(lowerType, upperType)
|
||||||
var constraintsFromIsSubtype = true
|
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
|
val constraintsToProcess = possibleNewConstraints
|
||||||
possibleNewConstraints = null
|
possibleNewConstraints = null
|
||||||
for ((typeVariable, constraint) in constraintsToProcess!!) {
|
for ((typeVariable, constraint) in constraintsToProcess!!) {
|
||||||
@@ -103,7 +105,7 @@ class ConstraintInjector(
|
|||||||
if (possibleNewConstraints == null ||
|
if (possibleNewConstraints == null ||
|
||||||
(contextOps != null && c.notFixedTypeVariables.all { typeVariable ->
|
(contextOps != null && c.notFixedTypeVariables.all { typeVariable ->
|
||||||
typeVariable.value.constraints.any { constraint ->
|
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())
|
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(
|
private fun Context.shouldWeSkipConstraint(
|
||||||
typeVariable: TypeVariableMarker,
|
typeVariable: TypeVariableMarker,
|
||||||
constraint: Constraint,
|
constraint: Constraint,
|
||||||
|
|||||||
+3
-3
@@ -30,7 +30,7 @@ class Foo<out A> {
|
|||||||
other1.product(
|
other1.product(
|
||||||
other2.product(
|
other2.product(
|
||||||
other3.product(
|
other3.product(
|
||||||
<!TYPE_MISMATCH!>bar { d -> { c -> { b -> { a -> function(<!DEBUG_INFO_EXPRESSION_TYPE("A")!>a<!>, <!DEBUG_INFO_EXPRESSION_TYPE("B")!>b<!>, <!DEBUG_INFO_EXPRESSION_TYPE("C")!>c<!>, <!DEBUG_INFO_EXPRESSION_TYPE("D")!>d<!>) } } } }<!>
|
bar { d -> { c -> { b -> { a -> function(<!DEBUG_INFO_EXPRESSION_TYPE("A")!>a<!>, <!DEBUG_INFO_EXPRESSION_TYPE("B")!>b<!>, <!DEBUG_INFO_EXPRESSION_TYPE("C")!>c<!>, <!DEBUG_INFO_EXPRESSION_TYPE("D")!>d<!>) } } } }
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -43,9 +43,9 @@ class Foo<out A> {
|
|||||||
other1.product(
|
other1.product(
|
||||||
other2.product(
|
other2.product(
|
||||||
other3.product(
|
other3.product(
|
||||||
<!TYPE_MISMATCH!>other4.product(
|
other4.product(
|
||||||
bar { e -> { d -> { c -> { b -> { a -> function(<!DEBUG_INFO_EXPRESSION_TYPE("A")!>a<!>, <!DEBUG_INFO_EXPRESSION_TYPE("B")!>b<!>, <!DEBUG_INFO_EXPRESSION_TYPE("C")!>c<!>, <!DEBUG_INFO_EXPRESSION_TYPE("D")!>d<!>, <!DEBUG_INFO_EXPRESSION_TYPE("E")!>e<!>) } } } } }
|
bar { e -> { d -> { c -> { b -> { a -> function(<!DEBUG_INFO_EXPRESSION_TYPE("A")!>a<!>, <!DEBUG_INFO_EXPRESSION_TYPE("B")!>b<!>, <!DEBUG_INFO_EXPRESSION_TYPE("C")!>c<!>, <!DEBUG_INFO_EXPRESSION_TYPE("D")!>d<!>, <!DEBUG_INFO_EXPRESSION_TYPE("E")!>e<!>) } } } } }
|
||||||
)<!>
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user