From 59c5d8bdb88b7a01d5c50d213e6783180da235dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steven=20Sch=C3=A4fer?= Date: Mon, 25 Mar 2019 10:39:00 +0100 Subject: [PATCH] Add an implicit cast to Unit in returns from a constructor. --- .../transformations/InsertImplicitCasts.kt | 7 ++++- .../box/secondaryConstructors/withReturn.kt | 1 - .../secondaryConstructors/withReturnUnit.kt | 1 - .../implicitCastInReturnFromConstructor.kt | 5 +++ .../implicitCastInReturnFromConstructor.txt | 31 +++++++++++++++++++ .../kotlin/ir/IrTextTestCaseGenerated.java | 5 +++ 6 files changed, 47 insertions(+), 3 deletions(-) create mode 100644 compiler/testData/ir/irText/expressions/implicitCastInReturnFromConstructor.kt create mode 100644 compiler/testData/ir/irText/expressions/implicitCastInReturnFromConstructor.txt diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InsertImplicitCasts.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InsertImplicitCasts.kt index 21911426506..42203b97c28 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InsertImplicitCasts.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InsertImplicitCasts.kt @@ -27,6 +27,7 @@ import org.jetbrains.kotlin.ir.declarations.IrVariable import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl +import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.classifierOrFail import org.jetbrains.kotlin.ir.types.impl.originalKotlinType @@ -107,7 +108,11 @@ open class InsertImplicitCasts( override fun visitReturn(expression: IrReturn): IrExpression = expression.transformPostfix { - value = value.cast(expression.returnTarget.returnType) + value = if (expression.returnTargetSymbol is IrConstructorSymbol) { + value.coerceToUnit() + } else { + value.cast(expression.returnTarget.returnType) + } } override fun visitSetVariable(expression: IrSetVariable): IrExpression = diff --git a/compiler/testData/codegen/box/secondaryConstructors/withReturn.kt b/compiler/testData/codegen/box/secondaryConstructors/withReturn.kt index 0fcd71bb87c..b6cb18cf2af 100644 --- a/compiler/testData/codegen/box/secondaryConstructors/withReturn.kt +++ b/compiler/testData/codegen/box/secondaryConstructors/withReturn.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR class A { val prop: Int constructor(arg: Boolean) { diff --git a/compiler/testData/codegen/box/secondaryConstructors/withReturnUnit.kt b/compiler/testData/codegen/box/secondaryConstructors/withReturnUnit.kt index d44b3557c1f..956c6db367e 100644 --- a/compiler/testData/codegen/box/secondaryConstructors/withReturnUnit.kt +++ b/compiler/testData/codegen/box/secondaryConstructors/withReturnUnit.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR class A { val prop: Int constructor(arg: Boolean) { diff --git a/compiler/testData/ir/irText/expressions/implicitCastInReturnFromConstructor.kt b/compiler/testData/ir/irText/expressions/implicitCastInReturnFromConstructor.kt new file mode 100644 index 00000000000..b9ee8fc6040 --- /dev/null +++ b/compiler/testData/ir/irText/expressions/implicitCastInReturnFromConstructor.kt @@ -0,0 +1,5 @@ +class C() { + constructor(x: Any?) : this() { + if (x is Unit) return x + } +} \ No newline at end of file diff --git a/compiler/testData/ir/irText/expressions/implicitCastInReturnFromConstructor.txt b/compiler/testData/ir/irText/expressions/implicitCastInReturnFromConstructor.txt new file mode 100644 index 00000000000..b618de419bc --- /dev/null +++ b/compiler/testData/ir/irText/expressions/implicitCastInReturnFromConstructor.txt @@ -0,0 +1,31 @@ +FILE fqName: fileName:/implicitCastInReturnFromConstructor.kt + CLASS CLASS name:C modality:FINAL visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.C + CONSTRUCTOR visibility:public <> () returnType:.C [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:C modality:FINAL visibility:public superTypes:[kotlin.Any]' + CONSTRUCTOR visibility:public <> (x:kotlin.Any?) returnType:.C + VALUE_PARAMETER name:x index:0 type:kotlin.Any? + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in .C' + WHEN type=kotlin.Unit origin=IF + BRANCH + if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=kotlin.Unit + GET_VAR 'x: kotlin.Any? declared in .C.' type=kotlin.Any? origin=null + then: RETURN type=kotlin.Nothing from='public constructor (x: kotlin.Any?) declared in .C' + TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit + GET_VAR 'x: kotlin.Any? declared in .C.' type=kotlin.Any? origin=null + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java b/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java index 3ccad277a7e..8f74b410e7b 100644 --- a/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java @@ -907,6 +907,11 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase { runTest("compiler/testData/ir/irText/expressions/ifElseIf.kt"); } + @TestMetadata("implicitCastInReturnFromConstructor.kt") + public void testImplicitCastInReturnFromConstructor() throws Exception { + runTest("compiler/testData/ir/irText/expressions/implicitCastInReturnFromConstructor.kt"); + } + @TestMetadata("implicitCastOnPlatformType.kt") public void testImplicitCastOnPlatformType() throws Exception { runTest("compiler/testData/ir/irText/expressions/implicitCastOnPlatformType.kt");