diff --git a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxAgainstJavaCodegenTestGenerated.java b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxAgainstJavaCodegenTestGenerated.java index 8b03298d54d..b8e90b35bf7 100644 --- a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxAgainstJavaCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxAgainstJavaCodegenTestGenerated.java @@ -1066,6 +1066,34 @@ public class FirBlackBoxAgainstJavaCodegenTestGenerated extends AbstractFirBlack } } + @TestMetadata("compiler/testData/codegen/boxAgainstJava/varargs") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Varargs extends AbstractFirBlackBoxAgainstJavaCodegenTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTestWithCustomIgnoreDirective(this::doTest, TargetBackend.JVM_IR, testDataFilePath, "// IGNORE_BACKEND_FIR: "); + } + + public void testAllFilesPresentInVarargs() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxAgainstJava/varargs"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); + } + + @TestMetadata("varargsOverride.kt") + public void testVarargsOverride() throws Exception { + runTest("compiler/testData/codegen/boxAgainstJava/varargs/varargsOverride.kt"); + } + + @TestMetadata("varargsOverride2.kt") + public void testVarargsOverride2() throws Exception { + runTest("compiler/testData/codegen/boxAgainstJava/varargs/varargsOverride2.kt"); + } + + @TestMetadata("varargsOverride3.kt") + public void testVarargsOverride3() throws Exception { + runTest("compiler/testData/codegen/boxAgainstJava/varargs/varargsOverride3.kt"); + } + } + @TestMetadata("compiler/testData/codegen/boxAgainstJava/visibility") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FunctionReferenceLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FunctionReferenceLowering.kt index b0bc0bbbf4b..4dd8caa22a0 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FunctionReferenceLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FunctionReferenceLowering.kt @@ -401,8 +401,8 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext) body = context.createJvmIrBuilder(symbol, startOffset, endOffset).run { var unboundIndex = 0 irExprBody(irCall(callee).apply { - for ((typeParameter, typeArgument) in typeArgumentsMap) { - putTypeArgument(typeParameter.owner.index, typeArgument) + for (typeParameter in irFunctionReference.symbol.owner.allTypeParameters) { + putTypeArgument(typeParameter.index, typeArgumentsMap[typeParameter.symbol]) } for (parameter in callee.explicitParameters) { diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt index 99acfb35440..21d5d108720 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt @@ -389,7 +389,6 @@ fun extractTypeParameters(klass: IrDeclarationParent): List { val result = mutableListOf() var current: IrDeclarationParent? = klass while (current != null) { -// result += current.typeParameters (current as? IrTypeParametersContainer)?.let { result += it.typeParameters } current = when (current) { diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/IrUtils.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/IrUtils.kt index f1435afa502..2529dc3df0e 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/IrUtils.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/IrUtils.kt @@ -16,10 +16,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl import org.jetbrains.kotlin.ir.expressions.impl.IrConstructorCallImpl import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl import org.jetbrains.kotlin.ir.symbols.* -import org.jetbrains.kotlin.ir.types.IrSimpleType -import org.jetbrains.kotlin.ir.types.IrType -import org.jetbrains.kotlin.ir.types.isAny -import org.jetbrains.kotlin.ir.types.isSubtypeOf +import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.SpecialNames import org.jetbrains.kotlin.utils.DFS @@ -518,9 +515,24 @@ val IrFunction.allTypeParameters: List else typeParameters + fun IrMemberAccessExpression<*>.getTypeSubstitutionMap(irFunction: IrFunction): Map { val typeParameters = irFunction.allTypeParameters - return if (typeParameters.isEmpty()) emptyMap() else typeParameters.withIndex().associate { + val dispatchReceiverTypeArguments = (dispatchReceiver?.type as? IrSimpleType)?.arguments ?: emptyList() + if (typeParameters.isEmpty() && dispatchReceiverTypeArguments.isEmpty()) { + return emptyMap() + } + + val result = mutableMapOf() + if (dispatchReceiverTypeArguments.isNotEmpty()) { + val parentTypeParameters = extractTypeParameters(irFunction.parentClassOrNull!!) + parentTypeParameters.withIndex().forEach { (index, typeParam) -> + dispatchReceiverTypeArguments[index].typeOrNull?.let { + result[typeParam.symbol] = it + } + } + } + return typeParameters.withIndex().associateTo(result) { it.value.symbol to getTypeArgument(it.index)!! } } diff --git a/compiler/testData/codegen/boxAgainstJava/varargs/varargsOverride.kt b/compiler/testData/codegen/boxAgainstJava/varargs/varargsOverride.kt new file mode 100644 index 00000000000..f0bd8bceb3c --- /dev/null +++ b/compiler/testData/codegen/boxAgainstJava/varargs/varargsOverride.kt @@ -0,0 +1,18 @@ +// FILE: A.java + +public abstract class A { + protected abstract String doIt(T... args); + + public String test(T... args) { + return doIt(args); + } +} + +// FILE: 1.kt + +val a: A = + object : A() { + override fun doIt(vararg parameters: Void): String = "OK" + } + +fun box(): String = a.test() diff --git a/compiler/testData/codegen/boxAgainstJava/varargs/varargsOverride2.kt b/compiler/testData/codegen/boxAgainstJava/varargs/varargsOverride2.kt new file mode 100644 index 00000000000..68e8a7e1704 --- /dev/null +++ b/compiler/testData/codegen/boxAgainstJava/varargs/varargsOverride2.kt @@ -0,0 +1,21 @@ +// FILE: A.java + +public abstract class A { + protected abstract String doIt(T... args); + + public String test(S... args) { + return doIt(args); + } +} + +// FILE: 1.kt + +open class Super +class Sub: Super() + +val a: A = + object : A() { + override fun doIt(vararg parameters: Super): String = "OK" + } + +fun box(): String = a.test() diff --git a/compiler/testData/codegen/boxAgainstJava/varargs/varargsOverride3.kt b/compiler/testData/codegen/boxAgainstJava/varargs/varargsOverride3.kt new file mode 100644 index 00000000000..643002804b5 --- /dev/null +++ b/compiler/testData/codegen/boxAgainstJava/varargs/varargsOverride3.kt @@ -0,0 +1,37 @@ +// FILE: A.java + +public abstract class A { + protected abstract String doIt(T... args); + + class B { + public String test(T... args) { + return doIt(args); + } + + public String test2(S... args) { + return doIt(args); + } + + public String test3(U... args) { + return doIt(args); + } + } +} + +// FILE: 1.kt + +open class Super +open class Sub: Super() +class Sub2: Sub() + +val a: A = + object : A() { + override fun doIt(vararg parameters: Super): String = "OK" + } + +fun box(): String { + val b = a.B() + if (b.test() != "OK") return "FAIL1" + if (b.test2() != "OK") return "FAIL2" + return b.test3() +} diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxAgainstJavaCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxAgainstJavaCodegenTestGenerated.java index bb87213aa4c..bf6e05f1343 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxAgainstJavaCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxAgainstJavaCodegenTestGenerated.java @@ -1096,6 +1096,34 @@ public class BlackBoxAgainstJavaCodegenTestGenerated extends AbstractBlackBoxAga } } + @TestMetadata("compiler/testData/codegen/boxAgainstJava/varargs") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Varargs extends AbstractBlackBoxAgainstJavaCodegenTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + public void testAllFilesPresentInVarargs() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxAgainstJava/varargs"), Pattern.compile("^(.+)\\.kt$"), null, true); + } + + @TestMetadata("varargsOverride.kt") + public void testVarargsOverride() throws Exception { + runTest("compiler/testData/codegen/boxAgainstJava/varargs/varargsOverride.kt"); + } + + @TestMetadata("varargsOverride2.kt") + public void testVarargsOverride2() throws Exception { + runTest("compiler/testData/codegen/boxAgainstJava/varargs/varargsOverride2.kt"); + } + + @TestMetadata("varargsOverride3.kt") + public void testVarargsOverride3() throws Exception { + runTest("compiler/testData/codegen/boxAgainstJava/varargs/varargsOverride3.kt"); + } + } + @TestMetadata("compiler/testData/codegen/boxAgainstJava/visibility") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxAgainstJavaCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxAgainstJavaCodegenTestGenerated.java index 29a0d786631..e77d6e67d6a 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxAgainstJavaCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxAgainstJavaCodegenTestGenerated.java @@ -1066,6 +1066,34 @@ public class IrBlackBoxAgainstJavaCodegenTestGenerated extends AbstractIrBlackBo } } + @TestMetadata("compiler/testData/codegen/boxAgainstJava/varargs") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Varargs extends AbstractIrBlackBoxAgainstJavaCodegenTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM_IR, testDataFilePath); + } + + public void testAllFilesPresentInVarargs() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxAgainstJava/varargs"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); + } + + @TestMetadata("varargsOverride.kt") + public void testVarargsOverride() throws Exception { + runTest("compiler/testData/codegen/boxAgainstJava/varargs/varargsOverride.kt"); + } + + @TestMetadata("varargsOverride2.kt") + public void testVarargsOverride2() throws Exception { + runTest("compiler/testData/codegen/boxAgainstJava/varargs/varargsOverride2.kt"); + } + + @TestMetadata("varargsOverride3.kt") + public void testVarargsOverride3() throws Exception { + runTest("compiler/testData/codegen/boxAgainstJava/varargs/varargsOverride3.kt"); + } + } + @TestMetadata("compiler/testData/codegen/boxAgainstJava/visibility") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)