Problem:
- Iterator.toIndexedSeq skips the first element if Iterator.hasNext changes some internal state.
- Iterator's hasNext() will be called multiple times, so if the code is expecting that hasNext() will be called only once and changing some internal state, some elements will be skipped in the generated IndexedSeq.
- This behavior is introduced after Scala 2.13.0-M5.
- Iterator.haxNext() implementation that are not idempotent will produce broken results with this change, even though ideally all of the implementations of Iterator.haxNext() should be idempotent.
Code Example
class MyIterator extends Iterator[Int] {
private var i = 0
def hasNext: Boolean = {
val flag = i < 2
i += 1
flag
}
def next:Int = i
}
object Example {
def main(args:Array[String]): Unit = {
val s = new MyIterator().toIndexedSeq
println(s.mkString(", ")) // Expected 1,2, but 2.13.0-pre-59975bb produces 2
}
}
This code is in https://github.com/xerial/scala-bug-repro
How to reproduce:
$ git clone https://github.com/xerial/scala-bug-repro
$ cd scala-bug-repo
$ sbt run
...
2
For the other Scala versions
$ sbt
> ++ 2.12.8!
> run
1, 2
This behavior is found at #11453
Cause
VectorBuilder.addAll calls the Iterator.hasNext to check whether it should advance to the next block or not:
while (it.hasNext) { // The first call is here
advanceToNextBlockIfNecessary()
lo += it.copyToArray(xs = display0, start = lo, len = display0.length - lo) // The next call happens here
}
Related change: scala/scala#7588
Problem:
next()https://docs.oracle.com/javase/8/docs/api/java/util/Iterator.html#hasNext--Code Example
This code is in https://github.com/xerial/scala-bug-repro
How to reproduce:
For the other Scala versions
This behavior is found at #11453
Cause
VectorBuilder.addAll calls the Iterator.hasNext to check whether it should advance to the next block or not:
Related change: scala/scala#7588