diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/cir/utils.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/cir/utils.kt index 38b01137ea7..1bdb573482f 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/cir/utils.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/cir/utils.kt @@ -85,27 +85,25 @@ internal tailrec fun computeExpandedType(underlyingType: CirClassOrTypeAliasType internal inline fun CirDeclaration.unsupported(): Nothing = error("This method should never be called on ${this::class.java}, $this") internal fun CirClassOrTypeAliasType.withParentArguments( - parentArguments: List, parentIsMarkedNullable: Boolean + parentArguments: List ): CirClassOrTypeAliasType { - val newIsMarkedNullable = isMarkedNullable || parentIsMarkedNullable - val newArguments = arguments.map { oldArgument -> if (oldArgument !is CirRegularTypeProjection) return@map oldArgument when (val type = oldArgument.type) { is CirTypeParameterType -> parentArguments[type.index] is CirClassOrTypeAliasType -> CirRegularTypeProjection( - oldArgument.projectionKind, type.withParentArguments(parentArguments, parentIsMarkedNullable) + oldArgument.projectionKind, type.withParentArguments(parentArguments) ) else -> oldArgument } } - return when (val newType = makeNullableIfNecessary(newIsMarkedNullable).withArguments(newArguments)) { + return when (val newType = withArguments(newArguments)) { this -> this is CirClassType -> newType is CirTypeAliasType -> newType.withUnderlyingType( - newType.underlyingType.withParentArguments(parentArguments, newIsMarkedNullable) + newType.underlyingType.withParentArguments(parentArguments) ) } } diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/ClassOrTypeAliasTypeCommonizer.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/ClassOrTypeAliasTypeCommonizer.kt index ca2661aa859..52b2b7aa088 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/ClassOrTypeAliasTypeCommonizer.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/ClassOrTypeAliasTypeCommonizer.kt @@ -90,7 +90,8 @@ internal class ClassOrTypeAliasTypeCommonizer( arguments = arguments, isMarkedNullable = isMarkedNullable, underlyingType = dependencyClassifier.underlyingType.toCirClassOrTypeAliasTypeOrNull(classifiers.commonDependencies) - ?.withParentArguments(arguments, isMarkedNullable) ?: return null + ?.makeNullableIfNecessary(isMarkedNullable) + ?.withParentArguments(arguments) ?: return null ) else -> Unit @@ -114,7 +115,9 @@ internal class ClassOrTypeAliasTypeCommonizer( typeAliasId = classifierId, arguments = arguments, isMarkedNullable = isMarkedNullable, - underlyingType = commonizedClassifier.underlyingType.withParentArguments(arguments, isMarkedNullable) + underlyingType = commonizedClassifier.underlyingType + .makeNullableIfNecessary(isMarkedNullable) + .withParentArguments(arguments) ) else -> null diff --git a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/hierarchical/ParameterizedTypesCommonizationTest.kt b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/hierarchical/ParameterizedTypesCommonizationTest.kt index e0a231286bb..f4d67d6c0f4 100644 --- a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/hierarchical/ParameterizedTypesCommonizationTest.kt +++ b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/hierarchical/ParameterizedTypesCommonizationTest.kt @@ -582,7 +582,7 @@ class ParameterizedTypesCommonizationTest : AbstractInlineSourcesCommonizationTe ) } - fun `test KT-51686`() { + fun `test KT-51686 - type argument is parameterized class`() { val result = commonize { outputTarget("(a, b)") "a" withSource """ @@ -618,4 +618,99 @@ class ParameterizedTypesCommonizationTest : AbstractInlineSourcesCommonizationTe """.trimIndent() ) } + + fun `test KT-51686 - type argument is parameterized class - nullability - 0`() { + val result = commonize { + outputTarget("(a, b)") + "a" withSource """ + class A + class Y + class X + typealias TA = X> + fun f(): TA? = null!! + """.trimIndent() + + "b" withSource """ + class A + class Y + class X + typealias TA = X> + fun f(): TA? = null!! + """.trimIndent() + } + + result.assertCommonized( + "(a, b)", """ + expect class A() + expect class Y() + expect class X() + typealias TA = X> + expect fun f(): TA? + """.trimIndent() + ) + } + + fun `test KT-51686 - type argument is parameterized class - nullability - 1`() { + val result = commonize { + outputTarget("(a, b)") + "a" withSource """ + class A + class X + typealias TA1 = X + typealias TA2 = X? + + val p1: A> get() = null!! + val p2: A get() = null!! + val p3: A?> get() = null!! + val p4: A> get() = null!! + val p5: A> get() = null!! + val p6: A?> get() = null!! + val p7: A>? get() = null!! + val p8: TA2> get() = null!! + val p9: TA2?> get() = null!! + val p10: TA2 get() = null!! + fun f1(): A>> = null!! + """.trimIndent() + + "b" withSource """ + class A + class X + typealias TA1 = X + typealias TA2 = X? + + val p1: A> get() = null!! + val p2: A get() = null!! + val p3: A?> get() = null!! + val p4: A> get() = null!! + val p5: A> get() = null!! + val p6: A?> get() = null!! + val p7: A>? get() = null!! + val p8: TA2> get() = null!! + val p9: TA2?> get() = null!! + val p10: TA2 get() = null!! + fun f1(): A>> = null!! + """.trimIndent() + } + + result.assertCommonized( + "(a, b)", """ + expect class A() + expect class X() + typealias TA1 = X + typealias TA2 = X? + + expect val p1: A> + expect val p2: A + expect val p3: A?> + expect val p4: A?> + expect val p5: A?> + expect val p6: A?> + expect val p7: A>? + expect val p8: TA2>? + expect val p9: TA2?>? + expect val p10: TA2? + expect fun f1(): A?>> + """.trimIndent() + ) + } }