[Commonizer] Always use parent arguments for type substitution

This commit is contained in:
sebastian.sellmair
2021-09-10 14:34:01 +02:00
committed by Space
parent 5c7ac614ce
commit 35a29acdc7
4 changed files with 43 additions and 3 deletions
@@ -95,6 +95,10 @@ internal fun CirClassOrTypeAliasType.withParentArguments(
if (oldArgument is CirRegularTypeProjection) {
val oldArgumentType = oldArgument.type
if (oldArgumentType is CirTypeParameterType) {
when (val parentArgument = parentArguments[oldArgumentType.index]) {
is CirRegularTypeProjection -> if (parentArgument is CirClassOrTypeAliasType) return@map parentArgument
is CirStarTypeProjection -> return@map parentArgument
}
return@map parentArguments[oldArgumentType.index]
}
}
@@ -105,7 +109,7 @@ internal fun CirClassOrTypeAliasType.withParentArguments(
this -> this
is CirClassType -> newUnderlyingType
is CirTypeAliasType -> newUnderlyingType.withUnderlyingType(
newUnderlyingType.underlyingType.withParentArguments(newArguments, newIsMarkedNullable)
newUnderlyingType.underlyingType.withParentArguments(parentArguments, newIsMarkedNullable)
)
}
}
@@ -113,7 +113,7 @@ internal class ClassOrTypeAliasTypeCommonizer(
/* Only forward substitutions allowed -> Only substitute with any underlying type */
forwardSubstitutionAllowed -> commonId.aliases.filter { candidate ->
types.all { type -> type.isAnyUnderlyingClassifier(candidate) }
types.all { type -> candidate == type.classifierId || type.isAnyUnderlyingClassifier(candidate) }
}
/* Only backward substitutions allowed -> Only substitute with any typealias pointing to this types */
@@ -618,7 +618,7 @@ class HierarchicalOptimisticNumbersTypeCommonizerTest : AbstractInlineSourcesCom
@UnsafeNumber(["a: kotlin.Int", "b: kotlin.Long"])
typealias B = A
@UnsafeNumber(["a: kotlin.Int", "b: kotlin.Long"])
typealias X = A
typealias X = B
""".trimIndent()
)
}
@@ -162,4 +162,40 @@ class HierarchicalTypeAliasCommonizationTest : AbstractInlineSourcesCommonizatio
""".trimIndent()
)
}
fun `test typealias with phantom type`() {
val result = commonize {
outputTarget("(a, b)")
simpleSingleSourceTarget(
"a", """
typealias A<N, M> = Map<N, M>
typealias B<N, Phantom, M> = A<N, M>
typealias X<T> = B<T, String, Long>
fun x(x: X<Int>) = Unit
""".trimIndent()
)
simpleSingleSourceTarget(
"b", """
typealias A<N, M> = Map<N, M>
typealias B<N, Phantom, M> = A<N, M>
typealias X<T> = B<T, String, Long>
typealias Y<T> = X<T>
fun x(x: Y<Int>) = Unit
""".trimIndent()
)
}
result.assertCommonized(
"(a, b)", """
typealias A<N, M> = Map<N, M>
typealias B<N, Phantom, M> = A<N, M>
typealias X<T> = B<T, String, Long>
expect fun x(x: X<Int>)
""".trimIndent()
)
}
}