summaryrefslogtreecommitdiff
path: root/src/library/scala/collection/mutable/SetLike.scala
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2013-08-22 23:51:15 +0200
committerJason Zaugg <jzaugg@gmail.com>2013-08-29 16:03:39 +0200
commitfe9a3e9c5ef2d2de5fa62a14fa4a613a573e5e5f (patch)
tree1810fadccc121b41d2f501315edf47b98f395b66 /src/library/scala/collection/mutable/SetLike.scala
parent7b351dca8458f599f5fafef4daa307351031ef06 (diff)
downloadscala-fe9a3e9c5ef2d2de5fa62a14fa4a613a573e5e5f.tar.gz
scala-fe9a3e9c5ef2d2de5fa62a14fa4a613a573e5e5f.tar.bz2
scala-fe9a3e9c5ef2d2de5fa62a14fa4a613a573e5e5f.zip
SI-7269 Rework MapLike#retains to account for desugaring change
`MapLike#retains` contains a for-comprehension that relied on the strict `filter` by its generator. You can't, in general, iterate a mutable map and remove items in the same pass. Here's the history of the desugaring of: def retain[A, B](thiz: mutable.Map[A, B])(p: (A, B) => Boolean): thiz.type = { thiz.foreach { case (k, v) => if (p(k, v)) thiz -= k } Before regression (c82ecabad6~1): thiz.filter(((check$ifrefutable$1) => check$ifrefutable$1: @scala.unchecked match { case scala.Tuple2((k @ _), (v @ _)) => true case _ => false })).withFilter(((x$1) => x$1: @scala.unchecked match { case scala.Tuple2((k @ _), (v @ _)) => p(k, v).unary_$bang })).foreach(((x$2) => x$2: @scala.unchecked match { case scala.Tuple2((k @ _), (v @ _)) => thiz.$minus$eq(k) })); After regression (c82ecabad6, which incorrectly assumed in the parser that no filter is required for isInstanceOf[Tuple2]) thiz.withFilter(((x$1) => x$1: @scala.unchecked match { case scala.Tuple2((k @ _), (v @ _)) => p(k, v).unary_$bang })).foreach(((x$2) => x$2: @scala.unchecked match { case scala.Tuple2((k @ _), (v @ _)) => thiz.$minus$eq(k) })); After the reversion of c82ecabad6, v2.10.2 This is also after 365bb2b4e, which uses `withFilter` rather than `filter`. thiz.withFilter(((check$q$1) => check$ifrefutable$1: @scala.unchecked match { case scala.Tuple2((k @ _), (v @ _)) => true case _ => false })).withFilter(((x$1) => x$1: @scala.unchecked match { case scala.Tuple2((k @ _), (v @ _)) => p(k, v).unary_$bang })).foreach(((x$2) => x$2: @scala.unchecked match { case scala.Tuple2((k @ _), (v @ _)) => thiz.$minus$eq(k) })); This commit does the same as `SetLike#retains`, and converts the map to an immutable list before the rest of the operation.
Diffstat (limited to 'src/library/scala/collection/mutable/SetLike.scala')
-rw-r--r--src/library/scala/collection/mutable/SetLike.scala4
1 files changed, 3 insertions, 1 deletions
diff --git a/src/library/scala/collection/mutable/SetLike.scala b/src/library/scala/collection/mutable/SetLike.scala
index 01f87447ae..71da4c89dc 100644
--- a/src/library/scala/collection/mutable/SetLike.scala
+++ b/src/library/scala/collection/mutable/SetLike.scala
@@ -120,7 +120,9 @@ trait SetLike[A, +This <: SetLike[A, This] with Set[A]]
* which `p` returns `true` are retained in the set; all others
* are removed.
*/
- def retain(p: A => Boolean): Unit = for (elem <- this.toList) if (!p(elem)) this -= elem
+ def retain(p: A => Boolean): Unit =
+ for (elem <- this.toList) // SI-7269 toList avoids ConcurrentModificationException
+ if (!p(elem)) this -= elem
/** Removes all elements from the set. After this operation is completed,
* the set will be empty.