Skip to content

Moved Maximized back in universal trait IterableOnceOps #19446

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

nicolasstucki
Copy link
Contributor

Under -Ycompile-scala2-library we allow universal traits that have nested classes.

Difference with original source
sbt>scala2-library-cc/run diff scala/collection/IterableOnce.scala

@@ -20,6 +20,7 @@ import scala.language.implicitConversions
 import scala.math.{Numeric, Ordering}
 import scala.reflect.ClassTag
 import scala.runtime.{AbstractFunction1, AbstractFunction2}
+import language.experimental.captureChecking
 
 /**
   * A template trait for collections which can be traversed either once only
@@ -42,8 +43,9 @@ import scala.runtime.{AbstractFunction1, AbstractFunction2}
   * @define coll collection
   */
 trait IterableOnce[+A] extends Any {
+
   /** Iterator can be used only once */
-  def iterator: Iterator[A]
+  def iterator: Iterator[A]^{this}
 
   /** Returns a [[scala.collection.Stepper]] for the elements of this collection.
     *
@@ -65,9 +67,9 @@ trait IterableOnce[+A] extends Any {
     * allow creating parallel streams, whereas bare Steppers can be converted only to sequential
     * streams.
     */
-  def stepper[S <: Stepper[_]](implicit shape: StepperShape[A, S]): S = {
+  def stepper[S <: Stepper[_]^{this}](implicit shape: StepperShape[A, S]): S = {
     import convert.impl._
-    val s = shape.shape match {
+    val s: Any = shape.shape match {
       case StepperShape.IntShape    => new IntIteratorStepper   (iterator.asInstanceOf[Iterator[Int]])
       case StepperShape.LongShape   => new LongIteratorStepper  (iterator.asInstanceOf[Iterator[Long]])
       case StepperShape.DoubleShape => new DoubleIteratorStepper(iterator.asInstanceOf[Iterator[Double]])
@@ -84,7 +86,7 @@ trait IterableOnce[+A] extends Any {
 
 final class IterableOnceExtensionMethods[A](private val it: IterableOnce[A]) extends AnyVal {
   @deprecated("Use .iterator.withFilter(...) instead", "2.13.0")
-  def withFilter(f: A => Boolean): Iterator[A] = it.iterator.withFilter(f)
+  def withFilter(f: A => Boolean): Iterator[A]^{f} = it.iterator.withFilter(f)
 
   @deprecated("Use .iterator.reduceLeftOption(...) instead", "2.13.0")
   def reduceLeftOption(f: (A, A) => A): Option[A] = it.iterator.reduceLeftOption(f)
@@ -102,7 +104,7 @@ final class IterableOnceExtensionMethods[A](private val it: IterableOnce[A]) ext
   def reduceRight(f: (A, A) => A): A = it.iterator.reduceRight(f)
 
   @deprecated("Use .iterator.maxBy(...) instead", "2.13.0")
-  def maxBy[B](f: A => B)(implicit cmp: Ordering[B]): A = it.iterator.maxBy(f)
+  def maxBy[B](f: A -> B)(implicit cmp: Ordering[B]): A = it.iterator.maxBy(f)
 
   @deprecated("Use .iterator.reduceLeft(...) instead", "2.13.0")
   def reduceLeft(f: (A, A) => A): A = it.iterator.reduceLeft(f)
@@ -120,7 +122,7 @@ final class IterableOnceExtensionMethods[A](private val it: IterableOnce[A]) ext
   def reduceOption(f: (A, A) => A): Option[A] = it.iterator.reduceOption(f)
 
   @deprecated("Use .iterator.minBy(...) instead", "2.13.0")
-  def minBy[B](f: A => B)(implicit cmp: Ordering[B]): A = it.iterator.minBy(f)
+  def minBy[B](f: A -> B)(implicit cmp: Ordering[B]): A = it.iterator.minBy(f)
 
   @deprecated("Use .iterator.size instead", "2.13.0")
   def size: Int = it.iterator.size
@@ -132,7 +134,7 @@ final class IterableOnceExtensionMethods[A](private val it: IterableOnce[A]) ext
   def collectFirst[B](f: PartialFunction[A, B]): Option[B] = it.iterator.collectFirst(f)
 
   @deprecated("Use .iterator.filter(...) instead", "2.13.0")
-  def filter(f: A => Boolean): Iterator[A] = it.iterator.filter(f)
+  def filter(f: A => Boolean): Iterator[A]^{f} = it.iterator.filter(f)
 
   @deprecated("Use .iterator.exists(...) instead", "2.13.0")
   def exists(f: A => Boolean): Boolean = it.iterator.exists(f)
@@ -238,13 +240,13 @@ final class IterableOnceExtensionMethods[A](private val it: IterableOnce[A]) ext
   @`inline` def :\ [B](z: B)(op: (A, B) => B): B = foldRight[B](z)(op)
 
   @deprecated("Use .iterator.map instead or consider requiring an Iterable", "2.13.0")
-  def map[B](f: A => B): IterableOnce[B] = it match {
+  def map[B](f: A => B): IterableOnce[B]^{f} = it match {
     case it: Iterable[A] => it.map(f)
     case _ => it.iterator.map(f)
   }
 
   @deprecated("Use .iterator.flatMap instead or consider requiring an Iterable", "2.13.0")
-  def flatMap[B](f: A => IterableOnce[B]): IterableOnce[B] = it match {
+  def flatMap[B](f: A => IterableOnce[B]^): IterableOnce[B]^{f} = it match {
     case it: Iterable[A] => it.flatMap(f)
     case _ => it.iterator.flatMap(f)
   }
@@ -269,10 +271,11 @@ object IterableOnce {
     math.max(math.min(math.min(len, srcLen), destLen - start), 0)
 
   /** Calls `copyToArray` on the given collection, regardless of whether or not it is an `Iterable`. */
-  @inline private[collection] def copyElemsToArray[A, B >: A](elems: IterableOnce[A],
-                                                              xs: Array[B],
-                                                              start: Int = 0,
-                                                              len: Int = Int.MaxValue): Int =
+  @inline private[collection] def copyElemsToArray[A, B >: A](
+      elems: IterableOnce[A]^,
+      xs: Array[B],
+      start: Int = 0,
+      len: Int = Int.MaxValue): Int =
     elems match {
       case src: Iterable[A] => src.copyToArray[B](xs, start, len)
       case src              => src.iterator.copyToArray[B](xs, start, len)
@@ -315,7 +318,7 @@ object IterableOnce {
   * @define coll collection
   *
   */
-trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
+trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A]^ =>
   /////////////////////////////////////////////////////////////// Abstract methods that must be implemented
 
   /** Produces a $coll containing cumulative results of applying the
@@ -329,7 +332,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
    *  @param op      the binary operator applied to the intermediate result and the element
    *  @return        collection with intermediate results
    */
-  def scanLeft[B](z: B)(op: (B, A) => B): CC[B]
+  def scanLeft[B](z: B)(op: (B, A) => B): CC[B]^{this, op}
 
   /** Selects all elements of this $coll which satisfy a predicate.
    *
@@ -337,7 +340,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
    *  @return      a new $coll consisting of all elements of this $coll that satisfy the given
    *               predicate `p`. The order of the elements is preserved.
    */
-  def filter(p: A => Boolean): C
+  def filter(p: A => Boolean): C^{this, p}
 
   /** Selects all elements of this $coll which do not satisfy a predicate.
    *
@@ -345,7 +348,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
    *  @return      a new $coll consisting of all elements of this $coll that do not satisfy the given
    *               predicate `pred`. Their order may not be preserved.
    */
-  def filterNot(pred: A => Boolean): C
+  def filterNot(p: A => Boolean): C^{this, p}
 
   /** Selects the first ''n'' elements.
    *  $orderDependent
@@ -354,7 +357,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
    *          or else the whole $coll, if it has less than `n` elements.
    *          If `n` is negative, returns an empty $coll.
    */
-  def take(n: Int): C
+  def take(n: Int): C^{this}
 
   /** Takes longest prefix of elements that satisfy a predicate.
    *  $orderDependent
@@ -362,7 +365,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
    *  @return  the longest prefix of this $coll whose elements all satisfy
    *           the predicate `p`.
    */
-  def takeWhile(p: A => Boolean): C
+  def takeWhile(p: A => Boolean): C^{this, p}
 
   /** Selects all elements except first ''n'' ones.
    *  $orderDependent
@@ -371,7 +374,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
    *          empty $coll, if this $coll has less than `n` elements.
    *          If `n` is negative, don't drop any elements.
    */
-  def drop(n: Int): C
+  def drop(n: Int): C^{this}
 
   /** Drops longest prefix of elements that satisfy a predicate.
    *  $orderDependent
@@ -379,7 +382,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
    *  @return  the longest suffix of this $coll whose first element
    *           does not satisfy the predicate `p`.
    */
-  def dropWhile(p: A => Boolean): C
+  def dropWhile(p: A => Boolean): C^{this, p}
 
   /** Selects an interval of elements.  The returned $coll is made up
    *  of all elements `x` which satisfy the invariant:
@@ -394,7 +397,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
    *           index `from` extending up to (but not including) index `until`
    *           of this $coll.
    */
-  def slice(from: Int, until: Int): C
+  def slice(from: Int, until: Int): C^{this}
 
   /** Builds a new $coll by applying a function to all elements of this $coll.
    *
@@ -403,7 +406,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
    *  @return       a new $coll resulting from applying the given function
    *                `f` to each element of this $coll and collecting the results.
    */
-  def map[B](f: A => B): CC[B]
+  def map[B](f: A => B): CC[B]^{this, f}
 
   /** Builds a new $coll by applying a function to all elements of this $coll
    *  and using the elements of the resulting collections.
@@ -436,7 +439,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
    *  @return       a new $coll resulting from applying the given collection-valued function
    *                `f` to each element of this $coll and concatenating the results.
    */
-  def flatMap[B](f: A => IterableOnce[B]): CC[B]
+  def flatMap[B](f: A => IterableOnce[B]^): CC[B]^{this, f}
 
   /** Converts this $coll of iterable collections into
    *  a $coll formed by the elements of these iterable
@@ -464,7 +467,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
    *          type of this $coll is an `Iterable`.
    *  @return a new $coll resulting from concatenating all element ${coll}s.
    */
-  def flatten[B](implicit asIterable: A => IterableOnce[B]): CC[B]
+  def flatten[B](implicit asIterable: A -> IterableOnce[B]): CC[B]^{this}
 
   /** Builds a new $coll by applying a partial function to all elements of this $coll
    *  on which the function is defined.
@@ -475,7 +478,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
    *                `pf` to each element on which it is defined and collecting the results.
    *                The order of the elements is preserved.
    */
-  def collect[B](pf: PartialFunction[A, B]): CC[B]
+  def collect[B](pf: PartialFunction[A, B]^): CC[B]^{this, pf}
 
   /** Zips this $coll with its indices.
    *
@@ -484,7 +487,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
    *  @example
    *    `List("a", "b", "c").zipWithIndex == List(("a", 0), ("b", 1), ("c", 2))`
    */
-  def zipWithIndex: CC[(A @uncheckedVariance, Int)]
+  def zipWithIndex: CC[(A @uncheckedVariance, Int)]^{this}
 
   /** Splits this $coll into a prefix/suffix pair according to a predicate.
    *
@@ -497,7 +500,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
    *  @return  a pair consisting of the longest prefix of this $coll whose
    *           elements all satisfy `p`, and the rest of this $coll.
    */
-  def span(p: A => Boolean): (C, C)
+  def span(p: A => Boolean): (C^{this, p}, C^{this, p})
 
   /** Splits this $coll into a prefix/suffix pair at a given position.
    *
@@ -509,7 +512,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
    *  @return  a pair of ${coll}s consisting of the first `n`
    *           elements of this $coll, and the other elements.
    */
-  def splitAt(n: Int): (C, C) = {
+  def splitAt(n: Int): (C^{this}, C^{this}) = {
     class Spanner extends runtime.AbstractFunction1[A, Boolean] {
       var i = 0
       def apply(a: A) = i < n && { i += 1 ; true }
@@ -527,7 +530,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
     * @tparam U the return type of f
     * @return The same logical collection as this
     */
-  def tapEach[U](f: A => U): C
+  def tapEach[U](f: A => U): C^{this, f}
 
   /////////////////////////////////////////////////////////////// Concrete methods based on iterator
 
@@ -802,7 +805,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
       case  _ => Some(reduceLeft(op))
     }
   private final def reduceLeftOptionIterator[B >: A](op: (B, A) => B): Option[B] = reduceOptionIterator[A, B](iterator)(op)
-  private final def reduceOptionIterator[X >: A, B >: X](it: Iterator[X])(op: (B, X) => B): Option[B] = {
+  private final def reduceOptionIterator[X >: A, B >: X](it: Iterator[X]^)(op: (B, X) => B): Option[B] = {
     if (it.hasNext) {
       var acc: B = it.next()
       while (it.hasNext)
@@ -1041,15 +1044,15 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
    *  @return   the first element of this $coll with the largest value measured by function f
    *            with respect to the ordering `cmp`.
    */
-  def maxBy[B](f: A => B)(implicit ord: Ordering[B]): A =
+  def maxBy[B](f: A -> B)(implicit ord: Ordering[B]): A =
     knownSize match {
       case  0 => throw new UnsupportedOperationException("empty.maxBy")
       case  _ => foldLeft(new Maximized[A, B]("maxBy")(f)(ord.gt))((m, a) => m(m, a)).result
     }
 
-  private class Maximized[X, B](descriptor: String)(f: X => B)(cmp: (B, B) => Boolean) extends AbstractFunction2[Maximized[X, B], X, Maximized[X, B]] {
-    var maxElem: X = null.asInstanceOf[X]
-    var maxF: B = null.asInstanceOf[B]
+  private class Maximized[X, B](descriptor: String)(f: X -> B)(cmp: (B, B) -> Boolean) extends AbstractFunction2[Maximized[X, B], X, Maximized[X, B]] {
+    var maxElem: X  = null.asInstanceOf[X]
+    var maxF: B  = null.asInstanceOf[B]
     var nonEmpty = false
     def toOption: Option[X] = if (nonEmpty) Some(maxElem) else None
     def result: X = if (nonEmpty) maxElem else throw new UnsupportedOperationException(s"empty.$descriptor")
@@ -1080,7 +1083,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
    *  @return   an option value containing the first element of this $coll with the
    *            largest value measured by function f with respect to the ordering `cmp`.
    */
-  def maxByOption[B](f: A => B)(implicit ord: Ordering[B]): Option[A] =
+  def maxByOption[B](f: A -> B)(implicit ord: Ordering[B]): Option[A] =
     knownSize match {
       case  0 => None
       case  _ => foldLeft(new Maximized[A, B]("maxBy")(f)(ord.gt))((m, a) => m(m, a)).toOption
@@ -1097,7 +1100,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
    *  @return   the first element of this $coll with the smallest value measured by function f
    *            with respect to the ordering `cmp`.
    */
-  def minBy[B](f: A => B)(implicit ord: Ordering[B]): A =
+  def minBy[B](f: A -> B)(implicit ord: Ordering[B]): A =
     knownSize match {
       case  0 => throw new UnsupportedOperationException("empty.minBy")
       case  _ => foldLeft(new Maximized[A, B]("minBy")(f)(ord.lt))((m, a) => m(m, a)).result
@@ -1114,7 +1117,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
    *            with the smallest value measured by function f
    *            with respect to the ordering `cmp`.
    */
-  def minByOption[B](f: A => B)(implicit ord: Ordering[B]): Option[A] =
+  def minByOption[B](f: A -> B)(implicit ord: Ordering[B]): Option[A] =
     knownSize match {
       case  0 => None
       case  _ => foldLeft(new Maximized[A, B]("minBy")(f)(ord.lt))((m, a) => m(m, a)).toOption
@@ -1310,7 +1313,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
   def to[C1](factory: Factory[A, C1]): C1 = factory.fromSpecific(this)
 
   @deprecated("Use .iterator instead of .toIterator", "2.13.0")
-  @`inline` final def toIterator: Iterator[A] = iterator
+  @`inline` final def toIterator: Iterator[A]^{this} = iterator
 
   def toList: immutable.List[A] = immutable.List.from(this)
 
@@ -1328,9 +1331,9 @@ trait IterableOnceOps

Under `-Ycompile-scala2-library` we allow universal traits that have nested
classes.
@nicolasstucki nicolasstucki marked this pull request as ready for review January 15, 2024 12:19
@nicolasstucki nicolasstucki requested a review from odersky January 15, 2024 13:19
@nicolasstucki nicolasstucki merged commit 994ceac into scala:main Jan 15, 2024
@nicolasstucki nicolasstucki deleted the cleanup-scala-library-cc-IterableOnce branch January 15, 2024 13:49
@Kordyjan Kordyjan added this to the 3.4.1 milestone Feb 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants