[NI] Fix subtyping between integer literal types and intersection ones
Consider a call like `select(1, "")`, the resulting type for it is Comparable<Int & String> & Serializable. After variable fixation, the compiler incorporates this type into the constraint system to check for a contradiction, so it checks applicability of argument to the resulting type. In other words, for the above call it checks is `Comparable<Int & String> & Serializable` subtype of `IntegerLiteralType`? Which ends up in checking is `IntegerLiteralType` subtype of `Int & String`. Before this commit, such check was leading to the false result, but because of losing diagnostic (which was fixed in the previous commit: 29f591b1), there was no error
This commit is contained in:
@@ -210,8 +210,10 @@ object AbstractTypeChecker {
|
||||
private fun AbstractTypeCheckerContext.checkSubtypeForIntegerLiteralType(subType: SimpleTypeMarker, superType: SimpleTypeMarker): Boolean? {
|
||||
if (!subType.isIntegerLiteralType() && !superType.isIntegerLiteralType()) return null
|
||||
|
||||
fun typeInIntegerLiteralType(integerLiteralType: SimpleTypeMarker, type: SimpleTypeMarker): Boolean =
|
||||
integerLiteralType.possibleIntegerTypes().any { it.typeConstructor() == type.typeConstructor() }
|
||||
fun typeInIntegerLiteralType(integerLiteralType: SimpleTypeMarker, type: SimpleTypeMarker, checkSupertypes: Boolean): Boolean =
|
||||
integerLiteralType.possibleIntegerTypes().any { possibleType ->
|
||||
(possibleType.typeConstructor() == type.typeConstructor()) || (checkSupertypes && isSubtypeOf(this, type, possibleType))
|
||||
}
|
||||
|
||||
when {
|
||||
subType.isIntegerLiteralType() && superType.isIntegerLiteralType() -> {
|
||||
@@ -219,13 +221,14 @@ object AbstractTypeChecker {
|
||||
}
|
||||
|
||||
subType.isIntegerLiteralType() -> {
|
||||
if (typeInIntegerLiteralType(subType, superType)) {
|
||||
if (typeInIntegerLiteralType(subType, superType, checkSupertypes = false)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
superType.isIntegerLiteralType() -> {
|
||||
if (typeInIntegerLiteralType(superType, subType)) {
|
||||
// Here we also have to check supertypes for intersection types: { Int & String } <: IntegerLiteralTypes
|
||||
if (typeInIntegerLiteralType(superType, subType, checkSupertypes = true)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user