Finally we’re updating a larger codebase to Scala 2.13 and 3. It used a lot of arrays for performance and interop reasons and passed them to methods needing Seq and IndexedSeq. This results in a lot of (deserved) deprecation warnings.
Implicit conversions from Array to immutable.IndexedSeq are implemented
by copying; Use the more efficient non-copying ArraySeq.unsafeWrapArray or an
explicit toIndexedSeq call
I looked at them all and most if not all should be rewritten to ArraySeq.unsafeWrapArray(array). I can add an implicit method so that array.toWrapped performs the conversion (by analogy to array.toIndexedSeq) with this code:
object WrappedArray {
implicit def toWrapped[T: _root_.scala.reflect.ClassTag](array: Array[T]): _root_.scala.collection.immutable.IndexedSeq[T] =
_root_.scala.collection.immutable.ArraySeq.unsafeWrapArray(array)
}
However, I would much prefer not to edit multiple lines in each file, turning array into array.toWrapped each time, but simply add an import to the top of each file in order to override the implicit toIndexedSeq conversion. Anything I’ve come up with so far either doesn’t see my conversion or results in something like
Note that implicit conversions are not applicable because they are ambiguous:
both method copyArrayToImmutableIndexedSeq in class LowPriorityImplicits2 of type [T](xs: Array[T]): IndexedSeq[T]
and method toWrappedIndexedSeq in class TestArray of type [T](array: Array[T])(implicit evidence$1: scala.reflect.ClassTag[T]): IndexedSeq[T]
are possible conversion functions from Array[Int] to Seq[Int]
val autoCopySeq1 = processSeq(array) // calls new ArrayOps(xs).toIndexedSeq
Sometimes I’ve added code like
import Predef.{copyArrayToImmutableIndexedSeq => _,_}
to attempt to reduce the ambiguity, but it doesn’t work and I’m hoping to just use a single import anyway.
The implicit conversions apparently have priorities, but so far, my import has not been able to override the Predef version and compilation always fails.
Does anyone know the correct incantation? A program like this should work correctly:
package mypackage
// This should be in a separate file and imported.
object WrappedArray {
implicit def toWrapped[T: _root_.scala.reflect.ClassTag](array: Array[T]): _root_.scala.collection.immutable.IndexedSeq[T] = {
println("I was here!")
_root_.scala.collection.immutable.ArraySeq.unsafeWrapArray(array)
}
}
object ArrayExample extends App {
def process(indexedSeq: IndexedSeq[Int]): Unit = println("It was processed.")
process(Array(1, 2,3, 4, 5))
}