Fix data class equals codegen for type parameters with interface bounds
#KT-24474 Fixed
This commit is contained in:
@@ -558,7 +558,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
iv.store(2, OBJECT_TYPE);
|
iv.store(2, OBJECT_TYPE);
|
||||||
|
|
||||||
for (PropertyDescriptor propertyDescriptor : properties) {
|
for (PropertyDescriptor propertyDescriptor : properties) {
|
||||||
Type asmType = typeMapper.mapType(propertyDescriptor);
|
KotlinType type = propertyDescriptor.getType();
|
||||||
|
Type asmType = typeMapper.mapType(type);
|
||||||
|
|
||||||
Type thisPropertyType = genPropertyOnStack(iv, context, propertyDescriptor, ImplementationBodyCodegen.this.classAsmType, 0);
|
Type thisPropertyType = genPropertyOnStack(iv, context, propertyDescriptor, ImplementationBodyCodegen.this.classAsmType, 0);
|
||||||
StackValue.coerce(thisPropertyType, asmType, iv);
|
StackValue.coerce(thisPropertyType, asmType, iv);
|
||||||
@@ -579,18 +580,21 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
StackValue value = StackValue.cmp(KtTokens.EQEQ, asmType, StackValue.onStack(asmType), StackValue.onStack(asmType));
|
StackValue value = StackValue.cmp(KtTokens.EQEQ, asmType, StackValue.onStack(asmType), StackValue.onStack(asmType));
|
||||||
value.put(Type.BOOLEAN_TYPE, iv);
|
value.put(Type.BOOLEAN_TYPE, iv);
|
||||||
}
|
}
|
||||||
else if (TypeUtils.isNullableType(propertyDescriptor.getType())) {
|
|
||||||
StackValue value =
|
|
||||||
genEqualsForExpressionsOnStack(KtTokens.EQEQ, StackValue.onStack(asmType), StackValue.onStack(asmType));
|
|
||||||
value.put(Type.BOOLEAN_TYPE, iv);
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
Type owner =
|
if (TypeUtils.isNullableType(type)) {
|
||||||
DescriptorUtils.isInterface(propertyDescriptor.getType().getConstructor().getDeclarationDescriptor())
|
StackValue value =
|
||||||
? AsmTypes.OBJECT_TYPE
|
genEqualsForExpressionsOnStack(KtTokens.EQEQ, StackValue.onStack(asmType), StackValue.onStack(asmType));
|
||||||
: asmType;
|
value.put(Type.BOOLEAN_TYPE, iv);
|
||||||
iv.invokevirtual(owner.getInternalName(), "equals",
|
}
|
||||||
Type.getMethodDescriptor(Type.BOOLEAN_TYPE, AsmTypes.OBJECT_TYPE), false);
|
else {
|
||||||
|
ClassifierDescriptor classifier = type.getConstructor().getDeclarationDescriptor();
|
||||||
|
Type owner =
|
||||||
|
!(classifier instanceof ClassDescriptor) || DescriptorUtils.isInterface(classifier)
|
||||||
|
? AsmTypes.OBJECT_TYPE
|
||||||
|
: asmType;
|
||||||
|
iv.invokevirtual(owner.getInternalName(), "equals",
|
||||||
|
Type.getMethodDescriptor(Type.BOOLEAN_TYPE, AsmTypes.OBJECT_TYPE), false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
iv.ifeq(ne);
|
iv.ifeq(ne);
|
||||||
}
|
}
|
||||||
|
|||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
interface A
|
||||||
|
|
||||||
|
data class B<out T : A>(val a: T)
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val b1 = B(object : A {})
|
||||||
|
val b2 = B(object : A {})
|
||||||
|
return if (b1.equals(b2)) "Fail" else "OK"
|
||||||
|
}
|
||||||
Generated
+5
@@ -7941,6 +7941,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
public void testSameinstance() throws Exception {
|
public void testSameinstance() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/dataClasses/equals/sameinstance.kt");
|
runTest("compiler/testData/codegen/box/dataClasses/equals/sameinstance.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("typeParameterWithInterfaceBound.kt")
|
||||||
|
public void testTypeParameterWithInterfaceBound() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/dataClasses/equals/typeParameterWithInterfaceBound.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/box/dataClasses/hashCode")
|
@TestMetadata("compiler/testData/codegen/box/dataClasses/hashCode")
|
||||||
|
|||||||
+5
@@ -7941,6 +7941,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
public void testSameinstance() throws Exception {
|
public void testSameinstance() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/dataClasses/equals/sameinstance.kt");
|
runTest("compiler/testData/codegen/box/dataClasses/equals/sameinstance.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("typeParameterWithInterfaceBound.kt")
|
||||||
|
public void testTypeParameterWithInterfaceBound() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/dataClasses/equals/typeParameterWithInterfaceBound.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/box/dataClasses/hashCode")
|
@TestMetadata("compiler/testData/codegen/box/dataClasses/hashCode")
|
||||||
|
|||||||
+5
@@ -7941,6 +7941,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
public void testSameinstance() throws Exception {
|
public void testSameinstance() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/dataClasses/equals/sameinstance.kt");
|
runTest("compiler/testData/codegen/box/dataClasses/equals/sameinstance.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("typeParameterWithInterfaceBound.kt")
|
||||||
|
public void testTypeParameterWithInterfaceBound() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/dataClasses/equals/typeParameterWithInterfaceBound.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/box/dataClasses/hashCode")
|
@TestMetadata("compiler/testData/codegen/box/dataClasses/hashCode")
|
||||||
|
|||||||
+5
@@ -6523,6 +6523,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
public void testSameinstance() throws Exception {
|
public void testSameinstance() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/dataClasses/equals/sameinstance.kt");
|
runTest("compiler/testData/codegen/box/dataClasses/equals/sameinstance.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("typeParameterWithInterfaceBound.kt")
|
||||||
|
public void testTypeParameterWithInterfaceBound() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/dataClasses/equals/typeParameterWithInterfaceBound.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/box/dataClasses/hashCode")
|
@TestMetadata("compiler/testData/codegen/box/dataClasses/hashCode")
|
||||||
|
|||||||
Reference in New Issue
Block a user