summaryrefslogtreecommitdiff
path: root/src/library/scala/collection/immutable/Stream.scala
diff options
context:
space:
mode:
authorErik Osheim <d_m@plastic-idolatry.com>2013-12-24 15:52:17 -0500
committerErik Osheim <d_m@plastic-idolatry.com>2013-12-24 15:58:50 -0500
commit2477bbd9d64df3dbfac063e1fc71115daf0f3ea7 (patch)
treeb0dc9f7b266fd4746ddc4eb8393bcf55f7562cb7 /src/library/scala/collection/immutable/Stream.scala
parent9f0594c57716ed551918e15be6da843982e8ba12 (diff)
downloadscala-2477bbd9d64df3dbfac063e1fc71115daf0f3ea7.tar.gz
scala-2477bbd9d64df3dbfac063e1fc71115daf0f3ea7.tar.bz2
scala-2477bbd9d64df3dbfac063e1fc71115daf0f3ea7.zip
SI-8100 - prevent possible SOE during Stream#flatten.
This commit changes stream flatten to avoid allocating a stack frame for every stream item. Previously, flattening a stream whose elements are mostly empty would result in a StackOverflowException. This commit also adds a test demonstrating the problem.
Diffstat (limited to 'src/library/scala/collection/immutable/Stream.scala')
-rw-r--r--src/library/scala/collection/immutable/Stream.scala18
1 files changed, 10 insertions, 8 deletions
diff --git a/src/library/scala/collection/immutable/Stream.scala b/src/library/scala/collection/immutable/Stream.scala
index 5e1de44749..e6e4d6ec18 100644
--- a/src/library/scala/collection/immutable/Stream.scala
+++ b/src/library/scala/collection/immutable/Stream.scala
@@ -960,14 +960,16 @@ self =>
* }}}
*/
override def flatten[B](implicit asTraversable: A => /*<:<!!!*/ GenTraversableOnce[B]): Stream[B] = {
- def flatten1(t: Traversable[B]): Stream[B] =
- if (!t.isEmpty)
- cons(t.head, flatten1(t.tail))
- else
- tail.flatten
-
- if (isEmpty) Stream.empty
- else flatten1(asTraversable(head).seq.toTraversable)
+ var st: Stream[A] = this
+ while (st.nonEmpty) {
+ val h = asTraversable(st.head)
+ if (h.isEmpty) {
+ st = st.tail
+ } else {
+ return h.toStream #::: st.tail.flatten
+ }
+ }
+ Stream.empty
}
override def view = new StreamView[A, Stream[A]] {