From 595cab2aaf163cc37d932d15e00735d31d9e3f3d Mon Sep 17 00:00:00 2001 From: "sebastian.sellmair" Date: Fri, 10 Sep 2021 11:00:24 +0200 Subject: [PATCH] [Commonizer] ClassOrTypeAliasTypeCommonizer: Implement proper type argument substitution ^KT-47574 Verification Pending --- .../kotlin/commonizer/cir/CirType.kt | 14 ++++--- .../core/ClassOrTypeAliasTypeCommonizer.kt | 38 ++++++++++++++----- .../HierarchicalTypeAliasCommonizationTest.kt | 2 +- 3 files changed, 38 insertions(+), 16 deletions(-) diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/cir/CirType.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/cir/CirType.kt index 447f76100a7..22ee412b768 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/cir/CirType.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/cir/CirType.kt @@ -100,6 +100,7 @@ abstract class CirClassType : CirClassOrTypeAliasType(), CirHasVisibility { } override fun withArguments(arguments: List): CirClassOrTypeAliasType { + if (arguments == this.arguments) return this return createInterned( classId = classifierId, outerType = outerType, @@ -162,12 +163,13 @@ abstract class CirTypeAliasType : CirClassOrTypeAliasType() { } override fun withArguments(arguments: List): CirClassOrTypeAliasType { - return createInterned( - typeAliasId = classifierId, - underlyingType = underlyingType, - arguments = arguments, - isMarkedNullable = isMarkedNullable - ) + if (this.arguments == arguments) return this + return copyInterned(arguments = arguments) + } + + fun withUnderlyingType(underlyingType: CirClassOrTypeAliasType): CirClassOrTypeAliasType { + if (this.underlyingType == underlyingType) return this + return copyInterned(underlyingType = underlyingType) } companion object { 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 f6db63af985..cfa32781fe8 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/ClassOrTypeAliasTypeCommonizer.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/ClassOrTypeAliasTypeCommonizer.kt @@ -68,8 +68,8 @@ internal class ClassOrTypeAliasTypeCommonizer( val commonizedClassifier = classifiers.commonizedNodes.classNode(classifierId)?.commonDeclaration?.invoke() ?: classifiers.commonizedNodes.typeAliasNode(classifierId)?.commonDeclaration?.invoke() - when (commonizedClassifier) { - is CirClass -> return CirClassType.createInterned( + return when (commonizedClassifier) { + is CirClass -> CirClassType.createInterned( classId = classifierId, outerType = outerType, arguments = arguments, @@ -77,19 +77,15 @@ internal class ClassOrTypeAliasTypeCommonizer( isMarkedNullable = isMarkedNullable ) - is CirTypeAlias -> return CirTypeAliasType.createInterned( + is CirTypeAlias -> CirTypeAliasType.createInterned( typeAliasId = classifierId, arguments = arguments, isMarkedNullable = isMarkedNullable, - underlyingType = computeSuitableUnderlyingType( - classifiers, typeCommonizer, commonizedClassifier.underlyingType - )?.makeNullableIfNecessary(isMarkedNullable) ?: return null + underlyingType = commonizedClassifier.underlyingType.withParentArguments(arguments, isMarkedNullable) ) - else -> Unit + else -> null } - - return null } private fun selectClassifierId(types: List): CirEntityId? { @@ -105,6 +101,30 @@ internal class ClassOrTypeAliasTypeCommonizer( } } +private fun CirClassOrTypeAliasType.withParentArguments( + parentArguments: List, parentIsMarkedNullable: Boolean +): CirClassOrTypeAliasType { + val newIsMarkedNullable = isMarkedNullable || parentIsMarkedNullable + + val newArguments = arguments.map { oldArgument -> + if (oldArgument is CirRegularTypeProjection) { + val oldArgumentType = oldArgument.type + if (oldArgumentType is CirTypeParameterType) { + return@map parentArguments[oldArgumentType.index] + } + } + oldArgument + } + + return when (val newUnderlyingType = makeNullableIfNecessary(newIsMarkedNullable).withArguments(newArguments)) { + this -> this + is CirClassType -> newUnderlyingType + is CirTypeAliasType -> newUnderlyingType.withUnderlyingType( + newUnderlyingType.underlyingType.withParentArguments(newArguments, newIsMarkedNullable) + ) + } +} + internal tailrec fun CirClassOrTypeAliasType.expandedType(): CirClassType = when (this) { is CirClassType -> this is CirTypeAliasType -> this.underlyingType.expandedType() diff --git a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/hierarchical/HierarchicalTypeAliasCommonizationTest.kt b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/hierarchical/HierarchicalTypeAliasCommonizationTest.kt index ab1e6efb971..a33c917543f 100644 --- a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/hierarchical/HierarchicalTypeAliasCommonizationTest.kt +++ b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/hierarchical/HierarchicalTypeAliasCommonizationTest.kt @@ -130,7 +130,7 @@ class HierarchicalTypeAliasCommonizationTest : AbstractInlineSourcesCommonizatio ) } - fun `KT-47574 - test long typealias chain`() { + fun `test long typealias chain`() { val result = commonize { outputTarget("(a, b)")