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
This commit is contained in:
@@ -2622,13 +2622,13 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> 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<StackValue, StackValue> 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);
|
||||
|
||||
|
||||
@@ -430,7 +430,10 @@ public abstract class StackValue {
|
||||
else {
|
||||
v.aconst(value);
|
||||
}
|
||||
coerceTo(type, v);
|
||||
|
||||
if (value != null) {
|
||||
coerceTo(type, v);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
fun <T : Any, R> 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"
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
fun isNull(x: Unit?) = x == null
|
||||
|
||||
fun isNullGeneric<T : Any>(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"
|
||||
}
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user