K2/MPP: treat Array<Some> & Array<out Some> as similar types in annotations

#KT-59561 Fixed
Related to KT-61100
This commit is contained in:
Mikhail Glukhikh
2023-10-12 08:44:57 +02:00
committed by Space Team
parent f085d0f660
commit 9f6abfc166
5 changed files with 74 additions and 13 deletions
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.symbols.resolvedAnnotationsWithArguments
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
import org.jetbrains.kotlin.mpp.*
import org.jetbrains.kotlin.name.CallableId
import org.jetbrains.kotlin.name.ClassId
@@ -305,10 +306,21 @@ class FirExpectActualMatchingContextImpl private constructor(
override fun areCompatibleExpectActualTypes(
expectType: KotlinTypeMarker?,
actualType: KotlinTypeMarker?,
parameterOfAnnotationComparisonMode: Boolean,
): Boolean {
if (expectType == null) return actualType == null
if (actualType == null) return false
if (parameterOfAnnotationComparisonMode && expectType is ConeClassLikeType && expectType.isArrayType &&
actualType is ConeClassLikeType && actualType.isArrayType
) {
return AbstractTypeChecker.equalTypes(
createTypeCheckerState(),
expectType.convertToArrayWithOutProjections(),
actualType.convertToArrayWithOutProjections()
)
}
return AbstractTypeChecker.equalTypes(
createTypeCheckerState(),
expectType,
@@ -316,6 +328,15 @@ class FirExpectActualMatchingContextImpl private constructor(
)
}
private fun ConeClassLikeType.convertToArrayWithOutProjections(): ConeClassLikeType {
val argumentsWithOutProjection = Array(typeArguments.size) { i ->
val typeArgument = typeArguments[i]
if (typeArgument !is ConeKotlinType) typeArgument
else ConeKotlinTypeProjectionOut(typeArgument)
}
return ConeClassLikeTypeImpl(lookupTag, argumentsWithOutProjection, isNullable)
}
override fun actualTypeIsSubtypeOfExpectType(expectType: KotlinTypeMarker, actualType: KotlinTypeMarker): Boolean {
return AbstractTypeChecker.isSubtypeOf(
createTypeCheckerState(),
@@ -370,7 +391,10 @@ class FirExpectActualMatchingContextImpl private constructor(
check(annotation1.hasResolvedArguments() && annotation2.hasResolvedArguments()) {
"By this time compared annotations are expected to have resolved arguments"
}
if (!areCompatibleExpectActualTypes(annotation1.resolvedType, annotation2.resolvedType)) {
if (!areCompatibleExpectActualTypes(
annotation1.resolvedType, annotation2.resolvedType, parameterOfAnnotationComparisonMode = false
)
) {
return false
}
val args1 = annotation1.argumentMapping.mapping