Inference for some kind of self types

This commit is contained in:
Mikhail Zarechenskiy
2021-06-18 02:50:22 +03:00
committed by Victor Petukhov
parent db72fd1e93
commit 44cf4be1e5
15 changed files with 273 additions and 16 deletions
@@ -293,17 +293,51 @@ class KotlinConstraintSystemCompleter(
val variableWithConstraints = notFixedTypeVariables.getValue(variableForFixation.variable)
if (variableForFixation.hasProperConstraint) {
fixVariable(this, variableWithConstraints, topLevelAtoms)
return true
} else {
processVariableWhenNotEnoughInformation(this, variableWithConstraints, topLevelAtoms, diagnosticsHolder)
when {
variableForFixation.hasProperConstraint -> {
fixVariable(this, variableWithConstraints, topLevelAtoms)
return true
}
hasDeclaredUpperBoundSelfTypes(variableWithConstraints) -> {
fixVariable(this, variableWithConstraints, topLevelAtoms)
return true
}
else -> processVariableWhenNotEnoughInformation(this, variableWithConstraints, topLevelAtoms, diagnosticsHolder)
}
}
return false
}
private fun ConstraintSystemCompletionContext.hasDeclaredUpperBoundSelfTypes(variable: VariableWithConstraints): Boolean {
val constraints = variable.constraints
return constraints.isNotEmpty() && constraints.all {
it.position.from is DeclaredUpperBoundConstraintPosition<*> && isSelfType(it.type.typeConstructor())
}
}
private fun ConstraintSystemCompletionContext.isSelfType(typeConstructor: TypeConstructorMarker): Boolean {
if (typeConstructor.isTypeParameterTypeConstructor()) {
val supertype = typeConstructor.supertypes().firstOrNull() ?: return false
return isSelfType(supertype.typeConstructor())
}
val parametersCount = typeConstructor.parametersCount()
if (parametersCount == 0) return false
for (parameterId in 0 until parametersCount) {
val parameter = typeConstructor.getParameter(parameterId)
if (parameter.upperBoundCount() != 1) return false
val upperBound = parameter.getUpperBound(0)
if (upperBound.typeConstructor() == typeConstructor) return true
}
return false
}
private fun processVariableWhenNotEnoughInformation(
c: ConstraintSystemCompletionContext,
variableWithConstraints: VariableWithConstraints,