diff --git a/src/library/scala/collection/Iterator.scala b/src/library/scala/collection/Iterator.scala index 3fe18e948f53..7843788ea4fb 100644 --- a/src/library/scala/collection/Iterator.scala +++ b/src/library/scala/collection/Iterator.scala @@ -1257,12 +1257,15 @@ object Iterator extends IterableFactory[Iterator] { else if (until <= lo) 0 // empty else if (unbounded) until - lo // now finite else adjustedBound min (until - lo) // keep lesser bound + val sum = dropping + lo if (rest == 0) empty + else if (sum < 0) { + dropping = Int.MaxValue + remaining = 0 + this.concat(new SliceIterator(underlying, start = sum - Int.MaxValue, limit = rest)) + } else { - dropping = { - val sum = dropping + lo - if (sum < 0) Int.MaxValue else sum - } + dropping = sum remaining = rest this } diff --git a/test/junit/scala/collection/IteratorTest.scala b/test/junit/scala/collection/IteratorTest.scala index 3b1eec14af75..dcc7d59bb906 100644 --- a/test/junit/scala/collection/IteratorTest.scala +++ b/test/junit/scala/collection/IteratorTest.scala @@ -221,6 +221,15 @@ class IteratorTest { assertSameElements(List(3) ++ List(1, 2, 3).reverseIterator.drop(1), List(3, 2, 1)) } + @Test def `drop does overflow t13052`: Unit = { + var counter = 0L + val it = Iterator.continually(counter.tap(_ => counter += 1)) + val n = 1_000_000_000 + val dropped = it.drop(n).drop(n).drop(n).drop(50) + assertEquals(3L * n + 50L, dropped.next()) + assertEquals(3L * n + 100L, dropped.drop(49).next()) + } + @Test def dropIsChainable(): Unit = { assertSameElements(1 to 4, Iterator from 0 take 5 drop 1) assertSameElements(3 to 4, Iterator from 0 take 5 drop 3) @@ -891,7 +900,7 @@ class IteratorTest { } @Test - def t11106(): Unit = { + def `t11106 still lazy after withFilter`: Unit = { var i = 0 Iterator.continually(0) .map(_ => {i += 1; i})