diff --git a/library/src/scala/collection/generic/IsSeq.scala b/library/src/scala/collection/generic/IsSeq.scala index 06341db26fb6..5329953ffec9 100644 --- a/library/src/scala/collection/generic/IsSeq.scala +++ b/library/src/scala/collection/generic/IsSeq.scala @@ -18,6 +18,7 @@ import language.experimental.captureChecking import caps.unsafe.untrackedCaptures import scala.reflect.ClassTag +import scala.annotation.experimental /** Type class witnessing that a collection representation type `Repr` has * elements of type `A` and has a conversion to `SeqOps[A, Iterable, C]`, for @@ -106,6 +107,25 @@ object IsSeq { } } + @experimental + given iarrayIsSeq[A0 : ClassTag]: (IsSeq[IArray[A0]] { type A = A0; type C = IArray[A0] }) = + new IsSeq[IArray[A0]] { + type A = A0 + type C = IArray[A0] + def apply(a: IArray[A0]): SeqOps[A0, Seq, IArray[A0]] = + new SeqOps[A, immutable.ArraySeq, IArray[A]] { + def apply(i: Int): A = a(i) + def length: Int = a.length + def toIterable: Iterable[A] = IArray.genericWrapArray(a) + protected def coll: IArray[A] = a + protected def fromSpecific(coll: IterableOnce[A]^): IArray[A] = IArray.from(coll) + def iterableFactory: IterableFactory[immutable.ArraySeq] = immutable.ArraySeq.untagged + override def empty: IArray[A] = IArray.empty[A] + protected def newSpecificBuilder: mutable.Builder[A, IArray[A]] = IArray.newBuilder + def iterator: Iterator[A] = a.iterator + } + } + // `Range` can not be unified with the `CC0` parameter of the // `seqOpsIsSeq` definition because it does not take a type parameter. // Hence the need for a separate case: diff --git a/project/MiMaFilters.scala b/project/MiMaFilters.scala index 575a20af629a..cbb7a418d498 100644 --- a/project/MiMaFilters.scala +++ b/project/MiMaFilters.scala @@ -23,6 +23,9 @@ object MiMaFilters { ProblemFilters.exclude[DirectMissingMethodProblem]("scala.NamedTuple.namedTupleOrdering"), ProblemFilters.exclude[MissingClassProblem]("scala.NamedTuple$namedTupleOrdering"), + // IArray integration with Scala Collections: + ProblemFilters.exclude[DirectMissingMethodProblem]("scala.collection.generic.IsSeq.iarrayIsSeq"), + // cc related ProblemFilters.exclude[MissingClassProblem]("scala.annotation.internal.readOnlyCapability"), ProblemFilters.exclude[MissingClassProblem]("scala.annotation.internal.onlyCapability"), diff --git a/tests/run-tasty-inspector/stdlibExperimentalDefinitions.scala b/tests/run-tasty-inspector/stdlibExperimentalDefinitions.scala index 4cfb23e229ac..a64a61b9ec8d 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: IsSeq[IArray[T]] + "scala.collection.generic.IsSeq$.iarrayIsSeq", ) diff --git a/tests/run/IArrayOps-experimental.check b/tests/run/IArrayOps-experimental.check new file mode 100644 index 000000000000..ff007233042f --- /dev/null +++ b/tests/run/IArrayOps-experimental.check @@ -0,0 +1,2 @@ +class scala.collection.immutable.ArraySeq$ofRef +1,2 diff --git a/tests/run/IArrayOps-experimental.scala b/tests/run/IArrayOps-experimental.scala new file mode 100644 index 000000000000..32141b5bda2f --- /dev/null +++ b/tests/run/IArrayOps-experimental.scala @@ -0,0 +1,16 @@ +//> using options -experimental + +@main def Test: Unit = + val isSeq1: scala.collection.generic.IsSeq[IArray[Int]] { type A = Int; type C = IArray[Int] } = + scala.collection.generic.IsSeq.iarrayIsSeq[Int] + val isSeq2: scala.collection.generic.IsSeq[IArray[Int]] { type A = Int; type C = IArray[Int] } = + summon[scala.collection.generic.IsSeq[IArray[Int]]] + assert(isSeq1.getClass eq isSeq2.getClass) // check that default implicit is same as explicit call + + val iarr = IArray(1, 2, 3) + val seqOps: scala.collection.SeqOps[Int, Iterable, IArray[Int]] = isSeq1(iarr) + println(seqOps.map(_ * 2).getClass()) // should be immutable.ArraySeq.ofRef + val evens: IArray[Int] = seqOps.filter(_ % 2 == 0) + val buckets: Map[Boolean, IArray[Int]] = seqOps.groupBy(_ < 3) + val smalls: IArray[Int] = buckets(true) + println(smalls.mkString(","))