diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index f7b4e07a0b5..36326fac561 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -2180,11 +2180,6 @@ public class ExpressionCodegen extends KtVisitor impleme FunctionDescriptor descriptor = accessibleFunctionDescriptor(resolvedCall); if (descriptor instanceof ConstructorDescriptor) { - if (InlineClassesUtilsKt.isInlineClass(descriptor.getContainingDeclaration()) && ((ConstructorDescriptor) descriptor).isPrimary()) { - // we do not call static function `constructor`, because it's empty - return generateInlineClassConstructorCall(expression); - } - return generateNewCall(expression, resolvedCall); } @@ -2197,24 +2192,6 @@ public class ExpressionCodegen extends KtVisitor 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 @@ -4215,8 +4192,12 @@ public class ExpressionCodegen extends KtVisitor impleme private StackValue generateNewCall(@NotNull KtCallExpression expression, @NotNull ResolvedCall resolvedCall) { Type type = expressionType(expression); if (type.getSort() == Type.ARRAY) { - //noinspection ConstantConditions - return generateNewArray(expression, bindingContext.getType(expression), resolvedCall); + KotlinType kotlinType = kotlinType(expression); + assert kotlinType != null : "No kotlinType for expression of type " + type + ": " + expression.getText(); + if (KotlinBuiltIns.isArrayOrPrimitiveArray(kotlinType)) { + //noinspection ConstantConditions + return generateNewArray(expression, bindingContext.getType(expression), resolvedCall); + } } return generateConstructorCall(resolvedCall, type); @@ -4250,7 +4231,7 @@ public class ExpressionCodegen extends KtVisitor impleme @NotNull public StackValue generateConstructorCall(@NotNull ResolvedCall resolvedCall, @NotNull Type objectType) { - return StackValue.functionCall(objectType, null, v -> { + return StackValue.functionCall(objectType, resolvedCall.getResultingDescriptor().getReturnType(), v -> { ClassConstructorDescriptor constructor = getConstructorDescriptor(resolvedCall); ReceiverParameterDescriptor dispatchReceiver = constructor.getDispatchReceiverParameter(); ClassDescriptor containingDeclaration = constructor.getContainingDeclaration(); diff --git a/compiler/testData/codegen/box/inlineClasses/boxResultInlineClassOfConstructorCall.kt b/compiler/testData/codegen/box/inlineClasses/boxResultInlineClassOfConstructorCall.kt new file mode 100644 index 00000000000..3999a3dbff7 --- /dev/null +++ b/compiler/testData/codegen/box/inlineClasses/boxResultInlineClassOfConstructorCall.kt @@ -0,0 +1,24 @@ +// !LANGUAGE: +InlineClasses + +inline class Result(val a: Any?) + +fun box(): String { + val a = Result(1) // valueOf + val b = Result("sample") + val c = Result>(a) + val d = Result>(Result(1)) // valueOf + + if (a.a !is Int) throw AssertionError() + + if (b.a !is String) throw AssertionError() + + if (c.a !is Result<*>) throw AssertionError() + val ca = c.a as Result<*> + if (ca.a !is Int) throw AssertionError() + + if (d.a !is Result<*>) throw AssertionError() + val da = d.a as Result<*> + if (da.a !is Int) throw AssertionError() + + return "OK" +} diff --git a/compiler/testData/codegen/box/inlineClasses/secondaryConstructorWithVararg.kt b/compiler/testData/codegen/box/inlineClasses/secondaryConstructorWithVararg.kt new file mode 100644 index 00000000000..e898e64309c --- /dev/null +++ b/compiler/testData/codegen/box/inlineClasses/secondaryConstructorWithVararg.kt @@ -0,0 +1,20 @@ +// !LANGUAGE: +InlineClasses +// WITH_RUNTIME +// IGNORE_BACKEND: JVM_IR + +inline class Z(val x: Int) { + constructor(vararg ys: Long) : this(ys.size) +} + +fun box(): String { + val z1 = Z(111) + if (z1.x != 111) throw AssertionError() + + val z2 = Z() + if (z2.x != 0) throw AssertionError() + + val z3 = Z(2222L) + if (z3.x != 1) throw AssertionError() + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/inlineClasses/boxInlineClassInsideElvisWithNullConstant.kt b/compiler/testData/codegen/bytecodeText/inlineClasses/boxInlineClassInsideElvisWithNullConstant.kt index f9d70ee3ac8..f82b8bb27b1 100644 --- a/compiler/testData/codegen/bytecodeText/inlineClasses/boxInlineClassInsideElvisWithNullConstant.kt +++ b/compiler/testData/codegen/bytecodeText/inlineClasses/boxInlineClassInsideElvisWithNullConstant.kt @@ -12,6 +12,7 @@ fun f() { // @TestKt.class: // 0 INVOKESTATIC UInt\$Erased.box +// 0 INVOKESTATIC UInt\.box // 0 INVOKEVIRTUAL UInt.unbox // 0 valueOf // 0 intValue \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/inlineClasses/boxResultInlineClassOfConstructorCall.kt b/compiler/testData/codegen/bytecodeText/inlineClasses/boxResultInlineClassOfConstructorCall.kt index 3d701334db9..b3bdafaec79 100644 --- a/compiler/testData/codegen/bytecodeText/inlineClasses/boxResultInlineClassOfConstructorCall.kt +++ b/compiler/testData/codegen/bytecodeText/inlineClasses/boxResultInlineClassOfConstructorCall.kt @@ -16,6 +16,7 @@ fun test() { // @TestKt.class: // 0 INVOKESTATIC Result\$Erased.box +// 2 INVOKESTATIC Result\.box // 0 INVOKEVIRTUAL Result.unbox // 2 valueOf diff --git a/compiler/testData/codegen/bytecodeText/inlineClasses/primaryConstructorCalledByInlineClass.kt b/compiler/testData/codegen/bytecodeText/inlineClasses/primaryConstructorCalledByInlineClass.kt new file mode 100644 index 00000000000..53fd56dde5c --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/inlineClasses/primaryConstructorCalledByInlineClass.kt @@ -0,0 +1,10 @@ +// !LANGUAGE: +InlineClasses + +// FILE: Z.kt +inline class Z(val x: Int) + +// FILE: test.kt +fun testZ() = Z(42) + +// @TestKt.class: +// 1 INVOKESTATIC Z\.constructor \(I\)I diff --git a/compiler/testData/codegen/bytecodeText/inlineClasses/unboxInlineClassFromParameterizedType.kt b/compiler/testData/codegen/bytecodeText/inlineClasses/unboxInlineClassFromParameterizedType.kt index 85ffcee6e69..366a68b1a8b 100644 --- a/compiler/testData/codegen/bytecodeText/inlineClasses/unboxInlineClassFromParameterizedType.kt +++ b/compiler/testData/codegen/bytecodeText/inlineClasses/unboxInlineClassFromParameterizedType.kt @@ -27,6 +27,7 @@ fun test(asInt: Result, asString: Result, asResult: Result