From d606e5bc8986d5e6e3c1902083af2788166e7177 Mon Sep 17 00:00:00 2001 From: Mikhail Zarechenskiy Date: Fri, 9 Feb 2018 08:48:15 +0300 Subject: [PATCH] Correct boxing for functional types containing inline classes --- .../kotlin/codegen/ClosureCodegen.java | 4 ++- ...LambdaWithInlineClassesInFunctionalType.kt | 26 ++++++++++++++++++ ...UnboxOfInlineClassesWithFunctionalTypes.kt | 27 +++++++++++++++++++ .../inlineClassesInsideFunctionalTypes.kt | 19 +++++++++++++ .../ir/IrBlackBoxCodegenTestGenerated.java | 6 +++++ .../codegen/BlackBoxCodegenTestGenerated.java | 6 +++++ .../codegen/BytecodeTextTestGenerated.java | 6 +++++ .../LightAnalysisModeTestGenerated.java | 6 +++++ .../compiler/WriteSignatureTestGenerated.java | 6 +++++ .../semantics/JsCodegenBoxTestGenerated.java | 6 +++++ 10 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 compiler/testData/codegen/box/inlineClasses/checkLambdaWithInlineClassesInFunctionalType.kt create mode 100644 compiler/testData/codegen/bytecodeText/inlineClasses/boxUnboxOfInlineClassesWithFunctionalTypes.kt create mode 100644 compiler/testData/writeSignature/inlineClasses/inlineClassesInsideFunctionalTypes.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java index 8057b47c882..a7a539eb64c 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java @@ -297,7 +297,9 @@ public class ClosureCodegen extends MemberCodegen { int slot = 1; for (int i = 0; i < calleeParameters.size(); i++) { Type type = myParameterTypes[i]; - StackValue.local(slot, type).put(typeMapper.mapType(calleeParameters.get(i)), iv); + ParameterDescriptor calleeParameter = calleeParameters.get(i); + KotlinType parameterType = calleeParameter.getType(); + StackValue.local(slot, type, parameterType).put(typeMapper.mapType(calleeParameter), parameterType, iv); slot += type.getSize(); } diff --git a/compiler/testData/codegen/box/inlineClasses/checkLambdaWithInlineClassesInFunctionalType.kt b/compiler/testData/codegen/box/inlineClasses/checkLambdaWithInlineClassesInFunctionalType.kt new file mode 100644 index 00000000000..aa3c2d2e1ad --- /dev/null +++ b/compiler/testData/codegen/box/inlineClasses/checkLambdaWithInlineClassesInFunctionalType.kt @@ -0,0 +1,26 @@ +// !LANGUAGE: +InlineClasses + +inline class UInt(val value: Int) +inline class ULong(val value: Long) + +fun foo(u: UInt, f: (UInt) -> ULong): ULong = f(u) +inline fun inlinedFoo(u: UInt, f: (UInt) -> ULong): ULong = f(u) + +fun mapUIntToULong(u: UInt): ULong = ULong(u.value.toLong()) + +fun box(): String { + val u = UInt(123) + val l1 = foo(u) { + mapUIntToULong(it) + } + + if (l1.value != 123L) return "fail" + + val l2 = inlinedFoo(UInt(10)) { + mapUIntToULong(it) + } + + if (l2.value != 10L) return "fail" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/inlineClasses/boxUnboxOfInlineClassesWithFunctionalTypes.kt b/compiler/testData/codegen/bytecodeText/inlineClasses/boxUnboxOfInlineClassesWithFunctionalTypes.kt new file mode 100644 index 00000000000..14a2233f3a3 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/inlineClasses/boxUnboxOfInlineClassesWithFunctionalTypes.kt @@ -0,0 +1,27 @@ +// !LANGUAGE: +InlineClasses + +inline class UInt(val value: Int) +inline class ULong(val value: Long) + +fun foo(u: UInt, f: (UInt) -> ULong): ULong = f(u) + +fun takeUInt(u: UInt) {} + +fun test() { + val u = UInt(0) + val l = foo(u) { // box unbox UInt + takeUInt(it) + + ULong(0) // box ULong + } // unbox ULong +} + +// 1 INVOKESTATIC UInt\$Erased.box +// 1 INVOKEVIRTUAL UInt.unbox + +// 1 INVOKESTATIC ULong\$Erased.box +// 1 INVOKEVIRTUAL ULong.unbox + +// 0 valueOf +// 0 intValue +// 0 longValue \ No newline at end of file diff --git a/compiler/testData/writeSignature/inlineClasses/inlineClassesInsideFunctionalTypes.kt b/compiler/testData/writeSignature/inlineClasses/inlineClassesInsideFunctionalTypes.kt new file mode 100644 index 00000000000..f8e8f52ab68 --- /dev/null +++ b/compiler/testData/writeSignature/inlineClasses/inlineClassesInsideFunctionalTypes.kt @@ -0,0 +1,19 @@ +// !LANGUAGE: +InlineClasses + +class Inv + +inline class UInt(val value: Int) +inline class ULong(val value: Long) + +object Test { + fun uIntToULong(f: (UInt) -> ULong) {} + fun listOfUIntsToListOfULongs(f: (List) -> List) {} +} + +// method: Test::uIntToULong +// jvm signature: (Lkotlin/jvm/functions/Function1;)V +// generic signature: (Lkotlin/jvm/functions/Function1<-LUInt;LULong;>;)V + +// method: Test::listOfUIntsToListOfULongs +// jvm signature: (Lkotlin/jvm/functions/Function1;)V +// generic signature: (Lkotlin/jvm/functions/Function1<-Ljava/util/List;+Ljava/util/List;>;)V \ No newline at end of file diff --git a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 40a51c865a4..91b0ac94b03 100644 --- a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -10449,6 +10449,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes doTest(fileName); } + @TestMetadata("checkLambdaWithInlineClassesInFunctionalType.kt") + public void testCheckLambdaWithInlineClassesInFunctionalType() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/checkLambdaWithInlineClassesInFunctionalType.kt"); + doTest(fileName); + } + @TestMetadata("computablePropertyInsideInlineClass.kt") public void testComputablePropertyInsideInlineClass() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/computablePropertyInsideInlineClass.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index eb1229ca97e..cf746bea24d 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -10449,6 +10449,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("checkLambdaWithInlineClassesInFunctionalType.kt") + public void testCheckLambdaWithInlineClassesInFunctionalType() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/checkLambdaWithInlineClassesInFunctionalType.kt"); + doTest(fileName); + } + @TestMetadata("computablePropertyInsideInlineClass.kt") public void testComputablePropertyInsideInlineClass() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/computablePropertyInsideInlineClass.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java index 7a2666f15b3..e7acfa21c01 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java @@ -1938,6 +1938,12 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest { doTest(fileName); } + @TestMetadata("boxUnboxOfInlineClassesWithFunctionalTypes.kt") + public void testBoxUnboxOfInlineClassesWithFunctionalTypes() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/inlineClasses/boxUnboxOfInlineClassesWithFunctionalTypes.kt"); + doTest(fileName); + } + @TestMetadata("boxUnboxOnInlinedParameters.kt") public void testBoxUnboxOnInlinedParameters() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/inlineClasses/boxUnboxOnInlinedParameters.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 2e8ffce4900..64bd7a6bada 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -10449,6 +10449,12 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes doTest(fileName); } + @TestMetadata("checkLambdaWithInlineClassesInFunctionalType.kt") + public void testCheckLambdaWithInlineClassesInFunctionalType() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/checkLambdaWithInlineClassesInFunctionalType.kt"); + doTest(fileName); + } + @TestMetadata("computablePropertyInsideInlineClass.kt") public void testComputablePropertyInsideInlineClass() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/computablePropertyInsideInlineClass.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/WriteSignatureTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/WriteSignatureTestGenerated.java index 6736e1a4823..02c830243ed 100644 --- a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/WriteSignatureTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/WriteSignatureTestGenerated.java @@ -600,6 +600,12 @@ public class WriteSignatureTestGenerated extends AbstractWriteSignatureTest { doTest(fileName); } + @TestMetadata("inlineClassesInsideFunctionalTypes.kt") + public void testInlineClassesInsideFunctionalTypes() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/writeSignature/inlineClasses/inlineClassesInsideFunctionalTypes.kt"); + doTest(fileName); + } + @TestMetadata("nullableInlineClassType.kt") public void testNullableInlineClassType() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/writeSignature/inlineClasses/nullableInlineClassType.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 58b83f3ffc6..7a9e86d9369 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -11433,6 +11433,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { doTest(fileName); } + @TestMetadata("checkLambdaWithInlineClassesInFunctionalType.kt") + public void testCheckLambdaWithInlineClassesInFunctionalType() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/checkLambdaWithInlineClassesInFunctionalType.kt"); + doTest(fileName); + } + @TestMetadata("computablePropertyInsideInlineClass.kt") public void testComputablePropertyInsideInlineClass() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/computablePropertyInsideInlineClass.kt");