From 8e0a386508d6cb655db0a29a23fb26170b262548 Mon Sep 17 00:00:00 2001 From: Szabolcs Berecz Date: Sat, 14 Mar 2015 01:27:02 +0100 Subject: SI-9219 Stream toString returns unexpected result - Cursor was not advanced before appending the second element when only the first two elements of the stream were known. - When there is no cycle in the stream, the "scout" (and "cursor") ends up pointing to a stream where tailDefined is false. This means that cursor is either empty, or cursor.tail is not yet evaluated. The former case is handled properly, but in the latter case, one more element (cursor.head) needs to be appended. --- src/library/scala/collection/immutable/Stream.scala | 21 +++++++++++++-------- test/files/run/t9219.check | 3 +++ test/files/run/t9219.scala | 11 +++++++++++ 3 files changed, 27 insertions(+), 8 deletions(-) create mode 100644 test/files/run/t9219.check create mode 100644 test/files/run/t9219.scala diff --git a/src/library/scala/collection/immutable/Stream.scala b/src/library/scala/collection/immutable/Stream.scala index 9ed5162061..f303e79bb3 100644 --- a/src/library/scala/collection/immutable/Stream.scala +++ b/src/library/scala/collection/immutable/Stream.scala @@ -743,16 +743,18 @@ self => b append end return b } - if ((cursor ne scout) && scout.tailDefined) { + if (cursor ne scout) { cursor = scout - scout = scout.tail - // Use 2x 1x iterator trick for cycle detection; slow iterator can add strings - while ((cursor ne scout) && scout.tailDefined) { - b append sep append cursor.head - n += 1 - cursor = cursor.tail + if (scout.tailDefined) { scout = scout.tail - if (scout.tailDefined) scout = scout.tail + // Use 2x 1x iterator trick for cycle detection; slow iterator can add strings + while ((cursor ne scout) && scout.tailDefined) { + b append sep append cursor.head + n += 1 + cursor = cursor.tail + scout = scout.tail + if (scout.tailDefined) scout = scout.tail + } } } if (!scout.tailDefined) { // Not a cycle, scout hit an end @@ -761,6 +763,9 @@ self => n += 1 cursor = cursor.tail } + if (cursor.nonEmpty) { + b append sep append cursor.head + } } else { // Cycle. diff --git a/test/files/run/t9219.check b/test/files/run/t9219.check new file mode 100644 index 0000000000..3509ece003 --- /dev/null +++ b/test/files/run/t9219.check @@ -0,0 +1,3 @@ +Stream(1, 2, ?) +Stream(1, 2, 3, 4, ?) +Stream(1, 2, 3, 4, 5, 6, ?) diff --git a/test/files/run/t9219.scala b/test/files/run/t9219.scala new file mode 100644 index 0000000000..c15f55faac --- /dev/null +++ b/test/files/run/t9219.scala @@ -0,0 +1,11 @@ +object Test extends App { + def check[U](f: Stream[Int] => U) = { + val s = Stream.from(1) + f(s) + println(s) + } + + check(_.tail) + check(_.take(4).force) + check(_(5)) +} -- cgit v1.2.3