Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect behavior with take on empty vector iterator #12479

Closed
adampauls opened this issue Nov 1, 2021 · 8 comments · Fixed by scala/scala#9799
Closed

Incorrect behavior with take on empty vector iterator #12479

adampauls opened this issue Nov 1, 2021 · 8 comments · Fixed by scala/scala#9799

Comments

@adampauls
Copy link

adampauls commented Nov 1, 2021

reproduction steps

using Scala 2.13.7

object Test {
  def main(args: Array[String]): Unit = {
    val xx: Vector[Int] = Vector.empty[Int]
    val rev = xx.reverseIterator
    assert(rev.isEmpty)
    val afterTake = rev.take(1)
    assert(afterTake.isEmpty) // fails but shouldn't
  }
}

problem

The second assert failes and shouldn't. Attempting to use afterTake will crash with an IndexOutOfBoundException.

@SethTisue
Copy link
Member

@scala/collections ?

@SethTisue
Copy link
Member

SethTisue commented Nov 1, 2021

minimized:

scala 2.13.7> Vector.empty[Int].reverseIterator.take(1).toList
java.lang.IndexOutOfBoundsException: 0 is out of bounds (empty vector)
  at scala.collection.immutable.Vector0$.ioob(Vector.scala:371)

@SethTisue SethTisue changed the title Incorrect behavior on empty vector iterator Incorrect behavior with take on empty vector iterator Nov 1, 2021
@som-snytt
Copy link

It is empty. res4 is the lie.

Welcome to Scala 2.13.7-20211029-123143-2d36e71 (OpenJDK 64-Bit Server VM, Java 17).
Type in expressions for evaluation. Or try :help.

scala> Vector.empty[Int]
val res0: scala.collection.immutable.Vector[Int] = Vector()

scala> .reverseIterator
val res1: Iterator[Int] = <iterator>

scala> .isEmpty
val res2: Boolean = true

scala> res1.take(1)
val res3: Iterator[Int] = <iterator>

scala> .isEmpty
val res4: Boolean = false

scala> res3.next()
java.lang.IndexOutOfBoundsException: 0 is out of bounds (empty vector)
  at scala.collection.immutable.Vector0$.ioob(Vector.scala:371)
  at scala.collection.immutable.Vector0$.apply(Vector.scala:336)
  at scala.collection.immutable.Vector0$.apply(Vector.scala:334)
  at scala.collection.SeqView$Id.apply(SeqView.scala:50)
  at scala.collection.IndexedSeqView$IndexedSeqViewReverseIterator.next(IndexedSeqView.scala:93)
  ... 34 elided

@som-snytt
Copy link

som-snytt commented Nov 2, 2021

I remember several years ago that tweaking slice iterators is so tricky.

I didn't try to understand what startCutoff and nextStartCutoff represent.

Are they releasing 2.13.8 soon? would be nice to sneak this one in.

It's an existing bug in the view, but the regression is that IndexedSeq#reverseIterator now uses view.

Welcome to Scala 2.13.6 (OpenJDK 64-Bit Server VM, Java 17).
Type in expressions for evaluation. Or try :help.

scala> Vector.empty[Int].view
val res0: scala.collection.IndexedSeqView[Int] = IndexedSeqView(<not computed>)

scala> .reverseIterator
val res1: Iterator[Int] = <iterator>

scala> .take(1)
val res2: Iterator[Int] = <iterator>

scala> .isEmpty
val res3: Boolean = false

@SethTisue
Copy link
Member

Ah, I hadn't realized this was a 2.13.7 specific regression. Presumably from scala/scala#9258.

This does put some pressure on us not to wait as long this time before building 2.13.8. (There was a five and a half month gap after 2.13.6.) I'm not sure how much pressure.

@som-snytt
Copy link

Yes, that's the one. I was going to joke that it really does fail faster. Just a little iterator humo(u)r.

@NthPortal
Copy link

NthPortal commented Nov 2, 2021

yup, I think you're right about the cause Seth. technically not my bug, but my fault it now happens without calling view first

@NthPortal
Copy link

@SethTisue there's also a ticket I opened for a CVE that should probably get fixed and be released ASAP, if that's motivation for a quick 2.13.8

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment