diff --git a/libraries/stdlib/common/src/generated/_Arrays.kt b/libraries/stdlib/common/src/generated/_Arrays.kt index 3a657da6e20..c31ebe82215 100644 --- a/libraries/stdlib/common/src/generated/_Arrays.kt +++ b/libraries/stdlib/common/src/generated/_Arrays.kt @@ -550,6 +550,8 @@ public operator fun LongArray.contains(element: Long): Boolean { /** * Returns `true` if [element] is found in the array. */ +@Deprecated("The function has unclear behavior when searching for NaN or zero values and will be removed soon. Use 'any { it == element }' instead to continue using this behavior, or '.asList().contains(element: T)' to get the same search behavior as in a list.", ReplaceWith("any { it == element }")) +@Suppress("DEPRECATION") public operator fun FloatArray.contains(element: Float): Boolean { return indexOf(element) >= 0 } @@ -557,6 +559,8 @@ public operator fun FloatArray.contains(element: Float): Boolean { /** * Returns `true` if [element] is found in the array. */ +@Deprecated("The function has unclear behavior when searching for NaN or zero values and will be removed soon. Use 'any { it == element }' instead to continue using this behavior, or '.asList().contains(element: T)' to get the same search behavior as in a list.", ReplaceWith("any { it == element }")) +@Suppress("DEPRECATION") public operator fun DoubleArray.contains(element: Double): Boolean { return indexOf(element) >= 0 } @@ -1474,6 +1478,7 @@ public fun LongArray.indexOf(element: Long): Int { /** * Returns first index of [element], or -1 if the array does not contain element. */ +@Deprecated("The function has unclear behavior when searching for NaN or zero values and will be removed soon. Use 'indexOfFirst { it == element }' instead to continue using this behavior, or '.asList().indexOf(element: T)' to get the same search behavior as in a list.", ReplaceWith("indexOfFirst { it == element }")) public fun FloatArray.indexOf(element: Float): Int { for (index in indices) { if (element == this[index]) { @@ -1486,6 +1491,7 @@ public fun FloatArray.indexOf(element: Float): Int { /** * Returns first index of [element], or -1 if the array does not contain element. */ +@Deprecated("The function has unclear behavior when searching for NaN or zero values and will be removed soon. Use 'indexOfFirst { it == element }' instead to continue using this behavior, or '.asList().indexOf(element: T)' to get the same search behavior as in a list.", ReplaceWith("indexOfFirst { it == element }")) public fun DoubleArray.indexOf(element: Double): Int { for (index in indices) { if (element == this[index]) { @@ -2004,6 +2010,7 @@ public fun LongArray.lastIndexOf(element: Long): Int { /** * Returns last index of [element], or -1 if the array does not contain element. */ +@Deprecated("The function has unclear behavior when searching for NaN or zero values and will be removed soon. Use 'indexOfLast { it == element }' instead to continue using this behavior, or '.asList().lastIndexOf(element: T)' to get the same search behavior as in a list.", ReplaceWith("indexOfLast { it == element }")) public fun FloatArray.lastIndexOf(element: Float): Int { for (index in indices.reversed()) { if (element == this[index]) { @@ -2016,6 +2023,7 @@ public fun FloatArray.lastIndexOf(element: Float): Int { /** * Returns last index of [element], or -1 if the array does not contain element. */ +@Deprecated("The function has unclear behavior when searching for NaN or zero values and will be removed soon. Use 'indexOfLast { it == element }' instead to continue using this behavior, or '.asList().lastIndexOf(element: T)' to get the same search behavior as in a list.", ReplaceWith("indexOfLast { it == element }")) public fun DoubleArray.lastIndexOf(element: Double): Int { for (index in indices.reversed()) { if (element == this[index]) { diff --git a/libraries/stdlib/test/collections/ArraysTest.kt b/libraries/stdlib/test/collections/ArraysTest.kt index ff6b4aca7da..8e5ce863333 100644 --- a/libraries/stdlib/test/collections/ArraysTest.kt +++ b/libraries/stdlib/test/collections/ArraysTest.kt @@ -12,7 +12,6 @@ import test.assertTypeEquals import test.collections.behaviors.* import test.comparisons.STRING_CASE_INSENSITIVE_ORDER import test.text.isAsciiLetter -import kotlin.math.exp import kotlin.test.* import kotlin.random.Random @@ -503,6 +502,7 @@ class ArraysTest { // for each arr with size > 0 arr.average() = arr.sum().toDouble() / arr.size() } + @Suppress("DEPRECATION") @Test fun indexOfInPrimitiveArrays() { expect(-1) { byteArrayOf(1, 2, 3).indexOf(0) } expect(0) { byteArrayOf(1, 2, 3).indexOf(1) } diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Elements.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Elements.kt index ca239d8f3d0..a1ddcd96f39 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Elements.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Elements.kt @@ -27,6 +27,10 @@ object Elements : TemplateGroupBase() { } } + private fun floatingSearchDeprecationMessage(signature: String, replacement: String): String { + return "The function has unclear behavior when searching for NaN or zero values and will be removed soon. Use '$replacement' instead to continue using this behavior, or '.asList().$signature' to get the same search behavior as in a list." + } + val f_contains = fn("contains(element: T)") { include(Iterables, Sequences, ArraysOfObjects, ArraysOfPrimitives) } builder { @@ -34,12 +38,17 @@ object Elements : TemplateGroupBase() { doc { "Returns `true` if [element] is found in the ${f.collection}." } typeParam("@kotlin.internal.OnlyInputTypes T") + if (f == ArraysOfPrimitives && primitive!!.isFloatingPoint()) { + val replacement = "any { it == element }" + deprecate(Deprecation(floatingSearchDeprecationMessage(signature, replacement), replacement, DeprecationLevel.WARNING)) + annotation("""@Suppress("DEPRECATION")""") + } returns("Boolean") body(Iterables) { """ - if (this is Collection) - return contains(element) - return indexOf(element) >= 0 + if (this is Collection) + return contains(element) + return indexOf(element) >= 0 """ } body(ArraysOfPrimitives, ArraysOfObjects, Sequences) { @@ -57,6 +66,10 @@ object Elements : TemplateGroupBase() { specialFor(Lists) { annotation("""@Suppress("EXTENSION_SHADOWED_BY_MEMBER") // false warning, extension takes precedence in some cases""") } + if (f == ArraysOfPrimitives && primitive!!.isFloatingPoint()) { + val replacement = "indexOfFirst { it == element }" + deprecate(Deprecation(floatingSearchDeprecationMessage(signature, replacement), replacement, DeprecationLevel.WARNING)) + } returns("Int") body { """ @@ -117,6 +130,10 @@ object Elements : TemplateGroupBase() { specialFor(Lists) { annotation("""@Suppress("EXTENSION_SHADOWED_BY_MEMBER") // false warning, extension takes precedence in some cases""") } + if (f == ArraysOfPrimitives && primitive!!.isFloatingPoint()) { + val replacement = "indexOfLast { it == element }" + deprecate(Deprecation(floatingSearchDeprecationMessage(signature, replacement), replacement, DeprecationLevel.WARNING)) + } returns("Int") body { """