From 3b604cfa7f521943511b059b15e67ecf06395e47 Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Mon, 30 Nov 2020 11:54:56 +0300 Subject: [PATCH] JVM_IR KT-32701 generate multiple big arity invokes, report error later --- .../lower/FunctionNVarargBridgeLowering.kt | 34 ++++++++----------- .../multipleBigArityFunsImplemented.kt | 20 +++++++++++ .../multipleBigArityFunsImplemented.txt | 10 ++++++ .../multipleBigArityFunsImplemented_ir.kt | 20 +++++++++++ .../multipleBigArityFunsImplemented_ir.txt | 10 ++++++ ...gnosticsTestWithJvmIrBackendGenerated.java | 5 +++ ...nosticsTestWithOldJvmBackendGenerated.java | 5 +++ 7 files changed, 85 insertions(+), 19 deletions(-) create mode 100644 compiler/testData/diagnostics/testsWithJvmBackend/multipleBigArityFunsImplemented.kt create mode 100644 compiler/testData/diagnostics/testsWithJvmBackend/multipleBigArityFunsImplemented.txt create mode 100644 compiler/testData/diagnostics/testsWithJvmBackend/multipleBigArityFunsImplemented_ir.kt create mode 100644 compiler/testData/diagnostics/testsWithJvmBackend/multipleBigArityFunsImplemented_ir.txt diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FunctionNVarargBridgeLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FunctionNVarargBridgeLowering.kt index 2ebf83b546f..d03fdd42e89 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FunctionNVarargBridgeLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FunctionNVarargBridgeLowering.kt @@ -76,26 +76,22 @@ private class FunctionNVarargBridgeLowering(val context: JvmBackendContext) : return super.visitClassNew(declaration) declaration.transformChildrenVoid(this) - // Note that we allow classes with multiple function supertypes, so long as only one - // of them has more than 22 arguments. - // TODO: Add a proper diagnostic message in the frontend - assert(bigArityFunctionSuperTypes.size == 1) { - "Class has multiple big-arity function super types: ${bigArityFunctionSuperTypes.joinToString { it.render() }}" - } + // Note that we allow classes with multiple function supertypes, so long as only one of them has more than 22 arguments. + // Code below will generate one 'invoke' for each function supertype, + // which will cause conflicting inherited JVM signatures error diagnostics in case of multiple big arity function supertypes. + for (superType in bigArityFunctionSuperTypes) { + declaration.superTypes -= superType + declaration.superTypes += context.ir.symbols.functionN.typeWith( + (superType.arguments.last() as IrTypeProjection).type + ) - // Fix super class - val superType = bigArityFunctionSuperTypes.single() - declaration.superTypes -= superType - declaration.superTypes += context.ir.symbols.functionN.typeWith( - (superType.arguments.last() as IrTypeProjection).type - ) - - // Add vararg invoke bridge - val invokeFunction = declaration.functions.single { - it.name.asString() == "invoke" && it.valueParameters.size == superType.arguments.size - if (it.isSuspend) 0 else 1 + // Add vararg invoke bridge + val invokeFunction = declaration.functions.single { + it.name.asString() == "invoke" && it.valueParameters.size == superType.arguments.size - if (it.isSuspend) 0 else 1 + } + invokeFunction.overriddenSymbols = emptyList() + declaration.addBridge(invokeFunction, functionNInvokeFun.owner) } - invokeFunction.overriddenSymbols = emptyList() - declaration.addBridge(invokeFunction, functionNInvokeFun.owner) return declaration } @@ -123,7 +119,7 @@ private class FunctionNVarargBridgeLowering(val context: JvmBackendContext) : irInt(argumentCount) ), irCall(context.irBuiltIns.illegalArgumentExceptionSymbol).apply { - putValueArgument(0, irString("Expected ${argumentCount} arguments")) + putValueArgument(0, irString("Expected $argumentCount arguments")) } ) diff --git a/compiler/testData/diagnostics/testsWithJvmBackend/multipleBigArityFunsImplemented.kt b/compiler/testData/diagnostics/testsWithJvmBackend/multipleBigArityFunsImplemented.kt new file mode 100644 index 00000000000..953510b6bc4 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithJvmBackend/multipleBigArityFunsImplemented.kt @@ -0,0 +1,20 @@ +// TARGET_BACKEND: JVM_OLD +class Fun : + (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, + Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int) -> Int, + (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, + Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int) -> Int +{ + override fun invoke( + p00: Int, p01: Int, p02: Int, p03: Int, p04: Int, p05: Int, p06: Int, p07: Int, p08: Int, p09: Int, + p10: Int, p11: Int, p12: Int, p13: Int, p14: Int, p15: Int, p16: Int, p17: Int, p18: Int, p19: Int, + p20: Int, p21: Int, p22: Int, p23: Int, p24: Int, p25: Int, p26: Int, p27: Int, p28: Int, p29: Int + ): Int = 330 + + override fun invoke( + p00: Int, p01: Int, p02: Int, p03: Int, p04: Int, p05: Int, p06: Int, p07: Int, p08: Int, p09: Int, + p10: Int, p11: Int, p12: Int, p13: Int, p14: Int, p15: Int, p16: Int, p17: Int, p18: Int, p19: Int, + p20: Int, p21: Int, p22: Int, p23: Int, p24: Int, p25: Int, p26: Int, p27: Int, p28: Int, p29: Int, + p30: Int, p31: Int, p32: Int + ): Int = 333 +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithJvmBackend/multipleBigArityFunsImplemented.txt b/compiler/testData/diagnostics/testsWithJvmBackend/multipleBigArityFunsImplemented.txt new file mode 100644 index 00000000000..6d94b0386fb --- /dev/null +++ b/compiler/testData/diagnostics/testsWithJvmBackend/multipleBigArityFunsImplemented.txt @@ -0,0 +1,10 @@ +package + +public final class Fun : (kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int) -> kotlin.Int, (kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int) -> kotlin.Int { + public constructor Fun() + public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ fun invoke(/*0*/ p00: kotlin.Int, /*1*/ p01: kotlin.Int, /*2*/ p02: kotlin.Int, /*3*/ p03: kotlin.Int, /*4*/ p04: kotlin.Int, /*5*/ p05: kotlin.Int, /*6*/ p06: kotlin.Int, /*7*/ p07: kotlin.Int, /*8*/ p08: kotlin.Int, /*9*/ p09: kotlin.Int, /*10*/ p10: kotlin.Int, /*11*/ p11: kotlin.Int, /*12*/ p12: kotlin.Int, /*13*/ p13: kotlin.Int, /*14*/ p14: kotlin.Int, /*15*/ p15: kotlin.Int, /*16*/ p16: kotlin.Int, /*17*/ p17: kotlin.Int, /*18*/ p18: kotlin.Int, /*19*/ p19: kotlin.Int, /*20*/ p20: kotlin.Int, /*21*/ p21: kotlin.Int, /*22*/ p22: kotlin.Int, /*23*/ p23: kotlin.Int, /*24*/ p24: kotlin.Int, /*25*/ p25: kotlin.Int, /*26*/ p26: kotlin.Int, /*27*/ p27: kotlin.Int, /*28*/ p28: kotlin.Int, /*29*/ p29: kotlin.Int): kotlin.Int + public open override /*1*/ fun invoke(/*0*/ p00: kotlin.Int, /*1*/ p01: kotlin.Int, /*2*/ p02: kotlin.Int, /*3*/ p03: kotlin.Int, /*4*/ p04: kotlin.Int, /*5*/ p05: kotlin.Int, /*6*/ p06: kotlin.Int, /*7*/ p07: kotlin.Int, /*8*/ p08: kotlin.Int, /*9*/ p09: kotlin.Int, /*10*/ p10: kotlin.Int, /*11*/ p11: kotlin.Int, /*12*/ p12: kotlin.Int, /*13*/ p13: kotlin.Int, /*14*/ p14: kotlin.Int, /*15*/ p15: kotlin.Int, /*16*/ p16: kotlin.Int, /*17*/ p17: kotlin.Int, /*18*/ p18: kotlin.Int, /*19*/ p19: kotlin.Int, /*20*/ p20: kotlin.Int, /*21*/ p21: kotlin.Int, /*22*/ p22: kotlin.Int, /*23*/ p23: kotlin.Int, /*24*/ p24: kotlin.Int, /*25*/ p25: kotlin.Int, /*26*/ p26: kotlin.Int, /*27*/ p27: kotlin.Int, /*28*/ p28: kotlin.Int, /*29*/ p29: kotlin.Int, /*30*/ p30: kotlin.Int, /*31*/ p31: kotlin.Int, /*32*/ p32: kotlin.Int): kotlin.Int + public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/testsWithJvmBackend/multipleBigArityFunsImplemented_ir.kt b/compiler/testData/diagnostics/testsWithJvmBackend/multipleBigArityFunsImplemented_ir.kt new file mode 100644 index 00000000000..e5739aed82b --- /dev/null +++ b/compiler/testData/diagnostics/testsWithJvmBackend/multipleBigArityFunsImplemented_ir.kt @@ -0,0 +1,20 @@ +// TARGET_BACKEND: JVM_IR +class Fun : + (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, + Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int) -> Int, + (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, + Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int) -> Int +{ + override fun invoke( + p00: Int, p01: Int, p02: Int, p03: Int, p04: Int, p05: Int, p06: Int, p07: Int, p08: Int, p09: Int, + p10: Int, p11: Int, p12: Int, p13: Int, p14: Int, p15: Int, p16: Int, p17: Int, p18: Int, p19: Int, + p20: Int, p21: Int, p22: Int, p23: Int, p24: Int, p25: Int, p26: Int, p27: Int, p28: Int, p29: Int + ): Int = 330 + + override fun invoke( + p00: Int, p01: Int, p02: Int, p03: Int, p04: Int, p05: Int, p06: Int, p07: Int, p08: Int, p09: Int, + p10: Int, p11: Int, p12: Int, p13: Int, p14: Int, p15: Int, p16: Int, p17: Int, p18: Int, p19: Int, + p20: Int, p21: Int, p22: Int, p23: Int, p24: Int, p25: Int, p26: Int, p27: Int, p28: Int, p29: Int, + p30: Int, p31: Int, p32: Int + ): Int = 333 +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithJvmBackend/multipleBigArityFunsImplemented_ir.txt b/compiler/testData/diagnostics/testsWithJvmBackend/multipleBigArityFunsImplemented_ir.txt new file mode 100644 index 00000000000..6d94b0386fb --- /dev/null +++ b/compiler/testData/diagnostics/testsWithJvmBackend/multipleBigArityFunsImplemented_ir.txt @@ -0,0 +1,10 @@ +package + +public final class Fun : (kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int) -> kotlin.Int, (kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int, kotlin.Int) -> kotlin.Int { + public constructor Fun() + public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ fun invoke(/*0*/ p00: kotlin.Int, /*1*/ p01: kotlin.Int, /*2*/ p02: kotlin.Int, /*3*/ p03: kotlin.Int, /*4*/ p04: kotlin.Int, /*5*/ p05: kotlin.Int, /*6*/ p06: kotlin.Int, /*7*/ p07: kotlin.Int, /*8*/ p08: kotlin.Int, /*9*/ p09: kotlin.Int, /*10*/ p10: kotlin.Int, /*11*/ p11: kotlin.Int, /*12*/ p12: kotlin.Int, /*13*/ p13: kotlin.Int, /*14*/ p14: kotlin.Int, /*15*/ p15: kotlin.Int, /*16*/ p16: kotlin.Int, /*17*/ p17: kotlin.Int, /*18*/ p18: kotlin.Int, /*19*/ p19: kotlin.Int, /*20*/ p20: kotlin.Int, /*21*/ p21: kotlin.Int, /*22*/ p22: kotlin.Int, /*23*/ p23: kotlin.Int, /*24*/ p24: kotlin.Int, /*25*/ p25: kotlin.Int, /*26*/ p26: kotlin.Int, /*27*/ p27: kotlin.Int, /*28*/ p28: kotlin.Int, /*29*/ p29: kotlin.Int): kotlin.Int + public open override /*1*/ fun invoke(/*0*/ p00: kotlin.Int, /*1*/ p01: kotlin.Int, /*2*/ p02: kotlin.Int, /*3*/ p03: kotlin.Int, /*4*/ p04: kotlin.Int, /*5*/ p05: kotlin.Int, /*6*/ p06: kotlin.Int, /*7*/ p07: kotlin.Int, /*8*/ p08: kotlin.Int, /*9*/ p09: kotlin.Int, /*10*/ p10: kotlin.Int, /*11*/ p11: kotlin.Int, /*12*/ p12: kotlin.Int, /*13*/ p13: kotlin.Int, /*14*/ p14: kotlin.Int, /*15*/ p15: kotlin.Int, /*16*/ p16: kotlin.Int, /*17*/ p17: kotlin.Int, /*18*/ p18: kotlin.Int, /*19*/ p19: kotlin.Int, /*20*/ p20: kotlin.Int, /*21*/ p21: kotlin.Int, /*22*/ p22: kotlin.Int, /*23*/ p23: kotlin.Int, /*24*/ p24: kotlin.Int, /*25*/ p25: kotlin.Int, /*26*/ p26: kotlin.Int, /*27*/ p27: kotlin.Int, /*28*/ p28: kotlin.Int, /*29*/ p29: kotlin.Int, /*30*/ p30: kotlin.Int, /*31*/ p31: kotlin.Int, /*32*/ p32: kotlin.Int): kotlin.Int + public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/tests-gen/org/jetbrains/kotlin/checkers/DiagnosticsTestWithJvmIrBackendGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/checkers/DiagnosticsTestWithJvmIrBackendGenerated.java index 0e71ce26617..a2f5b30b304 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/checkers/DiagnosticsTestWithJvmIrBackendGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/checkers/DiagnosticsTestWithJvmIrBackendGenerated.java @@ -39,6 +39,11 @@ public class DiagnosticsTestWithJvmIrBackendGenerated extends AbstractDiagnostic runTest("compiler/testData/diagnostics/testsWithJvmBackend/inlineCycle_ir.kt"); } + @TestMetadata("multipleBigArityFunsImplemented_ir.kt") + public void testMultipleBigArityFunsImplemented_ir() throws Exception { + runTest("compiler/testData/diagnostics/testsWithJvmBackend/multipleBigArityFunsImplemented_ir.kt"); + } + @TestMetadata("suspendInlineCycle_ir.kt") public void testSuspendInlineCycle_ir() throws Exception { runTest("compiler/testData/diagnostics/testsWithJvmBackend/suspendInlineCycle_ir.kt"); diff --git a/compiler/tests-gen/org/jetbrains/kotlin/checkers/DiagnosticsTestWithOldJvmBackendGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/checkers/DiagnosticsTestWithOldJvmBackendGenerated.java index 66044c1c3b7..6b90997e0e1 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/checkers/DiagnosticsTestWithOldJvmBackendGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/checkers/DiagnosticsTestWithOldJvmBackendGenerated.java @@ -39,6 +39,11 @@ public class DiagnosticsTestWithOldJvmBackendGenerated extends AbstractDiagnosti runTest("compiler/testData/diagnostics/testsWithJvmBackend/inlineCycle.kt"); } + @TestMetadata("multipleBigArityFunsImplemented.kt") + public void testMultipleBigArityFunsImplemented() throws Exception { + runTest("compiler/testData/diagnostics/testsWithJvmBackend/multipleBigArityFunsImplemented.kt"); + } + @TestMetadata("suspendInlineCycle.kt") public void testSuspendInlineCycle() throws Exception { runTest("compiler/testData/diagnostics/testsWithJvmBackend/suspendInlineCycle.kt");