diff options
author | Rui Gonçalves <ruippeixotog@gmail.com> | 2015-10-21 21:22:18 +0100 |
---|---|---|
committer | Rui Gonçalves <ruippeixotog@gmail.com> | 2015-10-21 21:22:18 +0100 |
commit | e7079ca36aef1b74696f50fbdfe11d99273274d7 (patch) | |
tree | 9acfd6f8da0a4691d69ad968d15e7f79f9053c7b | |
parent | ba173164c700698d9469bf289b7b40cc11b4262d (diff) | |
download | scala-e7079ca36aef1b74696f50fbdfe11d99273274d7.tar.gz scala-e7079ca36aef1b74696f50fbdfe11d99273274d7.tar.bz2 scala-e7079ca36aef1b74696f50fbdfe11d99273274d7.zip |
SI-9497 Fix SetLike#clear() default implementation
When dealing with mutable collections, it is not safe to assume iterators will remain consistent when the collection is modified mid-traversal. The bug reported in SI-9497 is very similar to SI-7269, "ConcurrentModificationException when filtering converted Java HashMap". Then, only the `retain` method was fixed. This commit fixes `clear`, which had the same problem.
-rw-r--r-- | src/library/scala/collection/mutable/SetLike.scala | 4 | ||||
-rw-r--r-- | test/junit/scala/collection/mutable/SetLikeTest.scala | 26 |
2 files changed, 29 insertions, 1 deletions
diff --git a/src/library/scala/collection/mutable/SetLike.scala b/src/library/scala/collection/mutable/SetLike.scala index 81a71adc91..01075a2633 100644 --- a/src/library/scala/collection/mutable/SetLike.scala +++ b/src/library/scala/collection/mutable/SetLike.scala @@ -129,7 +129,9 @@ trait SetLike[A, +This <: SetLike[A, This] with Set[A]] /** Removes all elements from the set. After this operation is completed, * the set will be empty. */ - def clear() { foreach(-=) } + def clear(): Unit = + for (elem <- this.toList) + this -= elem override def clone(): This = empty ++= repr.seq diff --git a/test/junit/scala/collection/mutable/SetLikeTest.scala b/test/junit/scala/collection/mutable/SetLikeTest.scala new file mode 100644 index 0000000000..c819024558 --- /dev/null +++ b/test/junit/scala/collection/mutable/SetLikeTest.scala @@ -0,0 +1,26 @@ +package scala.collection.mutable + +import org.junit.Assert._ +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 + +@RunWith(classOf[JUnit4]) +class SetLikeTest { + + class MySet(self: Set[String]) extends Set[String] with SetLike[String, MySet] { + override def -=(elem: String) = { self -= elem; this } + override def +=(elem: String) = { self += elem; this } + + override def empty = new MySet(self.empty) + override def iterator = self.iterator + override def contains(elem: String) = self.contains(elem) + } + + @Test + def hasCorrectClear() { + val s = new MySet(Set("EXPOSEDNODE", "CONNECTABLE")) + s.clear() + assertEquals(new MySet(Set()), s) + } +} |