Consider intersection with ILT subtype of ILT

This commit is contained in:
Victor Petukhov
2020-09-07 17:46:46 +03:00
parent 7bd9c52732
commit 140edb2215
@@ -235,28 +235,40 @@ object AbstractTypeChecker {
return isSubtypeOfForSingleClassifierType(subType.lowerBoundIfFlexible(), superType.upperBoundIfFlexible()) return isSubtypeOfForSingleClassifierType(subType.lowerBoundIfFlexible(), superType.upperBoundIfFlexible())
} }
private fun AbstractTypeCheckerContext.checkSubtypeForIntegerLiteralType(subType: SimpleTypeMarker, superType: SimpleTypeMarker): Boolean? { private fun AbstractTypeCheckerContext.checkSubtypeForIntegerLiteralType(
subType: SimpleTypeMarker,
superType: SimpleTypeMarker
): Boolean? {
if (!subType.isIntegerLiteralType() && !superType.isIntegerLiteralType()) return null if (!subType.isIntegerLiteralType() && !superType.isIntegerLiteralType()) return null
fun typeInIntegerLiteralType(integerLiteralType: SimpleTypeMarker, type: SimpleTypeMarker, checkSupertypes: Boolean): Boolean = fun isTypeInIntegerLiteralType(integerLiteralType: SimpleTypeMarker, type: SimpleTypeMarker, checkSupertypes: Boolean): Boolean =
integerLiteralType.possibleIntegerTypes().any { possibleType -> integerLiteralType.possibleIntegerTypes().any { possibleType ->
(possibleType.typeConstructor() == type.typeConstructor()) || (checkSupertypes && isSubtypeOf(this, type, possibleType)) (possibleType.typeConstructor() == type.typeConstructor()) || (checkSupertypes && isSubtypeOf(this, type, possibleType))
} }
fun isIntegerLiteralTypeInIntersectionComponents(type: SimpleTypeMarker): Boolean {
val typeConstructor = type.typeConstructor()
return typeConstructor is IntersectionTypeConstructorMarker
&& typeConstructor.supertypes().any { it.asSimpleType()?.isIntegerLiteralType() == true }
}
when { when {
subType.isIntegerLiteralType() && superType.isIntegerLiteralType() -> { subType.isIntegerLiteralType() && superType.isIntegerLiteralType() -> {
return true return true
} }
subType.isIntegerLiteralType() -> { subType.isIntegerLiteralType() -> {
if (typeInIntegerLiteralType(subType, superType, checkSupertypes = false)) { if (isTypeInIntegerLiteralType(subType, superType, checkSupertypes = false)) {
return true return true
} }
} }
superType.isIntegerLiteralType() -> { superType.isIntegerLiteralType() -> {
// Here we also have to check supertypes for intersection types: { Int & String } <: IntegerLiteralTypes // Here we also have to check supertypes for intersection types: { Int & String } <: IntegerLiteralTypes
if (typeInIntegerLiteralType(superType, subType, checkSupertypes = true)) { if (isIntegerLiteralTypeInIntersectionComponents(subType)
|| isTypeInIntegerLiteralType(superType, subType, checkSupertypes = true)
) {
return true return true
} }
} }