NI: Fix some unwanted exclusions constraints with remained corresponding optimization
This commit is contained in:
+48
-4
@@ -157,6 +157,11 @@ class ConstraintIncorporator(
|
||||
isSubtype: Boolean
|
||||
) {
|
||||
if (targetVariable in getNestedTypeVariables(newConstraint)) return
|
||||
|
||||
val isUsefulForNullabilityConstraint =
|
||||
isPotentialUsefulNullabilityConstraint(newConstraint, otherConstraint.type, otherConstraint.kind)
|
||||
|
||||
if (!isUsefulForNullabilityConstraint && !containsConstrainingTypeWithoutProjection(newConstraint, otherConstraint)) return
|
||||
if (trivialConstraintTypeInferenceOracle.isGeneratedConstraintTrivial(
|
||||
baseConstraint, otherConstraint, newConstraint, isSubtype
|
||||
)
|
||||
@@ -172,6 +177,28 @@ class ConstraintIncorporator(
|
||||
addNewIncorporatedConstraint(targetVariable, newConstraint, ConstraintContext(kind, derivedFrom))
|
||||
}
|
||||
|
||||
fun Context.containsConstrainingTypeWithoutProjection(
|
||||
newConstraint: KotlinTypeMarker,
|
||||
otherConstraint: Constraint
|
||||
): Boolean {
|
||||
return getNestedArguments(newConstraint).any {
|
||||
it.getType().typeConstructor() == otherConstraint.type.typeConstructor() && it.getVariance() == TypeVariance.INV
|
||||
}
|
||||
}
|
||||
|
||||
private fun Context.isPotentialUsefulNullabilityConstraint(
|
||||
newConstraint: KotlinTypeMarker,
|
||||
otherConstraint: KotlinTypeMarker,
|
||||
kind: ConstraintKind
|
||||
): Boolean {
|
||||
val otherConstraintCanAddNullabilityToNewOne =
|
||||
!newConstraint.isNullableType() && otherConstraint.isNullableType() && kind == ConstraintKind.LOWER
|
||||
val newConstraintCanAddNullabilityToOtherOne =
|
||||
newConstraint.isNullableType() && !otherConstraint.isNullableType() && kind == ConstraintKind.UPPER
|
||||
|
||||
return otherConstraintCanAddNullabilityToNewOne || newConstraintCanAddNullabilityToOtherOne
|
||||
}
|
||||
|
||||
fun Context.getNestedTypeVariables(type: KotlinTypeMarker): List<TypeVariableMarker> =
|
||||
getNestedArguments(type).mapNotNull { getTypeVariable(it.getType().typeConstructor()) }
|
||||
|
||||
@@ -189,19 +216,36 @@ class ConstraintIncorporator(
|
||||
|
||||
private fun TypeSystemInferenceExtensionContext.getNestedArguments(type: KotlinTypeMarker): List<TypeArgumentMarker> {
|
||||
val result = ArrayList<TypeArgumentMarker>()
|
||||
|
||||
val stack = ArrayDeque<TypeArgumentMarker>()
|
||||
|
||||
when (type) {
|
||||
is FlexibleType -> {
|
||||
stack.push(createTypeArgument(type.lowerBound, TypeVariance.INV))
|
||||
stack.push(createTypeArgument(type.upperBound, TypeVariance.INV))
|
||||
}
|
||||
else -> stack.push(createTypeArgument(type, TypeVariance.INV))
|
||||
}
|
||||
|
||||
stack.push(createTypeArgument(type, TypeVariance.INV))
|
||||
|
||||
val addArgumentsToStack = { projectedType: KotlinTypeMarker ->
|
||||
for (argumentIndex in 0 until projectedType.argumentsCount()) {
|
||||
stack.add(projectedType.getArgument(argumentIndex))
|
||||
}
|
||||
}
|
||||
|
||||
while (!stack.isEmpty()) {
|
||||
val typeProjection = stack.pop()
|
||||
if (typeProjection.isStarProjection()) continue
|
||||
|
||||
result.add(typeProjection)
|
||||
|
||||
val projectedType = typeProjection.getType()
|
||||
for (argumentIndex in 0 until projectedType.argumentsCount()) {
|
||||
stack.add(projectedType.getArgument(argumentIndex))
|
||||
when (val projectedType = typeProjection.getType()) {
|
||||
is FlexibleType -> {
|
||||
addArgumentsToStack(projectedType.lowerBound)
|
||||
addArgumentsToStack(projectedType.upperBound)
|
||||
}
|
||||
else -> addArgumentsToStack(projectedType)
|
||||
}
|
||||
}
|
||||
return result
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
|
||||
fun <T : Any> nullable(): T? = null
|
||||
|
||||
val value = nullable<Int>() <!NI;TYPE_MISMATCH!>?:<!> <!OI;TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH!>nullable()<!>
|
||||
val value = nullable<Int>() ?: <!OI;TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH!>nullable()<!>
|
||||
Reference in New Issue
Block a user