Fix KotlinType of constructor call for inline classes
This commit is contained in:
@@ -2107,19 +2107,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
if (descriptor instanceof ConstructorDescriptor) {
|
||||
if (InlineClassesUtilsKt.isInlineClass(descriptor.getContainingDeclaration())) {
|
||||
KtValueArgument valueArgument = CollectionsKt.firstOrNull(expression.getValueArguments());
|
||||
if (valueArgument == null) return null;
|
||||
|
||||
SimpleType inlineClassType = ((ClassDescriptor) descriptor.getContainingDeclaration()).getDefaultType();
|
||||
|
||||
Type underlyingType = typeMapper.mapType(inlineClassType);
|
||||
KotlinType underlyingKotlinType = InlineClassesUtilsKt.unsubstitutedUnderlyingType(inlineClassType);
|
||||
|
||||
StackValue argumentValue = gen(valueArgument.getArgumentExpression());
|
||||
|
||||
return StackValue.coercionValueForArgumentOfInlineClassConstructor(
|
||||
argumentValue, underlyingType, inlineClassType, underlyingKotlinType
|
||||
);
|
||||
return generateInlineClassConstructorCall(expression);
|
||||
}
|
||||
|
||||
return generateNewCall(expression, resolvedCall);
|
||||
@@ -2134,6 +2122,24 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
return invokeFunction(resolvedCall, receiver);
|
||||
}
|
||||
|
||||
private StackValue generateInlineClassConstructorCall(@NotNull KtCallExpression expression) {
|
||||
KtValueArgument valueArgument = CollectionsKt.singleOrNull(expression.getValueArguments());
|
||||
assert valueArgument != null : "Inline class constructor call should have single argument";
|
||||
|
||||
KotlinType inlineClassType = kotlinType(expression);
|
||||
assert inlineClassType != null && InlineClassesUtilsKt.isInlineClassType(inlineClassType) :
|
||||
"Constructor call expression of inline class should have inline class type, but have: " + inlineClassType;
|
||||
|
||||
Type underlyingType = typeMapper.mapType(inlineClassType);
|
||||
KotlinType underlyingKotlinType = InlineClassesUtilsKt.unsubstitutedUnderlyingType(inlineClassType);
|
||||
|
||||
StackValue argumentValue = gen(valueArgument.getArgumentExpression());
|
||||
|
||||
return StackValue.coercionValueForArgumentOfInlineClassConstructor(
|
||||
argumentValue, underlyingType, inlineClassType, underlyingKotlinType
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StackValue visitCollectionLiteralExpression(
|
||||
@NotNull KtCollectionLiteralExpression expression, StackValue data
|
||||
|
||||
+17
@@ -4,20 +4,37 @@ inline class Result<T>(val a: Any?) {
|
||||
fun typed(): T = a as T
|
||||
}
|
||||
|
||||
fun <T> takeResult(r: Result<T>) {}
|
||||
fun takeResultOfInt(r: Result<Int>) {}
|
||||
fun takeInt(i: Int) {}
|
||||
|
||||
|
||||
fun box(): String {
|
||||
val asInt = Result<Int>(19)
|
||||
val asString = Result<String>("sample")
|
||||
val asResult = Result<Result<Int>>(asInt)
|
||||
val asResultCtor = Result<Result<Int>>(Result<Int>(10))
|
||||
|
||||
takeResult(asInt)
|
||||
takeResult(asString)
|
||||
takeResult(asResult)
|
||||
takeResult(asResultCtor)
|
||||
|
||||
takeResultOfInt(asInt)
|
||||
takeInt(asInt.typed())
|
||||
|
||||
val unboxedInt = asInt.typed()
|
||||
val unboxedString = asString.typed()
|
||||
val unboxedResult = asResult.typed()
|
||||
val unboxedAsCtor = asResultCtor.typed()
|
||||
|
||||
if (unboxedInt != 19) return "fail"
|
||||
if (unboxedString != "sample") return "fail"
|
||||
if (unboxedResult.typed() != 19) return "fail"
|
||||
if (unboxedAsCtor.typed() != 10) return "fail"
|
||||
|
||||
if (asResult.typed().typed() != 19) return "fail"
|
||||
if (asResultCtor.typed().typed() != 10) return "fail"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
Vendored
+17
@@ -0,0 +1,17 @@
|
||||
// !LANGUAGE: +InlineClasses
|
||||
|
||||
inline class Result<T>(val a: Any?)
|
||||
|
||||
fun test() {
|
||||
val a = Result<Int>(1) // valueOf
|
||||
val b = Result<String>("sample")
|
||||
|
||||
val c = Result<Result<Int>>(a) // box
|
||||
val d = Result<Result<Int>>(Result<Int>(1)) // valueOf, box
|
||||
}
|
||||
|
||||
// 2 INVOKESTATIC Result\$Erased.box
|
||||
// 0 INVOKEVIRTUAL Result.unbox
|
||||
|
||||
// 2 valueOf
|
||||
// 0 intValue
|
||||
@@ -1959,6 +1959,12 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("boxResultInlineClassOfConstructorCall.kt")
|
||||
public void testBoxResultInlineClassOfConstructorCall() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/inlineClasses/boxResultInlineClassOfConstructorCall.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("boxThisOfInlineClass.kt")
|
||||
public void testBoxThisOfInlineClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/inlineClasses/boxThisOfInlineClass.kt");
|
||||
|
||||
Reference in New Issue
Block a user