diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index 772c19d2e43..a65dae20577 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -99,6 +99,7 @@ import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.*; import static org.jetbrains.kotlin.resolve.BindingContext.*; import static org.jetbrains.kotlin.resolve.BindingContextUtils.getDelegationConstructorCall; import static org.jetbrains.kotlin.resolve.BindingContextUtils.isVarCapturedInClosure; +import static org.jetbrains.kotlin.resolve.DescriptorUtils.isEnumClass; import static org.jetbrains.kotlin.resolve.DescriptorUtils.isEnumEntry; import static org.jetbrains.kotlin.resolve.DescriptorUtils.isObject; import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.*; @@ -3107,6 +3108,18 @@ public class ExpressionCodegen extends KtVisitor impleme ); } + if ((opToken == KtTokens.EQEQ || opToken == KtTokens.EXCLEQ) && + (isEnumClass(bindingContext.getType(left).getConstructor().getDeclarationDescriptor()) || + isEnumClass(bindingContext.getType(right).getConstructor().getDeclarationDescriptor()))) { + // Reference equality can be used for enums. + return StackValue.cmp( + opToken == KtTokens.EQEQ ? KtTokens.EQEQEQ : KtTokens.EXCLEQEQEQ, + OBJECT_TYPE, + genLazyUnlessProvided(pregeneratedLeft, left, leftType), + genLazy(right, rightType) + ); + } + return genEqualsForExpressionsPreferIEEE754Arithmetic(left, right, opToken, leftType, rightType, pregeneratedLeft); } diff --git a/compiler/testData/codegen/box/enum/kt18731.kt b/compiler/testData/codegen/box/enum/kt18731.kt new file mode 100644 index 00000000000..bc98fc4c1b8 --- /dev/null +++ b/compiler/testData/codegen/box/enum/kt18731.kt @@ -0,0 +1,13 @@ +enum class Bar { + ONE, + TWO +} + +fun isOne(i: Bar) = i == Bar.ONE + +fun box(): String { + return when (isOne(Bar.ONE) && !isOne(Bar.TWO)) { + true -> "OK" + else -> "Failure" + } +} diff --git a/compiler/testData/codegen/bytecodeText/enum/kt18731.kt b/compiler/testData/codegen/bytecodeText/enum/kt18731.kt new file mode 100644 index 00000000000..55c1ee8df8d --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/enum/kt18731.kt @@ -0,0 +1,16 @@ +enum class Bar { + ONE, + TWO +} + +fun isOne(i: Bar) = i == Bar.ONE + +fun box(): String { + return when (isOne(Bar.ONE) && !isOne(Bar.TWO)) { + true -> "OK" + else -> "Failure" + } +} + +// 1 IF_ACMPNE +// 0 INVOKESTATIC kotlin/jvm/internal/Intrinsics.areEqual \(Ljava/lang/Object;Ljava/lang/Object;\)Z \ No newline at end of file diff --git a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 66ff4568e53..a0b7a0fbafc 100644 --- a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -8541,6 +8541,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes doTest(fileName); } + @TestMetadata("kt18731.kt") + public void testKt18731() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/enum/kt18731.kt"); + doTest(fileName); + } + @TestMetadata("kt20651.kt") public void testKt20651() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/enum/kt20651.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 33971fbbdef..92a45089ff0 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -8541,6 +8541,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("kt18731.kt") + public void testKt18731() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/enum/kt18731.kt"); + doTest(fileName); + } + @TestMetadata("kt20651.kt") public void testKt20651() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/enum/kt20651.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java index dd799178584..76d81f03bd6 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java @@ -1270,6 +1270,21 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest { } } + @TestMetadata("compiler/testData/codegen/bytecodeText/enum") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Enum extends AbstractBytecodeTextTest { + public void testAllFilesPresentInEnum() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/bytecodeText/enum"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); + } + + @TestMetadata("kt18731.kt") + public void testKt18731() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/enum/kt18731.kt"); + doTest(fileName); + } + } + @TestMetadata("compiler/testData/codegen/bytecodeText/forLoop") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index f81517f3169..e09b33dcce4 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -8541,6 +8541,12 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes doTest(fileName); } + @TestMetadata("kt18731.kt") + public void testKt18731() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/enum/kt18731.kt"); + doTest(fileName); + } + @TestMetadata("kt20651.kt") public void testKt20651() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/enum/kt20651.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 c1cf221094d..6903a16a80e 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 @@ -9225,6 +9225,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { doTest(fileName); } + @TestMetadata("kt18731.kt") + public void testKt18731() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/enum/kt18731.kt"); + doTest(fileName); + } + @TestMetadata("kt20651.kt") public void testKt20651() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/enum/kt20651.kt");