From f19ede0637ea97db3f3a4f8f07626abd8f232e52 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Wed, 4 Dec 2013 19:13:39 +0400 Subject: [PATCH] Don't treat values of type "Unit?" to be always equal to Unit.VALUE Two changes here: StackValue.Constant does cast iff value is non-null (if null, no cast between classes is really needed, as null can be an instance of anything), and codegen for safe qualified expressions uses correct type for the expression #KT-4265 Fixed --- .../jet/codegen/ExpressionCodegen.java | 3 +-- .../org/jetbrains/jet/codegen/StackValue.java | 5 ++++- compiler/testData/codegen/box/unit/kt4265.kt | 14 +++++++++++++ .../testData/codegen/box/unit/nullableUnit.kt | 20 +++++++++++++++++++ .../BlackBoxCodegenTestGenerated.java | 10 ++++++++++ 5 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 compiler/testData/codegen/box/unit/kt4265.kt create mode 100644 compiler/testData/codegen/box/unit/nullableUnit.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index b765d1ce7f0..f7649be6416 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -2622,13 +2622,13 @@ public class ExpressionCodegen extends JetVisitor implem public StackValue visitSafeQualifiedExpression(@NotNull JetSafeQualifiedExpression expression, StackValue unused) { JetExpression receiver = expression.getReceiverExpression(); JetExpression selector = expression.getSelectorExpression(); + Type type = boxType(expressionType(expression)); Type receiverType = expressionType(receiver); gen(receiver, receiverType); if (isPrimitive(receiverType)) { StackValue propValue = genQualified(StackValue.onStack(receiverType), selector); - Type type = boxType(propValue.type); propValue.put(type, v); return StackValue.onStack(type); @@ -2639,7 +2639,6 @@ public class ExpressionCodegen extends JetVisitor implem v.dup(); v.ifnull(ifnull); StackValue propValue = genQualified(StackValue.onStack(receiverType), selector); - Type type = boxType(propValue.type); propValue.put(type, v); v.goTo(end); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java index 4d02fd2749d..c69abf2286f 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java @@ -430,7 +430,10 @@ public abstract class StackValue { else { v.aconst(value); } - coerceTo(type, v); + + if (value != null) { + coerceTo(type, v); + } } @Override diff --git a/compiler/testData/codegen/box/unit/kt4265.kt b/compiler/testData/codegen/box/unit/kt4265.kt new file mode 100644 index 00000000000..3c1aaf9d462 --- /dev/null +++ b/compiler/testData/codegen/box/unit/kt4265.kt @@ -0,0 +1,14 @@ +fun T.let(f: (T) -> R): R = f(this) + +fun box(): String { + val o: String? = null + + var state = 0 + + o?.let { + state = 1 + } ?: ({ state = 2 })() + + if (state != 2) return "Fail: $state" + return "OK" +} diff --git a/compiler/testData/codegen/box/unit/nullableUnit.kt b/compiler/testData/codegen/box/unit/nullableUnit.kt new file mode 100644 index 00000000000..12abddc9695 --- /dev/null +++ b/compiler/testData/codegen/box/unit/nullableUnit.kt @@ -0,0 +1,20 @@ +fun isNull(x: Unit?) = x == null + +fun isNullGeneric(x: T?) = x == null + +fun deepIsNull0(x: Unit?) = isNull(x) +fun deepIsNull(x: Unit?) = deepIsNull0(x) + +fun box(): String { + if (!isNull(null)) return "Fail 1" + + val x: Unit? = null + if (!isNull(x)) return "Fail 2" + + val y = x + if (!isNullGeneric(y)) return "Fail 3" + + if (!deepIsNull((null : Unit?) ?: null)) return "Fail 4" + + return "OK" +} diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java index 50db654cffc..8b07fd0f152 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java @@ -4764,6 +4764,16 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/box/unit"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("kt4265.kt") + public void testKt4265() throws Exception { + doTest("compiler/testData/codegen/box/unit/kt4265.kt"); + } + + @TestMetadata("nullableUnit.kt") + public void testNullableUnit() throws Exception { + doTest("compiler/testData/codegen/box/unit/nullableUnit.kt"); + } + @TestMetadata("unitClassObject.kt") public void testUnitClassObject() throws Exception { doTest("compiler/testData/codegen/box/unit/unitClassObject.kt");