IR: check type parameter bounds equality in overrides

The code is exactly the same as in K1's
`OverridingUtil.areTypeParametersEquivalent`.

 #KT-63442 Fixed
This commit is contained in:
Alexander Udalov
2023-11-24 13:12:04 +01:00
committed by Space Team
parent 560c1cacf3
commit fc7de5ab97
25 changed files with 816 additions and 22 deletions
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.ir.types.createIrTypeCheckerState
import org.jetbrains.kotlin.resolve.OverridingUtil.OverrideCompatibilityInfo
import org.jetbrains.kotlin.resolve.OverridingUtil.OverrideCompatibilityInfo.*
import org.jetbrains.kotlin.types.AbstractTypeChecker
import org.jetbrains.kotlin.types.TypeCheckerState
class IrOverrideChecker(
private val typeSystem: IrTypeSystemContext,
@@ -100,36 +101,48 @@ class IrOverrideChecker(
superValueParameters.size != subValueParameters.size -> return incompatible("Value parameter number mismatch")
}
// TODO: check the bounds. See OverridingUtil.areTypeParametersEquivalent()
// superTypeParameters.forEachIndexed { index, parameter ->
// if (!AbstractTypeChecker.areTypeParametersEquivalent(
// typeCheckerContext as AbstractTypeCheckerContext,
// subTypeParameters[index].type,
// parameter.type
// )
// ) return OverrideCompatibilityInfo.incompatible("Type parameter bounds mismatch")
// }
val typeCheckerState = createIrTypeCheckerState(
IrTypeSystemContextWithAdditionalAxioms(
typeSystem,
superTypeParameters,
subTypeParameters
)
IrTypeSystemContextWithAdditionalAxioms(typeSystem, superTypeParameters, subTypeParameters)
)
superValueParameters.forEachIndexed { index, parameter ->
if (!AbstractTypeChecker.equalTypes(
typeCheckerState,
subValueParameters[index].type,
parameter.type
)
) return incompatible("Value parameter type mismatch")
for ((index, superTypeParameter) in superTypeParameters.withIndex()) {
if (!areTypeParametersEquivalent(superTypeParameter, subTypeParameters[index], typeCheckerState)) {
return incompatible("Type parameter bounds mismatch")
}
}
for ((index, superValueParameter) in superValueParameters.withIndex()) {
if (!AbstractTypeChecker.equalTypes(typeCheckerState, subValueParameters[index].type, superValueParameter.type)) {
return incompatible("Value parameter type mismatch")
}
}
return success()
}
private fun areTypeParametersEquivalent(
superTypeParameter: IrTypeParameter,
subTypeParameter: IrTypeParameter,
typeCheckerState: TypeCheckerState,
): Boolean {
val superBounds = superTypeParameter.superTypes
val subBounds = subTypeParameter.superTypes.toMutableList()
if (superBounds.size != subBounds.size) return false
outer@ for (superBound in superBounds) {
val it = subBounds.listIterator()
while (it.hasNext()) {
val subBound = it.next()
if (AbstractTypeChecker.equalTypes(typeCheckerState, superBound, subBound)) {
it.remove()
continue@outer
}
}
return false
}
return true
}
private fun runExternalOverridabilityConditions(
superMember: IrOverridableMember,
subMember: IrOverridableMember,