Use correct lhs KotlinType & AsmType for is check generation
There were two problems: - For asm type `OBJECT_TYPE` was used, which can be wrong in case of inline classes, because it can be an underlying value of some inline class - For KotlinType, type from rhs was used
This commit is contained in:
@@ -4487,21 +4487,29 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
return negated ? StackValue.not(value) : value;
|
||||
}
|
||||
|
||||
private StackValue generateIsCheck(StackValue expressionToGen, KotlinType kotlinType, boolean leaveExpressionOnStack) {
|
||||
private StackValue generateIsCheck(StackValue expressionToGen, KotlinType rhsKotlinType, boolean leaveExpressionOnStack) {
|
||||
KotlinType lhsKotlinType = expressionToGen.kotlinType;
|
||||
Type lhsBoxedType;
|
||||
if (lhsKotlinType != null && InlineClassesUtilsKt.isInlineClassType(lhsKotlinType)) {
|
||||
lhsBoxedType = typeMapper.mapTypeAsDeclaration(lhsKotlinType);
|
||||
}
|
||||
else {
|
||||
lhsBoxedType = OBJECT_TYPE;
|
||||
}
|
||||
return StackValue.operation(Type.BOOLEAN_TYPE, v -> {
|
||||
expressionToGen.put(OBJECT_TYPE, kotlinType, v);
|
||||
expressionToGen.put(lhsBoxedType, expressionToGen.kotlinType, v);
|
||||
if (leaveExpressionOnStack) {
|
||||
v.dup();
|
||||
}
|
||||
|
||||
Type type = boxType(typeMapper.mapTypeAsDeclaration(kotlinType));
|
||||
if (TypeUtils.isReifiedTypeParameter(kotlinType)) {
|
||||
putReifiedOperationMarkerIfTypeIsReifiedParameter(kotlinType, ReifiedTypeInliner.OperationKind.IS);
|
||||
Type type = boxType(typeMapper.mapTypeAsDeclaration(rhsKotlinType));
|
||||
if (TypeUtils.isReifiedTypeParameter(rhsKotlinType)) {
|
||||
putReifiedOperationMarkerIfTypeIsReifiedParameter(rhsKotlinType, ReifiedTypeInliner.OperationKind.IS);
|
||||
v.instanceOf(type);
|
||||
return null;
|
||||
}
|
||||
|
||||
CodegenUtilKt.generateIsCheck(v, kotlinType, type);
|
||||
CodegenUtilKt.generateIsCheck(v, rhsKotlinType, type);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
// !LANGUAGE: +InlineClasses
|
||||
|
||||
inline class AsAny(val a: Any?) {
|
||||
fun myEq(other: Any?): Boolean {
|
||||
return other is AsAny && other.a == a
|
||||
}
|
||||
}
|
||||
|
||||
inline class AsInt(val a: Int) {
|
||||
fun myEq(other: Any?): Boolean {
|
||||
return other is AsInt && other.a == a
|
||||
}
|
||||
}
|
||||
|
||||
inline fun <reified T> Any?.isCheck() = this is T
|
||||
|
||||
object Reference {
|
||||
fun isNullable(a: AsAny) = a is AsAny?
|
||||
fun isNotNullable(a: AsAny) = a is AsAny
|
||||
fun isNullableNullable(a: AsAny?) = a is AsAny?
|
||||
fun isNullableNotNullable(a: AsAny?) = a is AsAny
|
||||
}
|
||||
|
||||
object Primitive {
|
||||
fun isNullable(a: AsInt) = a is AsInt?
|
||||
fun isNotNullable(a: AsInt) = a is AsInt
|
||||
fun isNullableNullable(a: AsInt?) = a is AsInt?
|
||||
fun isNullableNotNullable(a: AsInt?) = a is AsInt
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val a = AsAny(42)
|
||||
val b = AsAny(40 + 2)
|
||||
|
||||
if (!a.myEq(b)) return "Fail 1"
|
||||
if (a.myEq(42)) return "Fail 2"
|
||||
if (a.myEq("other")) return "Fail 3"
|
||||
|
||||
if (!Reference.isNullable(a)) return "Fail 4"
|
||||
if (!Reference.isNotNullable(a)) return "Fail 5"
|
||||
if (!Reference.isNullableNullable(a)) return "Fail 6"
|
||||
if (!Reference.isNullableNullable(null)) return "Fail 7"
|
||||
if (!Reference.isNullableNotNullable(a)) return "Fail 8"
|
||||
if (Reference.isNullableNotNullable(null)) return "Fail 9"
|
||||
|
||||
val c = AsInt(42)
|
||||
val d = AsInt(40 + 2)
|
||||
if (!c.myEq(d)) return "Fail 10"
|
||||
if (c.myEq(42)) return "Fail 11"
|
||||
if (c.myEq("other")) return "Fail 12"
|
||||
|
||||
if (!Primitive.isNullable(c)) return "Fail 13"
|
||||
if (!Primitive.isNotNullable(c)) return "Fail 14"
|
||||
if (!Primitive.isNullableNullable(c)) return "Fail 15"
|
||||
if (!Primitive.isNullableNullable(null)) return "Fail 16"
|
||||
if (!Primitive.isNullableNotNullable(c)) return "Fail 17"
|
||||
if (Primitive.isNullableNotNullable(null)) return "Fail 18"
|
||||
|
||||
if (!a.isCheck<AsAny>()) return "Fail 19"
|
||||
if (!a.isCheck<AsAny?>()) return "Fail 20"
|
||||
if (a.isCheck<AsInt>()) return "Fail 21"
|
||||
|
||||
if (!c.isCheck<AsInt>()) return "Fail 22"
|
||||
if (!c.isCheck<AsInt?>()) return "Fail 23"
|
||||
if (c.isCheck<AsAny>()) return "Fail 24"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
Generated
+5
@@ -11018,6 +11018,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/referToUnderlyingPropertyOfInlineClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("typeChecksForInlineClasses.kt")
|
||||
public void testTypeChecksForInlineClasses() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/typeChecksForInlineClasses.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("UIntArraySortExample.kt")
|
||||
public void testUIntArraySortExample() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/UIntArraySortExample.kt");
|
||||
|
||||
+5
@@ -11018,6 +11018,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/referToUnderlyingPropertyOfInlineClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("typeChecksForInlineClasses.kt")
|
||||
public void testTypeChecksForInlineClasses() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/typeChecksForInlineClasses.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("UIntArraySortExample.kt")
|
||||
public void testUIntArraySortExample() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/UIntArraySortExample.kt");
|
||||
|
||||
+5
@@ -11018,6 +11018,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/referToUnderlyingPropertyOfInlineClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("typeChecksForInlineClasses.kt")
|
||||
public void testTypeChecksForInlineClasses() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/typeChecksForInlineClasses.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("UIntArraySortExample.kt")
|
||||
public void testUIntArraySortExample() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/UIntArraySortExample.kt");
|
||||
|
||||
+5
@@ -9688,6 +9688,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/referToUnderlyingPropertyOfInlineClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("typeChecksForInlineClasses.kt")
|
||||
public void testTypeChecksForInlineClasses() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/typeChecksForInlineClasses.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("UIntArraySortExample.kt")
|
||||
public void testUIntArraySortExample() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/UIntArraySortExample.kt");
|
||||
|
||||
+5
@@ -9688,6 +9688,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/referToUnderlyingPropertyOfInlineClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("typeChecksForInlineClasses.kt")
|
||||
public void testTypeChecksForInlineClasses() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/typeChecksForInlineClasses.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("UIntArraySortExample.kt")
|
||||
public void testUIntArraySortExample() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/UIntArraySortExample.kt");
|
||||
|
||||
Reference in New Issue
Block a user