diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/PrimitiveNumberRangeIntrinsicRangeValue.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/PrimitiveNumberRangeIntrinsicRangeValue.kt index 38a9774293a..cc93c3c4f5c 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/PrimitiveNumberRangeIntrinsicRangeValue.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/PrimitiveNumberRangeIntrinsicRangeValue.kt @@ -47,7 +47,8 @@ abstract class PrimitiveNumberRangeIntrinsicRangeValue( resolvedCallForIn.resultingDescriptor.let { isPrimitiveRangeContains(it) || isClosedFloatingPointRangeContains(it) || - isPrimitiveNumberRangeExtensionContainsPrimitiveNumber(it) + isPrimitiveNumberRangeExtensionContainsPrimitiveNumber(it) || + isUnsignedIntegerRangeContains(it) } override fun createIntrinsicInExpressionGenerator( diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/RangeCodegenUtil.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/RangeCodegenUtil.kt index 9c3721608bf..272ec7c410b 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/RangeCodegenUtil.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/RangeCodegenUtil.kt @@ -224,6 +224,14 @@ fun isPrimitiveRangeContains(descriptor: CallableDescriptor): Boolean { return true } +fun isUnsignedIntegerRangeContains(descriptor: CallableDescriptor): Boolean { + if (descriptor.name.asString() != "contains") return false + val dispatchReceiverType = descriptor.dispatchReceiverParameter?.type ?: return false + if (!isUnsignedRange(dispatchReceiverType)) return false + + return true +} + fun isPrimitiveNumberRangeExtensionContainsPrimitiveNumber(descriptor: CallableDescriptor): Boolean { if (descriptor.name.asString() != "contains") return false diff --git a/compiler/testData/codegen/box/unsignedTypes/inUnsignedDownTo.kt b/compiler/testData/codegen/box/unsignedTypes/inUnsignedDownTo.kt new file mode 100644 index 00000000000..49969a3193c --- /dev/null +++ b/compiler/testData/codegen/box/unsignedTypes/inUnsignedDownTo.kt @@ -0,0 +1,31 @@ +// IGNORE_BACKEND: JVM_IR, JS_IR +// WITH_RUNTIME + +const val MaxUI = UInt.MAX_VALUE +const val MinUI = UInt.MIN_VALUE + +val M1 = MaxUI.toULong() +val M2 = M1 + 10UL + +fun box(): String { + if (0u in 10u downTo 1u) throw AssertionError() + if (1u !in 10u downTo 1u) throw AssertionError() + if (5u !in 10u downTo 1u) throw AssertionError() + if (10u !in 10u downTo 1u) throw AssertionError() + if (20u in 10u downTo 1u) throw AssertionError() + + if (0UL in 10UL downTo 1UL) throw AssertionError() + if (1UL !in 10UL downTo 1UL) throw AssertionError() + if (5UL !in 10UL downTo 1UL) throw AssertionError() + if (10UL !in 10UL downTo 1UL) throw AssertionError() + if (20UL in 10UL downTo 1UL) throw AssertionError() + + if (0UL in M2 downTo M1) throw AssertionError() + if (1UL in M2 downTo M1) throw AssertionError() + if (10UL in M2 downTo M1) throw AssertionError() + if (M1 !in M2 downTo M1) throw AssertionError() + if (M1+1UL !in M2 downTo M1) throw AssertionError() + if (M2 !in M2 downTo M1) throw AssertionError() + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/unsignedTypes/inUnsignedRange.kt b/compiler/testData/codegen/box/unsignedTypes/inUnsignedRange.kt new file mode 100644 index 00000000000..d5061d0345e --- /dev/null +++ b/compiler/testData/codegen/box/unsignedTypes/inUnsignedRange.kt @@ -0,0 +1,48 @@ +// IGNORE_BACKEND: JVM_IR +// WITH_RUNTIME + +const val MaxUI = UInt.MAX_VALUE +const val MinUI = UInt.MIN_VALUE + +const val MaxUL = ULong.MAX_VALUE +const val MinUL = ULong.MIN_VALUE + +val M1 = MaxUI.toULong() +val M2 = M1 + 10UL + +val u_1_10 = 1u .. 10u +val ul_1_10 = 1UL..10UL +val minUI_maxUI = MinUI..MaxUI +val minUL_maxUL = MinUL..MaxUL +val m1_m2 = M1..M2 + +fun box(): String { + if (0u in u_1_10) throw AssertionError() + if (1u !in u_1_10) throw AssertionError() + if (5u !in u_1_10) throw AssertionError() + if (10u !in u_1_10) throw AssertionError() + if (20u in u_1_10) throw AssertionError() + + if (0UL in ul_1_10) throw AssertionError() + if (1UL !in ul_1_10) throw AssertionError() + if (5UL !in ul_1_10) throw AssertionError() + if (10UL !in ul_1_10) throw AssertionError() + if (20UL in ul_1_10) throw AssertionError() + + if (0u !in minUI_maxUI) throw AssertionError() + if (MinUI !in minUI_maxUI) throw AssertionError() + if (MaxUI !in minUI_maxUI) throw AssertionError() + + if (0UL !in minUL_maxUL) throw AssertionError() + if (MinUL !in minUL_maxUL) throw AssertionError() + if (MaxUL !in minUL_maxUL) throw AssertionError() + + if (0UL in m1_m2) throw AssertionError() + if (1UL in m1_m2) throw AssertionError() + if (10UL in m1_m2) throw AssertionError() + if (M1 !in m1_m2) throw AssertionError() + if (M1+1UL !in m1_m2) throw AssertionError() + if (M2 !in m1_m2) throw AssertionError() + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/unsignedTypes/inUnsignedUntil.kt b/compiler/testData/codegen/box/unsignedTypes/inUnsignedUntil.kt new file mode 100644 index 00000000000..b4a2657f9d7 --- /dev/null +++ b/compiler/testData/codegen/box/unsignedTypes/inUnsignedUntil.kt @@ -0,0 +1,42 @@ +// IGNORE_BACKEND: JVM_IR +// WITH_RUNTIME + +const val MaxUI = UInt.MAX_VALUE +const val MinUI = UInt.MIN_VALUE + +const val MaxUL = ULong.MAX_VALUE +const val MinUL = ULong.MIN_VALUE + +val M1 = MaxUI.toULong() +val M2 = M1 + 10UL + +fun box(): String { + if (0u in 1u until 10u) throw AssertionError() + if (1u !in 1u until 10u) throw AssertionError() + if (5u !in 1u until 10u) throw AssertionError() + if (10u in 1u until 10u) throw AssertionError() + if (20u in 1u until 10u) throw AssertionError() + + if (0UL in 1UL until 10UL) throw AssertionError() + if (1UL !in 1UL until 10UL) throw AssertionError() + if (5UL !in 1UL until 10UL) throw AssertionError() + if (10UL in 1UL until 10UL) throw AssertionError() + if (20UL in 1UL until 10UL) throw AssertionError() + + if (0u !in MinUI until MaxUI) throw AssertionError() + if (MinUI !in MinUI until MaxUI) throw AssertionError() + if (MaxUI in MinUI until MaxUI) throw AssertionError() + + if (0UL !in MinUL until MaxUL) throw AssertionError() + if (MinUL !in MinUL until MaxUL) throw AssertionError() + if (MaxUL in MinUL until MaxUL) throw AssertionError() + + if (0UL in M1 until M2) throw AssertionError() + if (1UL in M1 until M2) throw AssertionError() + if (10UL in M1 until M2) throw AssertionError() + if (M1 !in M1 until M2) throw AssertionError() + if (M1+1UL !in M1 until M2) throw AssertionError() + if (M2 in M1 until M2) throw AssertionError() + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/ranges/inOptimizableUnsignedRange.kt b/compiler/testData/codegen/bytecodeText/ranges/inOptimizableUnsignedRange.kt new file mode 100644 index 00000000000..fed885e8c8c --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/ranges/inOptimizableUnsignedRange.kt @@ -0,0 +1,11 @@ +// IGNORE_BACKEND: JVM_IR + +fun testUIntRangeLiteral(a: UInt, b: UInt) = 42u in a .. b + +fun testULongRangeLiteral(a: ULong, b: ULong) = 42UL in a .. b + +fun testUIntUntil(a: UInt, b: UInt) = 42u in a until b + +fun testULongUntil(a: ULong, b: ULong) = 42UL in a until b + +// 0 contains diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 0c1dd7f03ac..348aa59e61b 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -24218,11 +24218,26 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/unsignedTypes/forInUnsignedUntil.kt"); } + @TestMetadata("inUnsignedDownTo.kt") + public void testInUnsignedDownTo() throws Exception { + runTest("compiler/testData/codegen/box/unsignedTypes/inUnsignedDownTo.kt"); + } + + @TestMetadata("inUnsignedRange.kt") + public void testInUnsignedRange() throws Exception { + runTest("compiler/testData/codegen/box/unsignedTypes/inUnsignedRange.kt"); + } + @TestMetadata("inUnsignedRangeLiteral.kt") public void testInUnsignedRangeLiteral() throws Exception { runTest("compiler/testData/codegen/box/unsignedTypes/inUnsignedRangeLiteral.kt"); } + @TestMetadata("inUnsignedUntil.kt") + public void testInUnsignedUntil() throws Exception { + runTest("compiler/testData/codegen/box/unsignedTypes/inUnsignedUntil.kt"); + } + @TestMetadata("iterateOverArrayOfUnsignedValues.kt") public void testIterateOverArrayOfUnsignedValues() throws Exception { runTest("compiler/testData/codegen/box/unsignedTypes/iterateOverArrayOfUnsignedValues.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java index 7cc45e9a5e2..95ff1ce77e4 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java @@ -2885,6 +2885,11 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest { runTest("compiler/testData/codegen/bytecodeText/ranges/inOptimizableRange.kt"); } + @TestMetadata("inOptimizableUnsignedRange.kt") + public void testInOptimizableUnsignedRange() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/ranges/inOptimizableUnsignedRange.kt"); + } + @TestMetadata("inUntil.kt") public void testInUntil() throws Exception { runTest("compiler/testData/codegen/bytecodeText/ranges/inUntil.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/IrBytecodeTextTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/IrBytecodeTextTestGenerated.java index bdd94ec2b5c..c47c717cf1a 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/IrBytecodeTextTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/IrBytecodeTextTestGenerated.java @@ -2885,6 +2885,11 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest { runTest("compiler/testData/codegen/bytecodeText/ranges/inOptimizableRange.kt"); } + @TestMetadata("inOptimizableUnsignedRange.kt") + public void testInOptimizableUnsignedRange() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/ranges/inOptimizableUnsignedRange.kt"); + } + @TestMetadata("inUntil.kt") public void testInUntil() throws Exception { runTest("compiler/testData/codegen/bytecodeText/ranges/inUntil.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index c5134f91c15..4094ee4e413 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -24218,11 +24218,26 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/unsignedTypes/forInUnsignedUntil.kt"); } + @TestMetadata("inUnsignedDownTo.kt") + public void testInUnsignedDownTo() throws Exception { + runTest("compiler/testData/codegen/box/unsignedTypes/inUnsignedDownTo.kt"); + } + + @TestMetadata("inUnsignedRange.kt") + public void testInUnsignedRange() throws Exception { + runTest("compiler/testData/codegen/box/unsignedTypes/inUnsignedRange.kt"); + } + @TestMetadata("inUnsignedRangeLiteral.kt") public void testInUnsignedRangeLiteral() throws Exception { runTest("compiler/testData/codegen/box/unsignedTypes/inUnsignedRangeLiteral.kt"); } + @TestMetadata("inUnsignedUntil.kt") + public void testInUnsignedUntil() throws Exception { + runTest("compiler/testData/codegen/box/unsignedTypes/inUnsignedUntil.kt"); + } + @TestMetadata("iterateOverArrayOfUnsignedValues.kt") public void testIterateOverArrayOfUnsignedValues() throws Exception { runTest("compiler/testData/codegen/box/unsignedTypes/iterateOverArrayOfUnsignedValues.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index f173655d8a2..b70a5465cb6 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -24223,11 +24223,26 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/unsignedTypes/forInUnsignedUntil.kt"); } + @TestMetadata("inUnsignedDownTo.kt") + public void testInUnsignedDownTo() throws Exception { + runTest("compiler/testData/codegen/box/unsignedTypes/inUnsignedDownTo.kt"); + } + + @TestMetadata("inUnsignedRange.kt") + public void testInUnsignedRange() throws Exception { + runTest("compiler/testData/codegen/box/unsignedTypes/inUnsignedRange.kt"); + } + @TestMetadata("inUnsignedRangeLiteral.kt") public void testInUnsignedRangeLiteral() throws Exception { runTest("compiler/testData/codegen/box/unsignedTypes/inUnsignedRangeLiteral.kt"); } + @TestMetadata("inUnsignedUntil.kt") + public void testInUnsignedUntil() throws Exception { + runTest("compiler/testData/codegen/box/unsignedTypes/inUnsignedUntil.kt"); + } + @TestMetadata("iterateOverArrayOfUnsignedValues.kt") public void testIterateOverArrayOfUnsignedValues() throws Exception { runTest("compiler/testData/codegen/box/unsignedTypes/iterateOverArrayOfUnsignedValues.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 b41bedb4304..8a3c376756d 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 @@ -18668,11 +18668,26 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/unsignedTypes/forInUnsignedUntil.kt"); } + @TestMetadata("inUnsignedDownTo.kt") + public void testInUnsignedDownTo() throws Exception { + runTest("compiler/testData/codegen/box/unsignedTypes/inUnsignedDownTo.kt"); + } + + @TestMetadata("inUnsignedRange.kt") + public void testInUnsignedRange() throws Exception { + runTest("compiler/testData/codegen/box/unsignedTypes/inUnsignedRange.kt"); + } + @TestMetadata("inUnsignedRangeLiteral.kt") public void testInUnsignedRangeLiteral() throws Exception { runTest("compiler/testData/codegen/box/unsignedTypes/inUnsignedRangeLiteral.kt"); } + @TestMetadata("inUnsignedUntil.kt") + public void testInUnsignedUntil() throws Exception { + runTest("compiler/testData/codegen/box/unsignedTypes/inUnsignedUntil.kt"); + } + @TestMetadata("iterateOverArrayOfUnsignedValues.kt") public void testIterateOverArrayOfUnsignedValues() throws Exception { runTest("compiler/testData/codegen/box/unsignedTypes/iterateOverArrayOfUnsignedValues.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 c3b7adb6690..bfd7cd9f93c 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 @@ -19718,11 +19718,26 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/unsignedTypes/forInUnsignedUntil.kt"); } + @TestMetadata("inUnsignedDownTo.kt") + public void testInUnsignedDownTo() throws Exception { + runTest("compiler/testData/codegen/box/unsignedTypes/inUnsignedDownTo.kt"); + } + + @TestMetadata("inUnsignedRange.kt") + public void testInUnsignedRange() throws Exception { + runTest("compiler/testData/codegen/box/unsignedTypes/inUnsignedRange.kt"); + } + @TestMetadata("inUnsignedRangeLiteral.kt") public void testInUnsignedRangeLiteral() throws Exception { runTest("compiler/testData/codegen/box/unsignedTypes/inUnsignedRangeLiteral.kt"); } + @TestMetadata("inUnsignedUntil.kt") + public void testInUnsignedUntil() throws Exception { + runTest("compiler/testData/codegen/box/unsignedTypes/inUnsignedUntil.kt"); + } + @TestMetadata("iterateOverArrayOfUnsignedValues.kt") public void testIterateOverArrayOfUnsignedValues() throws Exception { runTest("compiler/testData/codegen/box/unsignedTypes/iterateOverArrayOfUnsignedValues.kt");