diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java index e849efb984b..1bd7d0afc34 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java @@ -828,8 +828,8 @@ public class AsmUtil { } return StackValue.operation(Type.BOOLEAN_TYPE, v -> { - left.put(leftType, v); - right.put(rightType, v); + left.put(AsmTypes.OBJECT_TYPE, left.kotlinType, v); + right.put(AsmTypes.OBJECT_TYPE, right.kotlinType, v); genAreEqualCall(v); if (opToken == KtTokens.EXCLEQ || opToken == KtTokens.EXCLEQEQEQ) { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index f16658303b7..a6e5643b723 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -3548,8 +3548,8 @@ public class ExpressionCodegen extends KtVisitor impleme return genEqualsForExpressionsOnStack( opToken, - genLazyUnlessProvided(pregeneratedLeft, left, leftType), - genLazy(right, rightType) + genLazyUnlessProvided(pregeneratedLeft, left, leftType, kotlinType(left)), + genLazy(right, rightType, kotlinType(right)) ); } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionsFromAnyGeneratorImpl.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionsFromAnyGeneratorImpl.java index 12c48d2068c..9481a991202 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionsFromAnyGeneratorImpl.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionsFromAnyGeneratorImpl.java @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.codegen; +import kotlin.Unit; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.backend.common.FunctionsFromAnyGenerator; @@ -96,7 +97,7 @@ public class FunctionsFromAnyGeneratorImpl extends FunctionsFromAnyGenerator { boolean first = true; for (PropertyDescriptor propertyDescriptor : properties) { if (first) { - iv.aconst(classDescriptor.getName() + "(" + propertyDescriptor.getName().asString()+"="); + iv.aconst(classDescriptor.getName() + "(" + propertyDescriptor.getName().asString() + "="); first = false; } else { @@ -237,23 +238,32 @@ public class FunctionsFromAnyGeneratorImpl extends FunctionsFromAnyGenerator { KotlinType kotlinType = propertyDescriptor.getReturnType(); Type asmType = typeMapper.mapType(kotlinType); - JvmKotlinType thisPropertyType = genOrLoadOnStack(iv,context, propertyDescriptor, 0); - StackValue.coerce(thisPropertyType.getType(), thisPropertyType.getKotlinType(), asmType, kotlinType, iv); - - JvmKotlinType otherPropertyType = genOrLoadOnStack(iv,context, propertyDescriptor, storedValueIndex); - StackValue.coerce(otherPropertyType.getType(), otherPropertyType.getKotlinType(), asmType, kotlinType, iv); + StackValue thisPropertyValue = StackValue.operation(asmType, kotlinType, (InstructionAdapter iiv) -> { + JvmKotlinType thisPropertyType = genOrLoadOnStack(iiv, context, propertyDescriptor, 0); + StackValue.coerce(thisPropertyType.getType(), thisPropertyType.getKotlinType(), asmType, kotlinType, iiv); + return Unit.INSTANCE; + }); + StackValue otherPropertyValue = StackValue.operation(asmType, kotlinType, (InstructionAdapter iiv) -> { + JvmKotlinType otherPropertyType = genOrLoadOnStack(iiv, context, propertyDescriptor, storedValueIndex); + StackValue.coerce(otherPropertyType.getType(), otherPropertyType.getKotlinType(), asmType, kotlinType, iiv); + return Unit.INSTANCE; + }); if (asmType.getSort() == Type.FLOAT) { + thisPropertyValue.put(asmType, kotlinType, iv); + otherPropertyValue.put(asmType, kotlinType, iv); iv.invokestatic("java/lang/Float", "compare", "(FF)I", false); iv.ifne(ne); } else if (asmType.getSort() == Type.DOUBLE) { + thisPropertyValue.put(asmType, kotlinType, iv); + otherPropertyValue.put(asmType, kotlinType, iv); iv.invokestatic("java/lang/Double", "compare", "(DD)I", false); iv.ifne(ne); } else { StackValue value = genEqualsForExpressionsOnStack( - KtTokens.EQEQ, StackValue.onStack(asmType, kotlinType), StackValue.onStack(asmType, kotlinType) + KtTokens.EQEQ, thisPropertyValue, otherPropertyValue ); value.put(Type.BOOLEAN_TYPE, iv); iv.ifeq(ne); diff --git a/compiler/testData/codegen/box/unsignedTypes/equalsImplForInlineClassWrappingNullableInlineClass.kt b/compiler/testData/codegen/box/unsignedTypes/equalsImplForInlineClassWrappingNullableInlineClass.kt new file mode 100644 index 00000000000..ee83125f01f --- /dev/null +++ b/compiler/testData/codegen/box/unsignedTypes/equalsImplForInlineClassWrappingNullableInlineClass.kt @@ -0,0 +1,15 @@ +// !LANGUAGE: +InlineClasses +// IGNORE_BACKEND: JVM_IR + +inline class Z(val x: Int) +inline class NZ1(val nz: Z?) +inline class NZ2(val nz: NZ1) + +fun box(): String { + if (NZ2(NZ1(null)) != NZ2(NZ1(null))) throw AssertionError() + if (NZ2(NZ1(Z(1))) != NZ2(NZ1(Z(1)))) throw AssertionError() + if (NZ2(NZ1(null)) == NZ2(NZ1(Z(1)))) throw AssertionError() + if (NZ2(NZ1(Z(1))) == NZ2(NZ1(null))) throw AssertionError() + + return "OK" +} diff --git a/compiler/testData/codegen/box/unsignedTypes/literalEqualsNullableUnsigned.kt b/compiler/testData/codegen/box/unsignedTypes/literalEqualsNullableUnsigned.kt new file mode 100644 index 00000000000..3e9b2775d88 --- /dev/null +++ b/compiler/testData/codegen/box/unsignedTypes/literalEqualsNullableUnsigned.kt @@ -0,0 +1,17 @@ +// WITH_UNSIGNED +// IGNORE_BACKEND: JVM_IR + +fun isZeroUInt(n: UInt?) = 0U == n +fun isZeroULong(n: ULong?) = 0UL == n + +fun box(): String { + if (isZeroUInt(null)) throw AssertionError() + if (isZeroUInt(1U)) throw AssertionError() + if (!isZeroUInt(0U)) throw AssertionError() + + if (isZeroULong(null)) throw AssertionError() + if (isZeroULong(1UL)) throw AssertionError() + if (!isZeroULong(0UL)) throw AssertionError() + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/unsignedTypes/nullableUnsignedEqualsLiteral.kt b/compiler/testData/codegen/box/unsignedTypes/nullableUnsignedEqualsLiteral.kt new file mode 100644 index 00000000000..6fd91aa8668 --- /dev/null +++ b/compiler/testData/codegen/box/unsignedTypes/nullableUnsignedEqualsLiteral.kt @@ -0,0 +1,17 @@ +// WITH_UNSIGNED +// IGNORE_BACKEND: JVM_IR + +fun isZeroUInt(n: UInt?) = n == 0U +fun isZeroULong(n: ULong?) = n == 0UL + +fun box(): String { + if (isZeroUInt(null)) throw AssertionError() + if (isZeroUInt(1U)) throw AssertionError() + if (!isZeroUInt(0U)) throw AssertionError() + + if (isZeroULong(null)) throw AssertionError() + if (isZeroULong(1UL)) throw AssertionError() + if (!isZeroULong(0UL)) throw AssertionError() + + return "OK" +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 8cc9bdcef8c..bd0180fe5fb 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -23882,6 +23882,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/unsignedTypes/checkBasicUnsignedLiterals.kt"); } + @TestMetadata("equalsImplForInlineClassWrappingNullableInlineClass.kt") + public void testEqualsImplForInlineClassWrappingNullableInlineClass() throws Exception { + runTest("compiler/testData/codegen/box/unsignedTypes/equalsImplForInlineClassWrappingNullableInlineClass.kt"); + } + @TestMetadata("evaluateConstructorOfUnsignedType.kt") public void testEvaluateConstructorOfUnsignedType() throws Exception { runTest("compiler/testData/codegen/box/unsignedTypes/evaluateConstructorOfUnsignedType.kt"); @@ -23907,6 +23912,16 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/unsignedTypes/kt25784.kt"); } + @TestMetadata("literalEqualsNullableUnsigned.kt") + public void testLiteralEqualsNullableUnsigned() throws Exception { + runTest("compiler/testData/codegen/box/unsignedTypes/literalEqualsNullableUnsigned.kt"); + } + + @TestMetadata("nullableUnsignedEqualsLiteral.kt") + public void testNullableUnsignedEqualsLiteral() throws Exception { + runTest("compiler/testData/codegen/box/unsignedTypes/nullableUnsignedEqualsLiteral.kt"); + } + @TestMetadata("signedToUnsignedLiteralConversion.kt") public void testSignedToUnsignedLiteralConversion() throws Exception { runTest("compiler/testData/codegen/box/unsignedTypes/signedToUnsignedLiteralConversion.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 4783c69bcc3..03165328fce 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -23882,6 +23882,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/unsignedTypes/checkBasicUnsignedLiterals.kt"); } + @TestMetadata("equalsImplForInlineClassWrappingNullableInlineClass.kt") + public void testEqualsImplForInlineClassWrappingNullableInlineClass() throws Exception { + runTest("compiler/testData/codegen/box/unsignedTypes/equalsImplForInlineClassWrappingNullableInlineClass.kt"); + } + @TestMetadata("evaluateConstructorOfUnsignedType.kt") public void testEvaluateConstructorOfUnsignedType() throws Exception { runTest("compiler/testData/codegen/box/unsignedTypes/evaluateConstructorOfUnsignedType.kt"); @@ -23907,6 +23912,16 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/unsignedTypes/kt25784.kt"); } + @TestMetadata("literalEqualsNullableUnsigned.kt") + public void testLiteralEqualsNullableUnsigned() throws Exception { + runTest("compiler/testData/codegen/box/unsignedTypes/literalEqualsNullableUnsigned.kt"); + } + + @TestMetadata("nullableUnsignedEqualsLiteral.kt") + public void testNullableUnsignedEqualsLiteral() throws Exception { + runTest("compiler/testData/codegen/box/unsignedTypes/nullableUnsignedEqualsLiteral.kt"); + } + @TestMetadata("signedToUnsignedLiteralConversion.kt") public void testSignedToUnsignedLiteralConversion() throws Exception { runTest("compiler/testData/codegen/box/unsignedTypes/signedToUnsignedLiteralConversion.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 7788a048ec1..96479727422 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -23887,6 +23887,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/unsignedTypes/checkBasicUnsignedLiterals.kt"); } + @TestMetadata("equalsImplForInlineClassWrappingNullableInlineClass.kt") + public void testEqualsImplForInlineClassWrappingNullableInlineClass() throws Exception { + runTest("compiler/testData/codegen/box/unsignedTypes/equalsImplForInlineClassWrappingNullableInlineClass.kt"); + } + @TestMetadata("evaluateConstructorOfUnsignedType.kt") public void testEvaluateConstructorOfUnsignedType() throws Exception { runTest("compiler/testData/codegen/box/unsignedTypes/evaluateConstructorOfUnsignedType.kt"); @@ -23912,6 +23917,16 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/unsignedTypes/kt25784.kt"); } + @TestMetadata("literalEqualsNullableUnsigned.kt") + public void testLiteralEqualsNullableUnsigned() throws Exception { + runTest("compiler/testData/codegen/box/unsignedTypes/literalEqualsNullableUnsigned.kt"); + } + + @TestMetadata("nullableUnsignedEqualsLiteral.kt") + public void testNullableUnsignedEqualsLiteral() throws Exception { + runTest("compiler/testData/codegen/box/unsignedTypes/nullableUnsignedEqualsLiteral.kt"); + } + @TestMetadata("signedToUnsignedLiteralConversion.kt") public void testSignedToUnsignedLiteralConversion() throws Exception { runTest("compiler/testData/codegen/box/unsignedTypes/signedToUnsignedLiteralConversion.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrJsCodegenBoxTestGenerated.java index c0901345f1b..69546412a10 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrJsCodegenBoxTestGenerated.java @@ -21047,6 +21047,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/unsignedTypes/checkBasicUnsignedLiterals.kt"); } + @TestMetadata("equalsImplForInlineClassWrappingNullableInlineClass.kt") + public void testEqualsImplForInlineClassWrappingNullableInlineClass() throws Exception { + runTest("compiler/testData/codegen/box/unsignedTypes/equalsImplForInlineClassWrappingNullableInlineClass.kt"); + } + @TestMetadata("forEachIndexedInListOfUInts.kt") public void testForEachIndexedInListOfUInts() throws Exception { runTest("compiler/testData/codegen/box/unsignedTypes/forEachIndexedInListOfUInts.kt"); @@ -21067,6 +21072,16 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/unsignedTypes/kt25784.kt"); } + @TestMetadata("literalEqualsNullableUnsigned.kt") + public void testLiteralEqualsNullableUnsigned() throws Exception { + runTest("compiler/testData/codegen/box/unsignedTypes/literalEqualsNullableUnsigned.kt"); + } + + @TestMetadata("nullableUnsignedEqualsLiteral.kt") + public void testNullableUnsignedEqualsLiteral() throws Exception { + runTest("compiler/testData/codegen/box/unsignedTypes/nullableUnsignedEqualsLiteral.kt"); + } + @TestMetadata("signedToUnsignedLiteralConversion.kt") public void testSignedToUnsignedLiteralConversion() throws Exception { runTest("compiler/testData/codegen/box/unsignedTypes/signedToUnsignedLiteralConversion.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index dab0a5233ed..64d588900f5 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -22092,6 +22092,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/unsignedTypes/checkBasicUnsignedLiterals.kt"); } + @TestMetadata("equalsImplForInlineClassWrappingNullableInlineClass.kt") + public void testEqualsImplForInlineClassWrappingNullableInlineClass() throws Exception { + runTest("compiler/testData/codegen/box/unsignedTypes/equalsImplForInlineClassWrappingNullableInlineClass.kt"); + } + @TestMetadata("forEachIndexedInListOfUInts.kt") public void testForEachIndexedInListOfUInts() throws Exception { runTest("compiler/testData/codegen/box/unsignedTypes/forEachIndexedInListOfUInts.kt"); @@ -22112,6 +22117,16 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/unsignedTypes/kt25784.kt"); } + @TestMetadata("literalEqualsNullableUnsigned.kt") + public void testLiteralEqualsNullableUnsigned() throws Exception { + runTest("compiler/testData/codegen/box/unsignedTypes/literalEqualsNullableUnsigned.kt"); + } + + @TestMetadata("nullableUnsignedEqualsLiteral.kt") + public void testNullableUnsignedEqualsLiteral() throws Exception { + runTest("compiler/testData/codegen/box/unsignedTypes/nullableUnsignedEqualsLiteral.kt"); + } + @TestMetadata("signedToUnsignedLiteralConversion.kt") public void testSignedToUnsignedLiteralConversion() throws Exception { runTest("compiler/testData/codegen/box/unsignedTypes/signedToUnsignedLiteralConversion.kt");