Correct boxing for functional types containing inline classes

This commit is contained in:
Mikhail Zarechenskiy
2018-02-09 08:48:15 +03:00
parent a8a9f774d0
commit d606e5bc89
10 changed files with 111 additions and 1 deletions
@@ -297,7 +297,9 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
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();
}
@@ -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"
}
@@ -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
@@ -0,0 +1,19 @@
// !LANGUAGE: +InlineClasses
class Inv<T>
inline class UInt(val value: Int)
inline class ULong(val value: Long)
object Test {
fun uIntToULong(f: (UInt) -> ULong) {}
fun listOfUIntsToListOfULongs(f: (List<UInt>) -> List<ULong>) {}
}
// 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<LUInt;>;+Ljava/util/List<LULong;>;>;)V
@@ -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");
@@ -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");
@@ -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");
@@ -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");
@@ -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");
@@ -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");