[FE 1.0] Skip improper constraints while determining READY_FOR_FIXATION_DECLARED_UPPER_BOUND_WITH_SELF_TYPES type variable readiness

^KT-51148 Fixed
This commit is contained in:
Victor Petukhov
2022-02-09 11:48:30 +03:00
committed by teamcity
parent 500295da68
commit c25e07119c
8 changed files with 119 additions and 7 deletions
@@ -67,7 +67,7 @@ class VariableFixationFinder(
): TypeVariableFixationReadiness = when {
!notFixedTypeVariables.contains(variable) ||
dependencyProvider.isVariableRelatedToTopLevelType(variable) -> TypeVariableFixationReadiness.FORBIDDEN
isTypeInferenceForSelfTypesSupported && hasOnlyDeclaredUpperBoundSelfTypes(variable) ->
isTypeInferenceForSelfTypesSupported && areAllProperConstraintsSelfTypeBased(variable) ->
TypeVariableFixationReadiness.READY_FOR_FIXATION_DECLARED_UPPER_BOUND_WITH_SELF_TYPES
!variableHasProperArgumentConstraints(variable) -> TypeVariableFixationReadiness.WITHOUT_PROPER_ARGUMENT_CONSTRAINT
hasDependencyToOtherTypeVariables(variable) -> TypeVariableFixationReadiness.WITH_COMPLEX_DEPENDENCY
@@ -175,13 +175,29 @@ class VariableFixationFinder(
}
}
private fun Context.hasOnlyDeclaredUpperBoundSelfTypes(variable: TypeConstructorMarker): Boolean {
val constraints = notFixedTypeVariables[variable]?.constraints ?: return false
return constraints.isNotEmpty() && constraints.all {
val typeConstructor = it.type.typeConstructor()
it.position.from is DeclaredUpperBoundConstraintPosition<*>
&& (hasRecursiveTypeParametersWithGivenSelfType(typeConstructor) || isRecursiveTypeParameter(typeConstructor))
private fun Context.isSelfTypeConstraint(constraint: Constraint): Boolean {
val typeConstructor = constraint.type.typeConstructor()
return constraint.position.from is DeclaredUpperBoundConstraintPosition<*>
&& (hasRecursiveTypeParametersWithGivenSelfType(typeConstructor) || isRecursiveTypeParameter(typeConstructor))
}
private fun Context.areAllProperConstraintsSelfTypeBased(variable: TypeConstructorMarker): Boolean {
val constraints = notFixedTypeVariables[variable]?.constraints?.takeIf { it.isNotEmpty() } ?: return false
var hasSelfTypeConstraint = false
var hasOtherProperConstraint = false
for (constraint in constraints) {
if (isSelfTypeConstraint(constraint)) {
hasSelfTypeConstraint = true
}
if (isProperArgumentConstraint(constraint)) {
hasOtherProperConstraint = true
}
if (hasSelfTypeConstraint && hasOtherProperConstraint) break
}
return hasSelfTypeConstraint && !hasOtherProperConstraint
}
}