[stdlib] Introduce interface to access collection toArray on non-JVM platforms
diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/collections/ArraysNative.kt b/kotlin-native/runtime/src/main/kotlin/kotlin/collections/ArraysNative.kt
index 36fca3d..2e2ea09 100644
--- a/kotlin-native/runtime/src/main/kotlin/kotlin/collections/ArraysNative.kt
+++ b/kotlin-native/runtime/src/main/kotlin/kotlin/collections/ArraysNative.kt
@@ -12,7 +12,12 @@
  * and populates the array with the elements of this collection.
  * @sample samples.collections.Collections.Collections.collectionToTypedArray
  */
-public actual inline fun <reified T> Collection<T>.toTypedArray(): Array<T> {
+public actual inline fun <reified T> Collection<T>.toTypedArray(): Array<T> = copyToTypedArray()
+
+@PublishedApi
+internal fun <T> Collection<T>.copyToTypedArray(): Array<T> {
+    @Suppress("UNCHECKED_CAST")
+    if (this is SupportsToArray) return toArray() as Array<T>
     val result = arrayOfNulls<T>(size)
     var index = 0
     for (element in this) result[index++] = element
diff --git a/libraries/stdlib/js/src/kotlin/collectionJs.kt b/libraries/stdlib/js/src/kotlin/collectionJs.kt
index 562b46d..4889381 100644
--- a/libraries/stdlib/js/src/kotlin/collectionJs.kt
+++ b/libraries/stdlib/js/src/kotlin/collectionJs.kt
@@ -29,8 +29,8 @@
 @JsName("copyToArray")
 @PublishedApi
 internal fun <T> copyToArray(collection: Collection<T>): Array<T> {
-    return if (collection.asDynamic().toArray !== undefined)
-        collection.asDynamic().toArray().unsafeCast<Array<T>>()
+    return if (collection is SupportsToArray)
+        collection.toArray().unsafeCast<Array<T>>()
     else
         collectionToArray(collection).unsafeCast<Array<T>>()
 }
diff --git a/libraries/stdlib/src/kotlin/collections/AbstractCollection.kt b/libraries/stdlib/src/kotlin/collections/AbstractCollection.kt
index 9f92754..316184b 100644
--- a/libraries/stdlib/src/kotlin/collections/AbstractCollection.kt
+++ b/libraries/stdlib/src/kotlin/collections/AbstractCollection.kt
@@ -12,7 +12,7 @@
  * @param E the type of elements contained in the collection. The collection is covariant in its element type.
  */
 @SinceKotlin("1.1")
-public abstract class AbstractCollection<out E> protected constructor() : Collection<E> {
+public abstract class AbstractCollection<out E> protected constructor() : Collection<E>, SupportsToArray {
     abstract override val size: Int
     abstract override fun iterator(): Iterator<E>
 
@@ -30,8 +30,9 @@
     /**
      * Returns new array of type `Array<Any?>` with the elements of this collection.
      */
-    @JsName("toArray")
-    protected open fun toArray(): Array<Any?> = collectionToArray(this)
+//    @JsName("toArray")
+    @Suppress("CANNOT_WEAKEN_ACCESS_PRIVILEGE")
+    protected override fun toArray(): Array<Any?> = collectionToArray(this)
 
     /**
      * Fills the provided [array] or creates new array of the same type
@@ -45,5 +46,11 @@
      *
      * @return An array containing all elements of this collection.
      */
-    protected open fun <T> toArray(array: Array<T>): Array<T> = collectionToArray(this, array)
+    @Suppress("CANNOT_WEAKEN_ACCESS_PRIVILEGE")
+    protected override fun <T> toArray(array: Array<T>): Array<T> = collectionToArray(this, array)
 }
+
+internal interface SupportsToArray {
+    fun toArray(): Array<Any?>
+    fun <T> toArray(array: Array<T>): Array<T>
+}
\ No newline at end of file
diff --git a/libraries/stdlib/wasm/src/kotlin/collections/ArraysWasm.kt b/libraries/stdlib/wasm/src/kotlin/collections/ArraysWasm.kt
index 50271fd..17652d9 100644
--- a/libraries/stdlib/wasm/src/kotlin/collections/ArraysWasm.kt
+++ b/libraries/stdlib/wasm/src/kotlin/collections/ArraysWasm.kt
@@ -18,8 +18,7 @@
 @Suppress("UNCHECKED_CAST")
 @PublishedApi
 internal fun <T> copyToArray(collection: Collection<T>): Array<T> =
-    if (collection is AbstractCollection<T>)
-        //TODO: Find more proper way to call abstract collection's toArray
-        @Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") collection.toArray() as Array<T>
+    if (collection is SupportsToArray)
+        collection.toArray() as Array<T>
     else
         collectionToArray(collection) as Array<T>
\ No newline at end of file
diff --git a/libraries/tools/binary-compatibility-validator/klib-public-api/kotlin-stdlib.api b/libraries/tools/binary-compatibility-validator/klib-public-api/kotlin-stdlib.api
index de477f3..906889b 100644
--- a/libraries/tools/binary-compatibility-validator/klib-public-api/kotlin-stdlib.api
+++ b/libraries/tools/binary-compatibility-validator/klib-public-api/kotlin-stdlib.api
@@ -1065,7 +1065,7 @@
     final object Companion // kotlin/Enum.Companion|null[0]
 }
 
-abstract class <#A: out kotlin/Any?> kotlin.collections/AbstractCollection : kotlin.collections/Collection<#A> { // kotlin.collections/AbstractCollection|null[0]
+abstract class <#A: out kotlin/Any?> kotlin.collections/AbstractCollection : kotlin.collections/Collection<#A>, kotlin.collections/SupportsToArray { // kotlin.collections/AbstractCollection|null[0]
     constructor <init>() // kotlin.collections/AbstractCollection.<init>|<init>(){}[0]
 
     abstract val size // kotlin.collections/AbstractCollection.size|{}size[0]
@@ -12273,6 +12273,9 @@
 final fun <#A: kotlin/Any?> (#A).kotlin.native.concurrent/freeze(): #A // kotlin.native.concurrent/freeze|freeze@0:0(){0§<kotlin.Any?>}[0]
 
 // Targets: [native]
+final fun <#A: kotlin/Any?> (kotlin.collections/Collection<#A>).kotlin.collections/copyToTypedArray(): kotlin/Array<#A> // kotlin.collections/copyToTypedArray|copyToTypedArray@kotlin.collections.Collection<0:0>(){0§<kotlin.Any?>}[0]
+
+// Targets: [native]
 final fun <#A: kotlin/Any?> (kotlin.collections/Collection<kotlin.native.concurrent/Future<#A>>).kotlin.native.concurrent/waitForMultipleFutures(kotlin/Int): kotlin.collections/Set<kotlin.native.concurrent/Future<#A>> // kotlin.native.concurrent/waitForMultipleFutures|waitForMultipleFutures@kotlin.collections.Collection<kotlin.native.concurrent.Future<0:0>>(kotlin.Int){0§<kotlin.Any?>}[0]
 
 // Targets: [native]
diff --git a/libraries/tools/binary-compatibility-validator/reference-public-api/kotlin-stdlib-runtime-merged.txt b/libraries/tools/binary-compatibility-validator/reference-public-api/kotlin-stdlib-runtime-merged.txt
index 36c81ca..6a3f01c 100644
--- a/libraries/tools/binary-compatibility-validator/reference-public-api/kotlin-stdlib-runtime-merged.txt
+++ b/libraries/tools/binary-compatibility-validator/reference-public-api/kotlin-stdlib-runtime-merged.txt
@@ -583,7 +583,7 @@
 	public abstract fun allowedTargets ()[Lkotlin/annotation/AnnotationTarget;
 }
 
-public abstract class kotlin/collections/AbstractCollection : java/util/Collection, kotlin/jvm/internal/markers/KMappedMarker {
+public abstract class kotlin/collections/AbstractCollection : java/util/Collection, kotlin/collections/SupportsToArray, kotlin/jvm/internal/markers/KMappedMarker {
 	protected fun <init> ()V
 	public fun add (Ljava/lang/Object;)Z
 	public fun addAll (Ljava/util/Collection;)Z