[MPP] Use module's type checker for upper bound checks

The default type checker doesn't have a correct type refinement setup.
This can cause false positives in subtyping of upper bounds in edge
cases with expect type arguments.

See the tests in the intellij repo.

KTIJ-22295
This commit is contained in:
Pavel Kirpichenkov
2022-08-31 19:58:51 +03:00
committed by Space
parent f8462f1b0c
commit 24dcad0d9c
2 changed files with 8 additions and 3 deletions
@@ -19,10 +19,13 @@ import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm.UPPER_BOUND_VIOLAT
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm.UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION_BASED_ON_JAVA_ANNOTATIONS
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeSubstitutor
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
import org.jetbrains.kotlin.types.getEnhancementDeeply
// TODO: remove this checker after removing support LV < 1.6
class WarningAwareUpperBoundChecker : UpperBoundChecker() {
class WarningAwareUpperBoundChecker(
typeChecker: KotlinTypeChecker,
) : UpperBoundChecker(typeChecker) {
override fun checkBoundsOfExpandedTypeAlias(type: KotlinType, expression: KtExpression, trace: BindingTrace) {
val typeParameters = type.constructor.parameters
@@ -23,7 +23,9 @@ import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
import org.jetbrains.kotlin.types.typeUtil.containsTypeAliasParameters
@DefaultImplementation(impl = UpperBoundChecker::class)
open class UpperBoundChecker {
open class UpperBoundChecker(
private val typeChecker: KotlinTypeChecker,
) {
open fun checkBoundsOfExpandedTypeAlias(type: KotlinType, expression: KtExpression, trace: BindingTrace) {
// do nothing in the strict mode as the errors are already reported in the type inference if necessary
}
@@ -141,7 +143,7 @@ open class UpperBoundChecker {
): Boolean {
val substitutedBound = substitutor.safeSubstitute(bound, Variance.INVARIANT)
if (!KotlinTypeChecker.DEFAULT.isSubtypeOf(argumentType, substitutedBound)) {
if (!typeChecker.isSubtypeOf(argumentType, substitutedBound)) {
if (argumentReference != null) {
upperBoundViolatedReporter.report(argumentReference, substitutedBound)
} else if (typeAliasUsageElement != null && !substitutedBound.containsTypeAliasParameters() && !argumentType.containsTypeAliasParameters()) {