From bfc2eb620395d0576f950492598916e1eb3e409d Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Fri, 5 Dec 2025 15:29:26 +0100 Subject: [PATCH] Add implicit conversion from IArray.type to Factory old style conversion so no language import is needed. When `into` is stabilized, then possibly `Factory` can be converted to an `into` trait, and the conversion turned into the new `given Conversion` style --- library/src/scala/IArray.scala | 17 ++++++++++++++++- .../stdlibExperimentalDefinitions.scala | 3 +++ tests/run/IArrayOps-experimental-Factory.scala | 16 ++++++++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 tests/run/IArrayOps-experimental-Factory.scala diff --git a/library/src/scala/IArray.scala b/library/src/scala/IArray.scala index 58e34373c6e9..12f51f66b91f 100644 --- a/library/src/scala/IArray.scala +++ b/library/src/scala/IArray.scala @@ -3,7 +3,9 @@ import reflect.ClassTag import language.experimental.captureChecking -import scala.collection.{LazyZip2, SeqView, Searching, Stepper, StepperShape} +import scala.annotation.experimental + +import scala.collection.{LazyZip2, SeqView, Searching, Stepper, StepperShape, Factory} import scala.collection.immutable.ArraySeq import scala.collection.mutable.{ArrayBuilder, Builder} @@ -14,6 +16,19 @@ opaque type IArray[+T] = Array[? <: T] */ object IArray: + // OLD style implicit conversion so no import is needed at use-site. + // once `into` feature is made stable, we could make `Factory` an `into` trait, and + // change this to the new style `given Conversion`. + /** Provides an implicit conversion from the IArray object to a collection Factory */ + @experimental + implicit def convertIArrayToFactory[A : ClassTag](@annotation.unused asFactory: IArray.type): Factory[A, IArray[A]] = + // copied from ArrayFactory, i guess its possible to capture a factory? + @SerialVersionUID(3L) + class ConcreteIArrayFactory extends Factory[A, IArray[A]] with Serializable: + def fromSpecific(it: IterableOnce[A]^): IArray[A] = IArray.from[A](it) + def newBuilder: Builder[A, IArray[A]] = IArray.newBuilder[A] + ConcreteIArrayFactory() + /** The selection operation on an immutable array. * * @param arr the immutable array diff --git a/tests/run-tasty-inspector/stdlibExperimentalDefinitions.scala b/tests/run-tasty-inspector/stdlibExperimentalDefinitions.scala index 4cfb23e229ac..3679aed3cfef 100644 --- a/tests/run-tasty-inspector/stdlibExperimentalDefinitions.scala +++ b/tests/run-tasty-inspector/stdlibExperimentalDefinitions.scala @@ -98,6 +98,9 @@ val experimentalDefinitionInLibrary = Set( // New feature: Erased trait "scala.compiletime.Erased", + + // New API: IArray Factory conversion + "scala.IArray$package$.IArray$.convertIArrayToFactory", ) diff --git a/tests/run/IArrayOps-experimental-Factory.scala b/tests/run/IArrayOps-experimental-Factory.scala new file mode 100644 index 000000000000..5a4c49ce4498 --- /dev/null +++ b/tests/run/IArrayOps-experimental-Factory.scala @@ -0,0 +1,16 @@ +//> using options -experimental + +import scala.collection.Factory + +@main def Test: Unit = + val explicit: Factory[Int, IArray[Int]] = IArray.convertIArrayToFactory[Int](IArray) + val contextual: Factory[Int, IArray[Int]] = IArray: Factory[Int, IArray[Int]] + + assert(explicit.getClass() == contextual.getClass()) // default is same implementation + + val convertFromList = List(1,2,3).to(IArray) + val ev: IArray[Int] = convertFromList + + assert(convertFromList.getClass == IArray(1,2,3).getClass()) + + assert(ev.sameElements(Vector(1,2,3)))