It appear Range equality no longer works correctly in scala 2.11 (was correct in 2.10)
first the symptoms:
Range(0,0) == Range(10,100,10)
res0: Boolean = true
and
Range(0,1) == Range(0,0)
java.util.NoSuchElementException
at scala.collection.LinearSeqOptimized$class.last(LinearSeqOptimized.scala:134)
at scala.collection.immutable.List.last(List.scala:83)
at scala.collection.immutable.Range.last(Range.scala:107)
at scala.collection.immutable.Range.equals(Range.scala:371)
... 32 elided
looking at the code, the following commit seems to be responsible:
https://github.com/scala/scala/commit/e152297090c26051b7e9a6a1740c4670d23d9d5d
we used to have a check (length == x.length) which was removed.
The current code, if the first Range is empty it will be equal to any Range
when the second isEmpty and the first is not empty and begins with 0 it will throw an exception when accessing last on the empty Range.
This is my suggested fix (addition is blue):
override def equals(other: Any) = other match {
case x: Range =>
// Note: this must succeed for overfull ranges (length > Int.MaxValue)
(x canEqual this) && (
(isEmpty && x.isEmpty) || // all empty sequences are equal
(nonEmpty && x.nonEmpty && start == x.start && { // Otherwise, must have same start
val l0 = last
(l0 == x.last && ( // And same end
start == l0 || step == x.step // And either the same step, or not take any steps
))
})
)
case _ =>
super.equals(other)
}
-------------------------------------------------------------------
Minor correction: for the exception to occur the empty range must have the same start as the first range.
Evidently empty Ranges still can have a different starting position (which seems funny to me)
The text was updated successfully, but these errors were encountered:
See: https://groups.google.com/forum/#!topic/scala-internals/wDXhYFBINs4
The text was updated successfully, but these errors were encountered: