[NI] Add extra ordering for ready-for-fixation variables

Helps fixing to more specific type in the following situations:
Type1 <: Var1
Var2 <: Var1
Var2 <: Type2

Type1 and Type2 may also be nullable and non-nullable versions of the same type.
Note that no additional constraints can be inferred from such constraints before fixation.
Resulting types for variables will always Type1 and Type2 may also be nullable and non-nullable versions of the same type.
Fixing Var1 first will make Var2's type more specific while fixing Var2 first
will make Var1's type less specific. The first is preferrable in general.
This commit is contained in:
Pavel Kirpichenkov
2020-09-17 14:39:22 +03:00
parent ec8465859c
commit 896fbbd1a3
6 changed files with 43 additions and 2 deletions
@@ -42,7 +42,8 @@ class VariableFixationFinder(
WITH_TRIVIAL_OR_NON_PROPER_CONSTRAINTS, // proper trivial constraint from arguments, Nothing <: T
RELATED_TO_ANY_OUTPUT_TYPE,
FROM_INCORPORATION_OF_DECLARED_UPPER_BOUND,
READY_FOR_FIXATION,
READY_FOR_FIXATION_UPPER,
READY_FOR_FIXATION_LOWER,
READY_FOR_FIXATION_REIFIED,
}
@@ -59,7 +60,8 @@ class VariableFixationFinder(
variableHasOnlyIncorporatedConstraintsFromDeclaredUpperBound(variable) ->
TypeVariableFixationReadiness.FROM_INCORPORATION_OF_DECLARED_UPPER_BOUND
isReified(variable) -> TypeVariableFixationReadiness.READY_FOR_FIXATION_REIFIED
else -> TypeVariableFixationReadiness.READY_FOR_FIXATION
!variableHasLowerProperConstraint(variable) -> TypeVariableFixationReadiness.READY_FOR_FIXATION_UPPER
else -> TypeVariableFixationReadiness.READY_FOR_FIXATION_LOWER
}
fun isTypeVariableHasProperConstraint(context: Context, typeVariable: TypeConstructorMarker): Boolean {
@@ -135,6 +137,13 @@ class VariableFixationFinder(
private fun Context.isReified(variable: TypeConstructorMarker): Boolean =
notFixedTypeVariables[variable]?.typeVariable?.let { isReified(it) } ?: false
private fun Context.variableHasLowerProperConstraint(variable: TypeConstructorMarker): Boolean =
notFixedTypeVariables[variable]?.constraints?.let { constraints ->
constraints.any {
it.kind.isLower() && isProperArgumentConstraint(it)
}
} ?: false
}
inline fun TypeSystemInferenceExtensionContext.isProperTypeForFixation(