[NI] Fix issues with star projection uncapturing

Prevent stack overflow during uncapturing of star projection
for parameter with recursive upper bound.
Uncapture star projections for flexible type parameters with
respect to flexible upper bound.

^KT-35210 Fixed
This commit is contained in:
Pavel Kirpichenkov
2019-12-16 20:51:29 +03:00
parent 86dc0925b1
commit ebb9f09656
15 changed files with 317 additions and 9 deletions
@@ -257,11 +257,7 @@ fun KotlinType.unCapture(): KotlinType = unwrap().unCapture()
fun UnwrappedType.unCapture(): UnwrappedType = when (this) {
is AbbreviatedType -> unCapture()
is SimpleType -> unCapture()
is FlexibleType ->
FlexibleTypeImpl(
lowerBound.unCapture() as? SimpleType ?: lowerBound,
upperBound.unCapture() as? SimpleType ?: upperBound
)
is FlexibleType -> unCapture()
}
fun SimpleType.unCapture(): UnwrappedType {
@@ -274,10 +270,8 @@ fun SimpleType.unCapture(): UnwrappedType {
}
fun unCaptureProjection(projection: TypeProjection): TypeProjection {
val unCapturedProjection = projection.type.constructor.safeAs<NewCapturedTypeConstructor>()?.let {
it.projection
} ?: projection
if (unCapturedProjection.type is ErrorType) return unCapturedProjection
val unCapturedProjection = projection.type.constructor.safeAs<NewCapturedTypeConstructor>()?.projection ?: projection
if (unCapturedProjection.isStarProjection || unCapturedProjection.type is ErrorType) return unCapturedProjection
val newArguments = unCapturedProjection.type.arguments.map(::unCaptureProjection)
return TypeProjectionImpl(
@@ -291,6 +285,22 @@ fun AbbreviatedType.unCapture(): SimpleType {
return AbbreviatedType(newType as? SimpleType ?: expandedType, abbreviation)
}
fun FlexibleType.unCapture(): FlexibleType {
val unCapturedLowerBound = when (val unCaptured = lowerBound.unCapture()) {
is SimpleType -> unCaptured
is FlexibleType -> unCaptured.lowerBound
else -> lowerBound
}
val unCapturedUpperBound = when (val unCaptured = upperBound.unCapture()) {
is SimpleType -> unCaptured
is FlexibleType -> unCaptured.upperBound
else -> upperBound
}
return FlexibleTypeImpl(unCapturedLowerBound, unCapturedUpperBound)
}
private fun NewCapturedType.unCaptureTopLevelType(): UnwrappedType {
if (lowerType != null) return lowerType