Support type inference for self type materialization calls

This commit is contained in:
Victor Petukhov
2021-06-30 16:21:58 +03:00
parent 44cf4be1e5
commit 51c5a54e31
21 changed files with 183 additions and 89 deletions
@@ -41,7 +41,7 @@ class ClassicTypeSystemContextForCS(override val builtIns: KotlinBuiltIns) : Typ
captureStatus: CaptureStatus
): CapturedTypeMarker {
require(lowerType is UnwrappedType?, lowerType::errorMessage)
require(constructorProjection is TypeProjectionImpl, constructorProjection::errorMessage)
require(constructorProjection is TypeProjectionBase, constructorProjection::errorMessage)
@Suppress("UNCHECKED_CAST")
val newCapturedTypeConstructor = NewCapturedTypeConstructor(
@@ -49,7 +49,7 @@ class ClassicTypeSystemContextForCS(override val builtIns: KotlinBuiltIns) : Typ
constructorSupertypes as List<UnwrappedType>
)
return NewCapturedType(
CaptureStatus.FOR_INCORPORATION,
captureStatus,
newCapturedTypeConstructor,
lowerType = lowerType
)
@@ -299,11 +299,6 @@ class KotlinConstraintSystemCompleter(
return true
}
hasDeclaredUpperBoundSelfTypes(variableWithConstraints) -> {
fixVariable(this, variableWithConstraints, topLevelAtoms)
return true
}
else -> processVariableWhenNotEnoughInformation(this, variableWithConstraints, topLevelAtoms, diagnosticsHolder)
}
}
@@ -311,33 +306,6 @@ class KotlinConstraintSystemCompleter(
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,