Skip to content

Commit

Permalink
Merge pull request #9774 from lrytz/deprecate-toIterable
Browse files Browse the repository at this point in the history
Deprecate IterableOps.toIterable
  • Loading branch information
NthPortal committed Sep 30, 2021
2 parents 531db50 + 158c05b commit e41a0cc
Show file tree
Hide file tree
Showing 25 changed files with 95 additions and 67 deletions.
4 changes: 2 additions & 2 deletions src/library/scala/Enumeration.scala
Expand Up @@ -310,8 +310,8 @@ abstract class Enumeration (initial: Int) extends Serializable {
override protected def fromSpecific(coll: IterableOnce[Value]): ValueSet = ValueSet.fromSpecific(coll)
override protected def newSpecificBuilder = ValueSet.newBuilder

def map(f: Value => Value): ValueSet = fromSpecific(new View.Map(toIterable, f))
def flatMap(f: Value => IterableOnce[Value]): ValueSet = fromSpecific(new View.FlatMap(toIterable, f))
def map(f: Value => Value): ValueSet = fromSpecific(new View.Map(this, f))
def flatMap(f: Value => IterableOnce[Value]): ValueSet = fromSpecific(new View.FlatMap(this, f))

// necessary for disambiguation:
override def map[B](f: Value => B)(implicit @implicitNotFound(ValueSet.ordMsg) ev: Ordering[B]): immutable.SortedSet[B] =
Expand Down
6 changes: 3 additions & 3 deletions src/library/scala/collection/BitSet.scala
Expand Up @@ -295,11 +295,11 @@ trait BitSetOps[+C <: BitSet with BitSetOps[C]]
* @return a new bitset resulting from applying the given function ''f'' to
* each element of this bitset and collecting the results
*/
def map(f: Int => Int): C = fromSpecific(new View.Map(toIterable, f))
def map(f: Int => Int): C = fromSpecific(new View.Map(this, f))

def flatMap(f: Int => IterableOnce[Int]): C = fromSpecific(new View.FlatMap(toIterable, f))
def flatMap(f: Int => IterableOnce[Int]): C = fromSpecific(new View.FlatMap(this, f))

def collect(pf: PartialFunction[Int, Int]): C = fromSpecific(super[SortedSetOps].collect(pf).toIterable)
def collect(pf: PartialFunction[Int, Int]): C = fromSpecific(super[SortedSetOps].collect(pf))

override def partition(p: Int => Boolean): (C, C) = {
val left = filter(p)
Expand Down
11 changes: 9 additions & 2 deletions src/library/scala/collection/Iterable.scala
Expand Up @@ -13,6 +13,7 @@
package scala
package collection

import scala.annotation.nowarn
import scala.annotation.unchecked.uncheckedVariance
import scala.collection.mutable.Builder
import scala.collection.View.{LeftPartitionMapped, RightPartitionMapped}
Expand All @@ -29,6 +30,7 @@ trait Iterable[+A] extends IterableOnce[A]
with IterableFactoryDefaults[A, Iterable] {

// The collection itself
@deprecated("toIterable is internal and will be made protected; its name is similar to `toList` or `toSeq`, but it doesn't copy non-immutable collections", "2.13.7")
final def toIterable: this.type = this

final protected def coll: this.type = this
Expand Down Expand Up @@ -133,13 +135,15 @@ trait IterableOps[+A, +CC[_], +C] extends Any with IterableOnce[A] with Iterable
/**
* @return This collection as an `Iterable[A]`. No new collection will be built if `this` is already an `Iterable[A]`.
*/
// Should be `protected def asIterable`, or maybe removed altogether if it's not needed
@deprecated("toIterable is internal and will be made protected; its name is similar to `toList` or `toSeq`, but it doesn't copy non-immutable collections", "2.13.7")
def toIterable: Iterable[A]

/** Converts this $coll to an unspecified Iterable. Will return
* the same collection if this instance is already Iterable.
* @return An Iterable containing all elements of this $coll.
*/
@deprecated("Use toIterable instead", "2.13.0")
@deprecated("toTraversable is internal and will be made protected; its name is similar to `toList` or `toSeq`, but it doesn't copy non-immutable collections", "2.13.0")
final def toTraversable: Traversable[A] = toIterable

override def isTraversableAgain: Boolean = true
Expand Down Expand Up @@ -830,7 +834,10 @@ trait IterableOps[+A, +CC[_], +C] extends Any with IterableOnce[A] with Iterable

// A helper for tails and inits.
private[this] def iterateUntilEmpty(f: Iterable[A] => Iterable[A]): Iterator[C] = {
val it = Iterator.iterate(toIterable)(f).takeWhile(_.nonEmpty)
// toIterable ties the knot between `this: IterableOnceOps[A, CC, C]` and `this.tail: C`
// `this.tail.tail` doesn't compile as `C` is unbounded
// `Iterable.from(this)` would eagerly copy non-immutable collections
val it = Iterator.iterate(toIterable: @nowarn("cat=deprecation"))(f).takeWhile(_.nonEmpty)
(it ++ Iterator.single(Iterable.empty)).map(fromSpecific)
}

Expand Down
2 changes: 1 addition & 1 deletion src/library/scala/collection/LinearSeq.scala
Expand Up @@ -248,7 +248,7 @@ trait LinearSeqOps[+A, +CC[X] <: LinearSeq[X], +C <: LinearSeq[A] with LinearSeq
trait StrictOptimizedLinearSeqOps[+A, +CC[X] <: LinearSeq[X], +C <: LinearSeq[A] with StrictOptimizedLinearSeqOps[A, CC, C]] extends Any with LinearSeqOps[A, CC, C] with StrictOptimizedSeqOps[A, CC, C] {
// A more efficient iterator implementation than the default LinearSeqIterator
override def iterator: Iterator[A] = new AbstractIterator[A] {
private[this] var current: Iterable[A] = toIterable
private[this] var current = StrictOptimizedLinearSeqOps.this
def hasNext = !current.isEmpty
def next() = { val r = current.head; current = current.tail; r }
}
Expand Down
16 changes: 8 additions & 8 deletions src/library/scala/collection/Map.scala
Expand Up @@ -71,7 +71,7 @@ trait Map[K, +V]
false
})

override def hashCode(): Int = MurmurHash3.mapHash(toIterable)
override def hashCode(): Int = MurmurHash3.mapHash(this)

// These two methods are not in MapOps so that MapView is not forced to implement them
@deprecated("Use - or removed on an immutable Map", "2.13.0")
Expand Down Expand Up @@ -296,7 +296,7 @@ trait MapOps[K, +V, +CC[_, _] <: IterableOps[_, AnyConstr, _], +C]
* @return a new $coll resulting from applying the given function
* `f` to each element of this $coll and collecting the results.
*/
def map[K2, V2](f: ((K, V)) => (K2, V2)): CC[K2, V2] = mapFactory.from(new View.Map(toIterable, f))
def map[K2, V2](f: ((K, V)) => (K2, V2)): CC[K2, V2] = mapFactory.from(new View.Map(this, f))

/** Builds a new collection by applying a partial function to all elements of this $coll
* on which the function is defined.
Expand All @@ -309,7 +309,7 @@ trait MapOps[K, +V, +CC[_, _] <: IterableOps[_, AnyConstr, _], +C]
* The order of the elements is preserved.
*/
def collect[K2, V2](pf: PartialFunction[(K, V), (K2, V2)]): CC[K2, V2] =
mapFactory.from(new View.Collect(toIterable, pf))
mapFactory.from(new View.Collect(this, pf))

/** Builds a new map by applying a function to all elements of this $coll
* and using the elements of the resulting collections.
Expand All @@ -318,7 +318,7 @@ trait MapOps[K, +V, +CC[_, _] <: IterableOps[_, AnyConstr, _], +C]
* @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[K2, V2](f: ((K, V)) => IterableOnce[(K2, V2)]): CC[K2, V2] = mapFactory.from(new View.FlatMap(toIterable, f))
def flatMap[K2, V2](f: ((K, V)) => IterableOnce[(K2, V2)]): CC[K2, V2] = mapFactory.from(new View.FlatMap(this, f))

/** Returns a new $coll containing the elements from the left hand operand followed by the elements from the
* right hand operand. The element type of the $coll is the most specific superclass encompassing
Expand All @@ -329,7 +329,7 @@ trait MapOps[K, +V, +CC[_, _] <: IterableOps[_, AnyConstr, _], +C]
* of this $coll followed by all elements of `suffix`.
*/
def concat[V2 >: V](suffix: collection.IterableOnce[(K, V2)]): CC[K, V2] = mapFactory.from(suffix match {
case it: Iterable[(K, V2)] => new View.Concat(toIterable, it)
case it: Iterable[(K, V2)] => new View.Concat(this, it)
case _ => iterator.concat(suffix.iterator)
})

Expand All @@ -343,11 +343,11 @@ trait MapOps[K, +V, +CC[_, _] <: IterableOps[_, AnyConstr, _], +C]

@deprecated("Consider requiring an immutable Map or fall back to Map.concat.", "2.13.0")
def + [V1 >: V](kv: (K, V1)): CC[K, V1] =
mapFactory.from(new View.Appended(toIterable, kv))
mapFactory.from(new View.Appended(this, kv))

@deprecated("Use ++ with an explicit collection argument instead of + with varargs", "2.13.0")
def + [V1 >: V](elem1: (K, V1), elem2: (K, V1), elems: (K, V1)*): CC[K, V1] =
mapFactory.from(new View.Concat(new View.Appended(new View.Appended(toIterable, elem1), elem2), elems))
mapFactory.from(new View.Concat(new View.Appended(new View.Appended(this, elem1), elem2), elems))

@deprecated("Consider requiring an immutable Map.", "2.13.0")
@`inline` def -- (keys: IterableOnce[K]): C = {
Expand All @@ -361,7 +361,7 @@ trait MapOps[K, +V, +CC[_, _] <: IterableOps[_, AnyConstr, _], +C]
case that: Iterable[(K, V1)] => that
case that => View.from(that)
}
mapFactory.from(new View.Concat(thatIterable, toIterable))
mapFactory.from(new View.Concat(thatIterable, this))
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/library/scala/collection/Seq.scala
Expand Up @@ -38,7 +38,7 @@ trait Seq[+A]
case _ => false
})

override def hashCode(): Int = MurmurHash3.seqHash(toIterable)
override def hashCode(): Int = MurmurHash3.seqHash(this)

override def toString(): String = super[Iterable].toString()

Expand Down
12 changes: 6 additions & 6 deletions src/library/scala/collection/Set.scala
Expand Up @@ -70,7 +70,7 @@ trait Set[A]
false
})

