summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2010-01-18 04:14:25 +0000
committerPaul Phillips <paulp@improving.org>2010-01-18 04:14:25 +0000
commitd73a32db9cb0357cb365b78bdbd0fa8d6af9873c (patch)
treec2fb02af2ce89f94d75c285a5b30a86b260be600
parent518ac3d5fd113e24df9cba5383a0bc9641b41f1d (diff)
downloadscala-d73a32db9cb0357cb365b78bdbd0fa8d6af9873c.tar.gz
scala-d73a32db9cb0357cb365b78bdbd0fa8d6af9873c.tar.bz2
scala-d73a32db9cb0357cb365b78bdbd0fa8d6af9873c.zip
Fix and test case for #408. Review by community.
-rw-r--r--src/library/scala/collection/immutable/HashSet.scala15
-rw-r--r--test/files/run/bug408.scala12
2 files changed, 21 insertions, 6 deletions
diff --git a/src/library/scala/collection/immutable/HashSet.scala b/src/library/scala/collection/immutable/HashSet.scala
index 25a8059b0c..2320187be9 100644
--- a/src/library/scala/collection/immutable/HashSet.scala
+++ b/src/library/scala/collection/immutable/HashSet.scala
@@ -115,17 +115,20 @@ class HashSet[A] extends Set[A]
private def makeCopy(last: HashSet[A]) {
def undo(m: HashSet[A]) {
- if (m ne last) {
- undo(m.later)
- if (m.deleted) addEntry(m.changedElem)
- else removeEntry(m.changedElem)
- }
+ if (m.deleted) addEntry(m.changedElem)
+ else removeEntry(m.changedElem)
}
table = new scala.Array[AnyRef](last.table.length)
scala.Array.copy(last.table, 0, table, 0, table.length)
tableSize = last.tableSize
threshold = last.threshold
- undo(this)
+
+ // we need to work from the end of the list but non-tail-recursion
+ // potentially blows the stack, so instead we create a stack on the heap.
+ // See ticket #408.
+ val toUndo = new mutable.Stack[HashSet[A]]
+ toUndo pushAll ((Iterator iterate this)(_.later) takeWhile (_ ne last))
+ toUndo foreach undo
later = null
}
diff --git a/test/files/run/bug408.scala b/test/files/run/bug408.scala
new file mode 100644
index 0000000000..9e51e881ed
--- /dev/null
+++ b/test/files/run/bug408.scala
@@ -0,0 +1,12 @@
+object Test
+{
+ val a = scala.collection.immutable.Set.empty ++ (0 to 100000)
+ val b = scala.collection.immutable.Set.empty ++ (0 to 100000)
+
+ def main(args: Array[String]): Unit = {
+ a -- b
+ a -- b
+ a -- b
+ a -- b
+ }
+}