[IR] Fix copying of default argument from expect to actual with type parameter
^KT-45866 fixed
This commit is contained in:
committed by
TeamCityServer
parent
d870876822
commit
b82c9225c8
+6
@@ -25182,6 +25182,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
public void testTypeAlias() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/multiplatform/defaultArguments/typeAlias.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("withTypeParameter.kt")
|
||||
public void testWithTypeParameter() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/multiplatform/defaultArguments/withTypeParameter.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
+20
-2
@@ -26,6 +26,8 @@ import org.jetbrains.kotlin.resolve.multiplatform.ExpectedActualResolver
|
||||
// `doRemove` means should expect-declaration be removed from IR
|
||||
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
||||
class ExpectDeclarationRemover(val symbolTable: ReferenceSymbolTable, private val doRemove: Boolean) : IrElementVisitorVoid {
|
||||
private val typeParameterSubstitutionMap = mutableMapOf<Pair<IrFunction, IrFunction>, Map<IrTypeParameter, IrTypeParameter>>()
|
||||
|
||||
override fun visitElement(element: IrElement) {
|
||||
element.acceptChildrenVoid(this)
|
||||
}
|
||||
@@ -97,13 +99,29 @@ class ExpectDeclarationRemover(val symbolTable: ReferenceSymbolTable, private va
|
||||
// the `actual fun` or `actual constructor` for this may be in a different module.
|
||||
// Nothing we can do with those.
|
||||
// TODO they may not actually have the defaults though -- may be a frontend bug.
|
||||
val expectParameter = function.findExpectForActual()?.valueParameters?.get(index) ?: return
|
||||
val expectFunction = function.findExpectForActual()
|
||||
val expectParameter = expectFunction?.valueParameters?.get(index) ?: return
|
||||
|
||||
val defaultValue = expectParameter.defaultValue ?: return
|
||||
|
||||
val expectToActual = expectFunction to function
|
||||
if (expectToActual !in typeParameterSubstitutionMap) {
|
||||
val functionTypeParameters = collectTypeParameters(function)
|
||||
val expectFunctionTypeParameters = collectTypeParameters(expectFunction)
|
||||
|
||||
expectFunctionTypeParameters.zip(functionTypeParameters).let { typeParametersMapping ->
|
||||
typeParameterSubstitutionMap[expectToActual] = typeParametersMapping.toMap()
|
||||
}
|
||||
}
|
||||
|
||||
defaultValue.let { originalDefault ->
|
||||
declaration.defaultValue = declaration.factory.createExpressionBody(originalDefault.startOffset, originalDefault.endOffset) {
|
||||
expression = originalDefault.expression.deepCopyWithSymbols(function).remapExpectValueSymbols()
|
||||
expression = originalDefault.expression
|
||||
.deepCopyWithSymbols(function)
|
||||
.remapExpectValueSymbols()
|
||||
.apply {
|
||||
remapTypes(IrTypeParameterRemapper(typeParameterSubstitutionMap.getValue(expectToActual)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-13
@@ -345,19 +345,6 @@ class InlineClassLowering(val context: CommonBackendContext) {
|
||||
}
|
||||
}
|
||||
|
||||
private fun collectTypeParameters(declaration: IrTypeParametersContainer): List<IrTypeParameter> {
|
||||
val result = mutableListOf<IrTypeParameter>()
|
||||
|
||||
fun collectImpl(declaration: IrDeclaration) {
|
||||
if (declaration is IrTypeParametersContainer) result.addAll(declaration.typeParameters)
|
||||
if (declaration is IrClass && declaration.isInner) collectImpl(declaration.parent as IrDeclaration)
|
||||
}
|
||||
|
||||
collectImpl(declaration)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
private fun createStaticBodilessMethod(function: IrFunction): IrSimpleFunction =
|
||||
context.irFactory.createStaticFunctionWithReceivers(
|
||||
function.parent,
|
||||
|
||||
@@ -602,4 +602,20 @@ internal fun <T> IrConst<T>.shallowCopy() = IrConstImpl(
|
||||
type,
|
||||
kind,
|
||||
value
|
||||
)
|
||||
)
|
||||
|
||||
fun collectTypeParameters(declaration: IrTypeParametersContainer): List<IrTypeParameter> {
|
||||
val result = mutableListOf<IrTypeParameter>()
|
||||
|
||||
fun collectImpl(declaration: IrDeclaration) {
|
||||
if (declaration is IrTypeParametersContainer) {
|
||||
result.addAll(declaration.typeParameters)
|
||||
declaration.parentClassOrNull?.let { collectImpl(it) }
|
||||
}
|
||||
if (declaration is IrClass && declaration.isInner) collectImpl(declaration.parent as IrDeclaration)
|
||||
}
|
||||
|
||||
collectImpl(declaration)
|
||||
|
||||
return result
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
// !LANGUAGE: +MultiPlatformProjects
|
||||
// MODULE: lib
|
||||
// FILE: common.kt
|
||||
|
||||
expect fun <T> topLevel(a: T, b: (T) -> Int = { 1 }): String
|
||||
|
||||
actual fun <T> topLevel(a: T, b: (T) -> Int): String = b(a).toString()
|
||||
|
||||
expect class Foo() {
|
||||
fun <T> member(a: T, b: (T) -> Int = { 2 }): String
|
||||
}
|
||||
|
||||
actual class Foo actual constructor() {
|
||||
actual fun <T> member(a: T, b: (T) -> Int): String = b(a).toString()
|
||||
}
|
||||
|
||||
expect class Bar<T>() {
|
||||
fun member(a: T, b: (T) -> Int = { 3 }): String
|
||||
}
|
||||
|
||||
actual class Bar<T> actual constructor() {
|
||||
actual fun member(a: T, b: (T) -> Int): String = b(a).toString()
|
||||
}
|
||||
|
||||
expect class A<T> {
|
||||
inner class B<N> {
|
||||
fun <H> foo(t: T, n: N, h: H, a: (T, N, H) -> Int = { _, _, _ -> 4 }): String
|
||||
}
|
||||
}
|
||||
|
||||
actual class A<T> {
|
||||
actual inner class B<N> {
|
||||
actual fun <H> foo(t: T, n: N, h: H, a: (T, N, H) -> Int) = a(t, n, h).toString()
|
||||
}
|
||||
}
|
||||
|
||||
// MODULE: main(lib)
|
||||
// FILE: main.kt
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
fun box(): String {
|
||||
assertEquals("1", topLevel("OK"))
|
||||
assertEquals("73", topLevel("OK") { 73 })
|
||||
|
||||
val foo = Foo()
|
||||
assertEquals("2", foo.member("OK"))
|
||||
assertEquals("42", foo.member("OK") { 42 })
|
||||
|
||||
val bar = Bar<String>()
|
||||
assertEquals("3", bar.member("OK"))
|
||||
assertEquals("37", bar.member("OK") { 37 })
|
||||
|
||||
val b = A<Int>().B<Double>()
|
||||
assertEquals("4", b.foo<Int>(1, 2.0, 3))
|
||||
assertEquals("6", b.foo<Int>(1, 2.0, 3) { t, n, h -> t + n.toInt() + h })
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+6
@@ -25164,6 +25164,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
public void testTypeAlias() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/multiplatform/defaultArguments/typeAlias.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("withTypeParameter.kt")
|
||||
public void testWithTypeParameter() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/multiplatform/defaultArguments/withTypeParameter.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
+6
@@ -25182,6 +25182,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
public void testTypeAlias() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/multiplatform/defaultArguments/typeAlias.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("withTypeParameter.kt")
|
||||
public void testWithTypeParameter() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/multiplatform/defaultArguments/withTypeParameter.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
+5
@@ -21301,6 +21301,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
public void testTypeAlias() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/multiplatform/defaultArguments/typeAlias.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("withTypeParameter.kt")
|
||||
public void testWithTypeParameter() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/multiplatform/defaultArguments/withTypeParameter.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/multiplatform/exhaustiveness")
|
||||
|
||||
js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java
Generated
+5
@@ -16745,6 +16745,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
|
||||
public void testTypeAlias() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/multiplatform/defaultArguments/typeAlias.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("withTypeParameter.kt")
|
||||
public void testWithTypeParameter() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/multiplatform/defaultArguments/withTypeParameter.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/multiplatform/exhaustiveness")
|
||||
|
||||
Generated
+5
@@ -16166,6 +16166,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
||||
public void testTypeAlias() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/multiplatform/defaultArguments/typeAlias.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("withTypeParameter.kt")
|
||||
public void testWithTypeParameter() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/multiplatform/defaultArguments/withTypeParameter.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/multiplatform/exhaustiveness")
|
||||
|
||||
Generated
+5
@@ -16231,6 +16231,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
public void testTypeAlias() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/multiplatform/defaultArguments/typeAlias.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("withTypeParameter.kt")
|
||||
public void testWithTypeParameter() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/multiplatform/defaultArguments/withTypeParameter.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/multiplatform/exhaustiveness")
|
||||
|
||||
js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java
Generated
+5
@@ -9977,6 +9977,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
|
||||
public void testTypeAlias() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/multiplatform/defaultArguments/typeAlias.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("withTypeParameter.kt")
|
||||
public void testWithTypeParameter() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/multiplatform/defaultArguments/withTypeParameter.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/multiplatform/exhaustiveness")
|
||||
|
||||
Reference in New Issue
Block a user