summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2010-04-08 18:12:34 +0000
committerPaul Phillips <paulp@improving.org>2010-04-08 18:12:34 +0000
commitad0cb2873fd3339445ede746b0120ff775bee51d (patch)
tree6e271a88475825ec77eb622d09f93ad188a10e93
parent0e437ba3095d732430a8b8cbd468aa74e5b307fe (diff)
downloadscala-ad0cb2873fd3339445ede746b0120ff775bee51d.tar.gz
scala-ad0cb2873fd3339445ede746b0120ff775bee51d.tar.bz2
scala-ad0cb2873fd3339445ede746b0120ff775bee51d.zip
Fix and test for Iterator corner case.
-rw-r--r--src/library/scala/collection/Iterator.scala7
-rw-r--r--test/files/run/bug3269.check2
-rw-r--r--test/files/run/bug3269.scala9
3 files changed, 16 insertions, 2 deletions
diff --git a/src/library/scala/collection/Iterator.scala b/src/library/scala/collection/Iterator.scala
index 701b24f300..2ee4e8056e 100644
--- a/src/library/scala/collection/Iterator.scala
+++ b/src/library/scala/collection/Iterator.scala
@@ -374,9 +374,12 @@ trait Iterator[+A] extends TraversableOnce[A] {
def ++[B >: A](that: => Iterator[B]): Iterator[B] = new Iterator[B] {
// optimize a little bit to prevent n log n behavior.
private var cur : Iterator[B] = self
- // this was unnecessarily looping forever on x ++ x
+ // since that is by-name, make sure it's only referenced once -
+ // if "val it = that" is inside the block, then hasNext on an empty
+ // iterator will continually reevaluate it. (ticket #3269)
+ lazy val it = that
+ // the eq check is to avoid an infinite loop on "x ++ x"
def hasNext = cur.hasNext || ((cur eq self) && {
- val it = that
it.hasNext && {
cur = it
true
diff --git a/test/files/run/bug3269.check b/test/files/run/bug3269.check
new file mode 100644
index 0000000000..c25611c15c
--- /dev/null
+++ b/test/files/run/bug3269.check
@@ -0,0 +1,2 @@
+1
+Hello
diff --git a/test/files/run/bug3269.scala b/test/files/run/bug3269.scala
new file mode 100644
index 0000000000..17e42cdb0e
--- /dev/null
+++ b/test/files/run/bug3269.scala
@@ -0,0 +1,9 @@
+object Test {
+ def main(args: Array[String]): Unit = {
+ val it = List(1).iterator ++ { println("Hello"); Iterator.empty }
+ println(it.next)
+ it.hasNext
+ it.hasNext
+ it.hasNext
+ }
+}