diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java index 92a9be65e47..18729aedee5 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java @@ -41561,6 +41561,24 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT public void testSurrogatePair() throws Exception { runTest("compiler/testData/codegen/box/strings/surrogatePair.kt"); } + + @Test + @TestMetadata("twoArgumentNullableStringOperatorPlus.kt") + public void testTwoArgumentNullableStringOperatorPlus() throws Exception { + runTest("compiler/testData/codegen/box/strings/twoArgumentNullableStringOperatorPlus.kt"); + } + + @Test + @TestMetadata("twoArgumentNullableStringPlus.kt") + public void testTwoArgumentNullableStringPlus() throws Exception { + runTest("compiler/testData/codegen/box/strings/twoArgumentNullableStringPlus.kt"); + } + + @Test + @TestMetadata("twoArgumentStringTemplate.kt") + public void testTwoArgumentStringTemplate() throws Exception { + runTest("compiler/testData/codegen/box/strings/twoArgumentStringTemplate.kt"); + } } @Nested diff --git a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/JvmStringConcatenationLowering.kt b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/JvmStringConcatenationLowering.kt index 7e39e25289c..312e08d0a62 100644 --- a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/JvmStringConcatenationLowering.kt +++ b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/JvmStringConcatenationLowering.kt @@ -147,13 +147,6 @@ private class JvmStringConcatenationLowering(val context: JvmBackendContext) : F arguments.size == 1 -> lowerInlineClassArgument(arguments[0]) ?: callToString(arguments[0].unwrapImplicitNotNull()) - arguments.size == 2 && arguments[0].type.isStringClassType() -> - irCall(backendContext.ir.symbols.intrinsicStringPlus).apply { - putValueArgument(0, lowerInlineClassArgument(arguments[0]) ?: arguments[0].unwrapImplicitNotNull()) - // Unwrapping IMPLICIT_NOTNULL is not strictly necessary on 2nd argument (parameter type is `Any?`) - putValueArgument(1, lowerInlineClassArgument(arguments[1]) ?: arguments[1]) - } - arguments.size < MAX_STRING_CONCAT_DEPTH -> { irCall(toStringFunction).apply { dispatchReceiver = appendWindow(arguments, irCall(constructor)) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmSymbols.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmSymbols.kt index 5ccdf883668..b3f8c2a58d2 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmSymbols.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmSymbols.kt @@ -177,9 +177,6 @@ class JvmSymbols( override val throwKotlinNothingValueException: IrSimpleFunctionSymbol = intrinsicsClass.functions.single { it.owner.name.asString() == "throwKotlinNothingValueException" } - val intrinsicStringPlus: IrFunctionSymbol = - intrinsicsClass.functions.single { it.owner.name.asString() == "stringPlus" } - val intrinsicsKotlinClass: IrClassSymbol = (intrinsicsClass.owner.declarations.single { it is IrClass && it.name.asString() == "Kotlin" } as IrClass).symbol diff --git a/compiler/testData/codegen/box/strings/twoArgumentNullableStringOperatorPlus.kt b/compiler/testData/codegen/box/strings/twoArgumentNullableStringOperatorPlus.kt new file mode 100644 index 00000000000..6c4f3c9c9df --- /dev/null +++ b/compiler/testData/codegen/box/strings/twoArgumentNullableStringOperatorPlus.kt @@ -0,0 +1,17 @@ +fun stringPlus(x: String?, y: Any?) = x + y + +fun box(): String { + val t1 = stringPlus("a", "b") + if (t1 != "ab") return "Failed: t1=$t1" + + val t2 = stringPlus("a", null) + if (t2 != "anull") return "Failed: t2=$t2" + + val t3 = stringPlus(null, "b") + if (t3 != "nullb") return "Failed: t3=$t3" + + val t4 = stringPlus(null, null) + if (t4 != "nullnull") return "Failed: t4=$t4" + + return "OK" +} diff --git a/compiler/testData/codegen/box/strings/twoArgumentNullableStringPlus.kt b/compiler/testData/codegen/box/strings/twoArgumentNullableStringPlus.kt new file mode 100644 index 00000000000..45e5bc8e8c6 --- /dev/null +++ b/compiler/testData/codegen/box/strings/twoArgumentNullableStringPlus.kt @@ -0,0 +1,17 @@ +fun stringPlus(x: String?, y: Any?) = x.plus(y) + +fun box(): String { + val t1 = stringPlus("a", "b") + if (t1 != "ab") return "Failed: t1=$t1" + + val t2 = stringPlus("a", null) + if (t2 != "anull") return "Failed: t2=$t2" + + val t3 = stringPlus(null, "b") + if (t3 != "nullb") return "Failed: t3=$t3" + + val t4 = stringPlus(null, null) + if (t4 != "nullnull") return "Failed: t4=$t4" + + return "OK" +} diff --git a/compiler/testData/codegen/box/strings/twoArgumentStringTemplate.kt b/compiler/testData/codegen/box/strings/twoArgumentStringTemplate.kt new file mode 100644 index 00000000000..c5e7e31983c --- /dev/null +++ b/compiler/testData/codegen/box/strings/twoArgumentStringTemplate.kt @@ -0,0 +1,17 @@ +fun stringPlus(x: String?, y: Any?) = "$x$y" + +fun box(): String { + val t1 = stringPlus("a", "b") + if (t1 != "ab") return "Failed: t1=$t1" + + val t2 = stringPlus("a", null) + if (t2 != "anull") return "Failed: t2=$t2" + + val t3 = stringPlus(null, "b") + if (t3 != "nullb") return "Failed: t3=$t3" + + val t4 = stringPlus(null, null) + if (t4 != "nullnull") return "Failed: t4=$t4" + + return "OK" +} diff --git a/compiler/testData/codegen/bytecodeText/boxingOptimization/maxMinByOrNull.kt b/compiler/testData/codegen/bytecodeText/boxingOptimization/maxMinByOrNull.kt index 99e795f0d0e..c261b496b91 100644 --- a/compiler/testData/codegen/bytecodeText/boxingOptimization/maxMinByOrNull.kt +++ b/compiler/testData/codegen/bytecodeText/boxingOptimization/maxMinByOrNull.kt @@ -33,19 +33,8 @@ fun box(): String { // 1 IFGE // 1 IFLE -// JVM_TEMPLATES -// -- no boxing but lots of StringBuilder calls // 0 valueOf // 0 Intrinsics.stringPlus // 4 StringBuilder. // 8 StringBuilder.append // 4 StringBuilder.toString - -// JVM_IR_TEMPLATES -// -- perform boxing and call Intrinsics.stringPlus instead -// -- of having inlined string builder allocation, appends, and toString -// 4 valueOf -// 4 Intrinsics.stringPlus -// 0 StringBuilder. -// 0 StringBuilder.append -// 0 StringBuilder.toString diff --git a/compiler/testData/codegen/bytecodeText/stringOperations/nullableStringPlus.kt b/compiler/testData/codegen/bytecodeText/stringOperations/nullableStringPlus.kt index ef37d600c13..b3c8226aee9 100644 --- a/compiler/testData/codegen/bytecodeText/stringOperations/nullableStringPlus.kt +++ b/compiler/testData/codegen/bytecodeText/stringOperations/nullableStringPlus.kt @@ -1,3 +1,9 @@ fun foo(x: String?, y: Any?) = x + y +// JVM_TEMPLATES // 1 stringPlus + +// JVM_IR_TEMPLATES +// 1 NEW java/lang/StringBuilder +// 2 INVOKEVIRTUAL java/lang/StringBuilder\.append \(Ljava/lang/Object;\)Ljava/lang/StringBuilder; +// 1 INVOKEVIRTUAL java/lang/StringBuilder\.toString \(\)Ljava/lang/String; diff --git a/compiler/testData/codegen/bytecodeText/stringOperations/stringPlus.kt b/compiler/testData/codegen/bytecodeText/stringOperations/stringPlus.kt index 9a1288d65fe..51818f13c40 100644 --- a/compiler/testData/codegen/bytecodeText/stringOperations/stringPlus.kt +++ b/compiler/testData/codegen/bytecodeText/stringOperations/stringPlus.kt @@ -1,5 +1,3 @@ -// IGNORE_BACKEND: JVM - fun f(s: String?, t: String): String { return s.plus(t) } @@ -12,6 +10,9 @@ fun h(s: String, t: Any?): String { return s + t } -// 0 valueOf -// 0 NEW java/lang/StringBuilder -// 3 INVOKESTATIC kotlin/jvm/internal/Intrinsics.stringPlus \ No newline at end of file +// JVM_TEMPLATES +// 1 INVOKESTATIC kotlin/jvm/internal/Intrinsics.stringPlus +// - used in 's.plus(t)' + +// JVM_IR_TEMPLATES +// 0 INVOKESTATIC kotlin/jvm/internal/Intrinsics.stringPlus \ No newline at end of file diff --git a/compiler/testData/debug/stepping/smapInlineInIntrinsicArgument.kt b/compiler/testData/debug/stepping/smapInlineInIntrinsicArgument.kt index b63084b4638..71e4fd7e33c 100644 --- a/compiler/testData/debug/stepping/smapInlineInIntrinsicArgument.kt +++ b/compiler/testData/debug/stepping/smapInlineInIntrinsicArgument.kt @@ -26,11 +26,13 @@ fun fail() : String { // LINENUMBERS // test.kt:4 box // test.kt:12 box +// test.kt:4 box // test.kt:5 box // test.kt:16 fail // test.kt:4 box // test.kt:7 box // test.kt:16 fail +// test.kt:7 box // test.kt:8 box // test.kt:12 box // test.kt:7 box diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java index d31a14d9ade..63e282c25c0 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java @@ -41405,6 +41405,24 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { public void testSurrogatePair() throws Exception { runTest("compiler/testData/codegen/box/strings/surrogatePair.kt"); } + + @Test + @TestMetadata("twoArgumentNullableStringOperatorPlus.kt") + public void testTwoArgumentNullableStringOperatorPlus() throws Exception { + runTest("compiler/testData/codegen/box/strings/twoArgumentNullableStringOperatorPlus.kt"); + } + + @Test + @TestMetadata("twoArgumentNullableStringPlus.kt") + public void testTwoArgumentNullableStringPlus() throws Exception { + runTest("compiler/testData/codegen/box/strings/twoArgumentNullableStringPlus.kt"); + } + + @Test + @TestMetadata("twoArgumentStringTemplate.kt") + public void testTwoArgumentStringTemplate() throws Exception { + runTest("compiler/testData/codegen/box/strings/twoArgumentStringTemplate.kt"); + } } @Nested diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index 7502213d721..a98b4313710 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java @@ -41561,6 +41561,24 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes public void testSurrogatePair() throws Exception { runTest("compiler/testData/codegen/box/strings/surrogatePair.kt"); } + + @Test + @TestMetadata("twoArgumentNullableStringOperatorPlus.kt") + public void testTwoArgumentNullableStringOperatorPlus() throws Exception { + runTest("compiler/testData/codegen/box/strings/twoArgumentNullableStringOperatorPlus.kt"); + } + + @Test + @TestMetadata("twoArgumentNullableStringPlus.kt") + public void testTwoArgumentNullableStringPlus() throws Exception { + runTest("compiler/testData/codegen/box/strings/twoArgumentNullableStringPlus.kt"); + } + + @Test + @TestMetadata("twoArgumentStringTemplate.kt") + public void testTwoArgumentStringTemplate() throws Exception { + runTest("compiler/testData/codegen/box/strings/twoArgumentStringTemplate.kt"); + } } @Nested diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 330487dc50f..7cc82e67b23 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -33275,6 +33275,21 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes public void testSurrogatePair() throws Exception { runTest("compiler/testData/codegen/box/strings/surrogatePair.kt"); } + + @TestMetadata("twoArgumentNullableStringOperatorPlus.kt") + public void testTwoArgumentNullableStringOperatorPlus() throws Exception { + runTest("compiler/testData/codegen/box/strings/twoArgumentNullableStringOperatorPlus.kt"); + } + + @TestMetadata("twoArgumentNullableStringPlus.kt") + public void testTwoArgumentNullableStringPlus() throws Exception { + runTest("compiler/testData/codegen/box/strings/twoArgumentNullableStringPlus.kt"); + } + + @TestMetadata("twoArgumentStringTemplate.kt") + public void testTwoArgumentStringTemplate() throws Exception { + runTest("compiler/testData/codegen/box/strings/twoArgumentStringTemplate.kt"); + } } @TestMetadata("compiler/testData/codegen/box/super") diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java index ee1aa50b42a..93b6b232cf3 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java @@ -27800,6 +27800,21 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes public void testSurrogatePair() throws Exception { runTest("compiler/testData/codegen/box/strings/surrogatePair.kt"); } + + @TestMetadata("twoArgumentNullableStringOperatorPlus.kt") + public void testTwoArgumentNullableStringOperatorPlus() throws Exception { + runTest("compiler/testData/codegen/box/strings/twoArgumentNullableStringOperatorPlus.kt"); + } + + @TestMetadata("twoArgumentNullableStringPlus.kt") + public void testTwoArgumentNullableStringPlus() throws Exception { + runTest("compiler/testData/codegen/box/strings/twoArgumentNullableStringPlus.kt"); + } + + @TestMetadata("twoArgumentStringTemplate.kt") + public void testTwoArgumentStringTemplate() throws Exception { + runTest("compiler/testData/codegen/box/strings/twoArgumentStringTemplate.kt"); + } } @TestMetadata("compiler/testData/codegen/box/super") diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index bcbe812f5f3..65e7fb4e1d8 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -27206,6 +27206,21 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { public void testSurrogatePair() throws Exception { runTest("compiler/testData/codegen/box/strings/surrogatePair.kt"); } + + @TestMetadata("twoArgumentNullableStringOperatorPlus.kt") + public void testTwoArgumentNullableStringOperatorPlus() throws Exception { + runTest("compiler/testData/codegen/box/strings/twoArgumentNullableStringOperatorPlus.kt"); + } + + @TestMetadata("twoArgumentNullableStringPlus.kt") + public void testTwoArgumentNullableStringPlus() throws Exception { + runTest("compiler/testData/codegen/box/strings/twoArgumentNullableStringPlus.kt"); + } + + @TestMetadata("twoArgumentStringTemplate.kt") + public void testTwoArgumentStringTemplate() throws Exception { + runTest("compiler/testData/codegen/box/strings/twoArgumentStringTemplate.kt"); + } } @TestMetadata("compiler/testData/codegen/box/super") diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index fe49ec50c80..2109488194c 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -27131,6 +27131,21 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { public void testSurrogatePair() throws Exception { runTest("compiler/testData/codegen/box/strings/surrogatePair.kt"); } + + @TestMetadata("twoArgumentNullableStringOperatorPlus.kt") + public void testTwoArgumentNullableStringOperatorPlus() throws Exception { + runTest("compiler/testData/codegen/box/strings/twoArgumentNullableStringOperatorPlus.kt"); + } + + @TestMetadata("twoArgumentNullableStringPlus.kt") + public void testTwoArgumentNullableStringPlus() throws Exception { + runTest("compiler/testData/codegen/box/strings/twoArgumentNullableStringPlus.kt"); + } + + @TestMetadata("twoArgumentStringTemplate.kt") + public void testTwoArgumentStringTemplate() throws Exception { + runTest("compiler/testData/codegen/box/strings/twoArgumentStringTemplate.kt"); + } } @TestMetadata("compiler/testData/codegen/box/super") diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java index a7e4d53b79d..114dc67623a 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java @@ -16415,6 +16415,21 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest public void testSurrogatePair() throws Exception { runTest("compiler/testData/codegen/box/strings/surrogatePair.kt"); } + + @TestMetadata("twoArgumentNullableStringOperatorPlus.kt") + public void testTwoArgumentNullableStringOperatorPlus() throws Exception { + runTest("compiler/testData/codegen/box/strings/twoArgumentNullableStringOperatorPlus.kt"); + } + + @TestMetadata("twoArgumentNullableStringPlus.kt") + public void testTwoArgumentNullableStringPlus() throws Exception { + runTest("compiler/testData/codegen/box/strings/twoArgumentNullableStringPlus.kt"); + } + + @TestMetadata("twoArgumentStringTemplate.kt") + public void testTwoArgumentStringTemplate() throws Exception { + runTest("compiler/testData/codegen/box/strings/twoArgumentStringTemplate.kt"); + } } @TestMetadata("compiler/testData/codegen/box/super")