override def hashCode(): Int = MurmurHash3.setHash(toIterable)
override def hashCode(): Int = MurmurHash3.setHash(this)

override def iterableFactory: IterableFactory[Set] = Set

Expand Down Expand Up @@ -115,15 +115,15 @@ trait SetOps[A, +CC[_], +C <: SetOps[A, CC, C]]
*/
def subsets(len: Int): Iterator[C] = {
if (len < 0 || len > size) Iterator.empty
else new SubsetsItr(toIterable.to(IndexedSeq), len)
else new SubsetsItr(this.to(IndexedSeq), len)
}

/** An iterator over all subsets of this set.
*
* @return the iterator.
*/
def subsets(): Iterator[C] = new AbstractIterator[C] {
private[this] val elms = toIterable.to(IndexedSeq)
private[this] val elms = SetOps.this.to(IndexedSeq)
private[this] var len = 0
private[this] var itr: Iterator[C] = Iterator.empty

Expand Down Expand Up @@ -221,15 +221,15 @@ trait SetOps[A, +CC[_], +C <: SetOps[A, CC, C]]
* @return a new $coll with the given elements added, omitting duplicates.
*/
def concat(that: collection.IterableOnce[A]): C = fromSpecific(that match {
case that: collection.Iterable[A] => new View.Concat(toIterable, that)
case that: collection.Iterable[A] => new View.Concat(this, that)
case _ => iterator.concat(that.iterator)
})

@deprecated("Consider requiring an immutable Set or fall back to Set.union", "2.13.0")
def + (elem: A): C = fromSpecific(new View.Appended(toIterable, elem))
def + (elem: A): C = fromSpecific(new View.Appended(this, elem))

@deprecated("Use ++ with an explicit collection argument instead of + with varargs", "2.13.0")
def + (elem1: A, elem2: A, elems: A*): C = fromSpecific(new View.Concat(new View.Appended(new View.Appended(toIterable, elem1), elem2), elems))
def + (elem1: A, elem2: A, elems: A*): C = fromSpecific(new View.Concat(new View.Appended(new View.Appended(this, elem1), elem2), elems))

/** Alias for `concat` */
@`inline` final def ++ (that: collection.IterableOnce[A]): C = concat(that)
Expand Down
12 changes: 6 additions & 6 deletions src/library/scala/collection/SortedMap.scala
Expand Up @@ -153,7 +153,7 @@ trait SortedMapOps[K, +V, +CC[X, Y] <: Map[X, Y] with SortedMapOps[X, Y, CC, _],
* `f` to each element of this $coll and collecting the results.
*/
def map[K2, V2](f: ((K, V)) => (K2, V2))(implicit @implicitNotFound(SortedMapOps.ordMsg) ordering: Ordering[K2]): CC[K2, V2] =
sortedMapFactory.from(new View.Map[(K, V), (K2, V2)](toIterable, f))
sortedMapFactory.from(new View.Map[(K, V), (K2, V2)](this, f))

/** Builds a new sorted map by applying a function to all elements of this $coll
* and using the elements of the resulting collections.
Expand All @@ -163,7 +163,7 @@ trait SortedMapOps[K, +V, +CC[X, Y] <: Map[X, Y] with SortedMapOps[X, Y, CC, _],
* `f` to each element of this $coll and concatenating the results.
*/
def flatMap[K2, V2](f: ((K, V)) => IterableOnce[(K2, V2)])(implicit @implicitNotFound(SortedMapOps.ordMsg) ordering: Ordering[K2]): CC[K2, V2] =
sortedMapFactory.from(new View.FlatMap(toIterable, f))
sortedMapFactory.from(new View.FlatMap(this, f))

/** Builds a new sorted map by applying a partial function to all elements of this $coll
* on which the function is defined.
Expand All @@ -174,21 +174,21 @@ trait SortedMapOps[K, +V, +CC[X, Y] <: Map[X, Y] with SortedMapOps[X, Y, CC, _],
* The order of the elements is preserved.
*/
def collect[K2, V2](pf: PartialFunction[(K, V), (K2, V2)])(implicit @implicitNotFound(SortedMapOps.ordMsg) ordering: Ordering[K2]): CC[K2, V2] =
sortedMapFactory.from(new View.Collect(toIterable, pf))
sortedMapFactory.from(new View.Collect(this, pf))

override def concat[V2 >: V](suffix: IterableOnce[(K, V2)]): CC[K, V2] = sortedMapFactory.from(suffix match {
case it: Iterable[(K, V2)] => new View.Concat(toIterable, it)
case it: Iterable[(K, V2)] => new View.Concat(this, it)
case _ => iterator.concat(suffix.iterator)
})(ordering)

/** Alias for `concat` */
@`inline` override final def ++ [V2 >: V](xs: IterableOnce[(K, V2)]): CC[K, V2] = concat(xs)

@deprecated("Consider requiring an immutable Map or fall back to Map.concat", "2.13.0")
override def + [V1 >: V](kv: (K, V1)): CC[K, V1] = sortedMapFactory.from(new View.Appended(toIterable, kv))(ordering)
override def + [V1 >: V](kv: (K, V1)): CC[K, V1] = sortedMapFactory.from(new View.Appended(this, kv))(ordering)

@deprecated("Use ++ with an explicit collection argument instead of + with varargs", "2.13.0")
override def + [V1 >: V](elem1: (K, V1), elem2: (K, V1), elems: (K, V1)*): CC[K, V1] = sortedMapFactory.from(new View.Concat(new View.Appended(new View.Appended(toIterable, elem1), elem2), elems))(ordering)
override def + [V1 >: V](elem1: (K, V1), elem2: (K, V1), elems: (K, V1)*): CC[K, V1] = sortedMapFactory.from(new View.Concat(new View.Appended(new View.Appended(this, elem1), elem2), elems))(ordering)
}

object SortedMapOps {
Expand Down
8 changes: 4 additions & 4 deletions src/library/scala/collection/SortedSet.scala
Expand Up @@ -118,7 +118,7 @@ trait SortedSetOps[A, +CC[X] <: SortedSet[X], +C <: SortedSetOps[A, CC, C]]
* `f` to each element of this $coll and collecting the results.
*/
def map[B](f: A => B)(implicit @implicitNotFound(SortedSetOps.ordMsg) ev: Ordering[B]): CC[B] =
sortedIterableFactory.from(new View.Map(toIterable, f))
sortedIterableFactory.from(new View.Map(this, f))

/** Builds a new sorted collection by applying a function to all elements of this $coll
* and using the elements of the resulting collections.
Expand All @@ -129,7 +129,7 @@ trait SortedSetOps[A, +CC[X] <: SortedSet[X], +C <: SortedSetOps[A, CC, C]]
* `f` to each element of this $coll and concatenating the results.
*/
def flatMap[B](f: A => IterableOnce[B])(implicit @implicitNotFound(SortedSetOps.ordMsg) ev: Ordering[B]): CC[B] =
sortedIterableFactory.from(new View.FlatMap(toIterable, f))
sortedIterableFactory.from(new View.FlatMap(this, f))

/** Returns a $coll formed from this $coll and another iterable collection
* by combining corresponding elements in pairs.
Expand All @@ -142,7 +142,7 @@ trait SortedSetOps[A, +CC[X] <: SortedSet[X], +C <: SortedSetOps[A, CC, C]]
*/
def zip[B](that: IterableOnce[B])(implicit @implicitNotFound(SortedSetOps.zipOrdMsg) ev: Ordering[(A @uncheckedVariance, B)]): CC[(A @uncheckedVariance, B)] = // sound bcs of VarianceNote
sortedIterableFactory.from(that match {
case that: Iterable[B] => new View.Zip(toIterable, that)
case that: Iterable[B] => new View.Zip(this, that)
case _ => iterator.zip(that)
})

Expand All @@ -156,7 +156,7 @@ trait SortedSetOps[A, +CC[X] <: SortedSet[X], +C <: SortedSetOps[A, CC, C]]
* The order of the elements is preserved.
*/
def collect[B](pf: scala.PartialFunction[A, B])(implicit @implicitNotFound(SortedSetOps.ordMsg) ev: Ordering[B]): CC[B] =
sortedIterableFactory.from(new View.Collect(toIterable, pf))
sortedIterableFactory.from(new View.Collect(this, pf))
}

object SortedSetOps {
Expand Down
7 changes: 4 additions & 3 deletions src/library/scala/collection/StrictOptimizedIterableOps.scala
Expand Up @@ -13,6 +13,7 @@
package scala
package collection

import scala.annotation.nowarn
import scala.annotation.unchecked.uncheckedVariance
import scala.runtime.Statics

Expand Down Expand Up @@ -203,7 +204,7 @@ trait StrictOptimizedIterableOps[+A, +CC[_], +C]

override def scanLeft[B](z: B)(op: (B, A) => B): CC[B] = {
val b = iterableFactory.newBuilder[B]
b.sizeHint(toIterable, delta = 0)
b.sizeHint(this, delta = 0)
var acc = z
b += acc
val it = iterator
Expand Down Expand Up @@ -254,7 +255,7 @@ trait StrictOptimizedIterableOps[+A, +CC[_], +C]
*/
override def takeRight(n: Int): C = {
val b = newSpecificBuilder
b.sizeHintBounded(n, toIterable)
b.sizeHintBounded(n, toIterable: @nowarn("cat=deprecation"))
val lead = iterator drop n
val it = iterator
while (lead.hasNext) {
Expand All @@ -271,7 +272,7 @@ trait StrictOptimizedIterableOps[+A, +CC[_], +C]
*/
override def dropRight(n: Int): C = {
val b = newSpecificBuilder
if (n >= 0) b.sizeHint(toIterable, delta = -n)
if (n >= 0) b.sizeHint(this, delta = -n)
val lead = iterator drop n
val it = iterator
while (lead.hasNext) {
Expand Down
4 changes: 2 additions & 2 deletions src/library/scala/collection/immutable/IntMap.scala
Expand Up @@ -323,9 +323,9 @@ sealed abstract class IntMap[+T] extends AbstractMap[Int, T]
case IntMap.Nil => IntMap.Tip(key, value)
}

def map[V2](f: ((Int, T)) => (Int, V2)): IntMap[V2] = intMapFrom(new View.Map(toIterable, f))
def map[V2](f: ((Int, T)) => (Int, V2)): IntMap[V2] = intMapFrom(new View.Map(this, f))

def flatMap[V2](f: ((Int, T)) => IterableOnce[(Int, V2)]): IntMap[V2] = intMapFrom(new View.FlatMap(toIterable, f))
def flatMap[V2](f: ((Int, T)) => IterableOnce[(Int, V2)]): IntMap[V2] = intMapFrom(new View.FlatMap(this, f))

override def concat[V1 >: T](that: collection.IterableOnce[(Int, V1)]): IntMap[V1] =
super.concat(that).asInstanceOf[IntMap[V1]] // Already has correct type but not declared as such
Expand Down
2 changes: 1 addition & 1 deletion src/library/scala/collection/immutable/Set.scala
Expand Up @@ -57,7 +57,7 @@ trait SetOps[A, +CC[X], +C <: SetOps[A, CC, C]]
@`inline` final override def - (elem: A): C = excl(elem)

def diff(that: collection.Set[A]): C =
toIterable.foldLeft(empty)((result, elem) => if (that contains elem) result else result + elem)
foldLeft(empty)((result, elem) => if (that contains elem) result else result + elem)

/** Creates a new $coll from this $coll by removing all elements of another
* collection.
Expand Down
6 changes: 3 additions & 3 deletions src/library/scala/collection/mutable/AnyRefMap.scala
Expand Up @@ -393,7 +393,7 @@ class AnyRefMap[K <: AnyRef, V] private[collection] (defaultEntry: K => V, initi
}

@deprecated("Consider requiring an immutable Map or fall back to Map.concat", "2.13.0")
override def + [V1 >: V](kv: (K, V1)): AnyRefMap[K, V1] = AnyRefMap.from(new View.Appended(toIterable, kv))
override def + [V1 >: V](kv: (K, V1)): AnyRefMap[K, V1] = AnyRefMap.from(new View.Appended(this, kv))

@deprecated("Use ++ with an explicit collection argument instead of + with varargs", "2.13.0")
override def + [V1 >: V](elem1: (K, V1), elem2: (K, V1), elems: (K, V1)*): AnyRefMap[K, V1] = {
Expand Down Expand Up @@ -477,9 +477,9 @@ class AnyRefMap[K <: AnyRef, V] private[collection] (defaultEntry: K => V, initi

// The implicit dummy parameter is necessary to distinguish these methods from the base methods they overload (not override)
def map[K2 <: AnyRef, V2](f: ((K, V)) => (K2, V2))(implicit dummy: DummyImplicit): AnyRefMap[K2, V2] =
AnyRefMap.from(new View.Map(toIterable, f))
AnyRefMap.from(new View.Map(this, f))
def flatMap[K2 <: AnyRef, V2](f: ((K, V)) => IterableOnce[(K2, V2)])(implicit dummy: DummyImplicit): AnyRefMap[K2, V2] =
AnyRefMap.from(new View.FlatMap(toIterable, f))
AnyRefMap.from(new View.FlatMap(this, f))
def collect[K2 <: AnyRef, V2](pf: PartialFunction[(K, V), (K2, V2)])(implicit dummy: DummyImplicit): AnyRefMap[K2, V2] =
strictOptimizedCollect(AnyRefMap.newBuilder[K2, V2], pf)

Expand Down
6 changes: 4 additions & 2 deletions src/library/scala/collection/mutable/Builder.scala
Expand Up @@ -68,9 +68,11 @@ trait Builder[-A, +To] extends Growable[A] { self =>
* an IndexedSeqLike, then sizes larger
* than collection's size are reduced.
*/
// should probably be `boundingColl: IterableOnce[_]`, but binary compatibility
final def sizeHintBounded(size: Int, boundingColl: scala.collection.Iterable[_]): Unit = {
if (boundingColl.knownSize != -1) {
sizeHint(scala.math.min(boundingColl.knownSize, size))
val s = boundingColl.knownSize
if (s != -1) {
sizeHint(scala.math.min(s, size))
}
}

Expand Down

0 comments on commit e41a0cc

Please sign in to comment.