Skip to content

Commit

Permalink
Merge pull request #10106 from som-snytt/issue/11697-linearseqops-isE…
Browse files Browse the repository at this point in the history
…mpty

Improve Scaladoc for LinearSeqOps isEmpty, head, tail
  • Loading branch information
lrytz committed Aug 16, 2022
2 parents a2db097 + cd92a52 commit 41620c5
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 6 deletions.
18 changes: 16 additions & 2 deletions src/library/scala/collection/LinearSeq.scala
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,23 @@ object LinearSeq extends SeqFactory.Delegate[LinearSeq](immutable.LinearSeq)
/** Base trait for linear Seq operations */
trait LinearSeqOps[+A, +CC[X] <: LinearSeq[X], +C <: LinearSeq[A] with LinearSeqOps[A, CC, C]] extends Any with SeqOps[A, CC, C] {

// To be overridden in implementations:
def isEmpty: Boolean
/** @inheritdoc
*
* Note: *Must* be overridden in subclasses. The default implementation that is inherited from [[SeqOps]]
* uses `lengthCompare`, which is defined here to use `isEmpty`.
*/
override def isEmpty: Boolean

/** @inheritdoc
*
* Note: *Must* be overridden in subclasses. The default implementation is inherited from [[IterableOps]].
*/
def head: A

/** @inheritdoc
*
* Note: *Must* be overridden in subclasses. The default implementation is inherited from [[IterableOps]].
*/
def tail: C

override def headOption: Option[A] =
Expand Down
30 changes: 26 additions & 4 deletions test/junit/scala/collection/LinearSeqTest.scala
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
package scala.collection

import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import org.junit.Assert.{assertEquals, assertTrue}
import scala.tools.testkit.AssertUtil.assertThrows

@RunWith(classOf[JUnit4])
class LinearSeqTest {
// Tests regression on issue 11262
@Test def extensionIteratorTest(): Unit = {
Expand All @@ -17,6 +16,29 @@ class LinearSeqTest {
val x = new ConstantLinearSeq(4, 7)

val it = x.iterator // The main thing we want to test is that this does not throw an exception
assert(it.hasNext == true) // Call it at least once so that it won't be optimized away
assertTrue(it.hasNext) // Call it at least once so that it won't be optimized away
}

// LinearSeqOps used isEmpty from SeqOps, which used lengthCompare, but LSO.lengthCompare used isEmpty
@Test def `linear seq is incoherent`: Unit = {
val ls = new LinearSeq[Int] {
var count = 0
override def isEmpty = {
if (count > 5) throw new IllegalStateException("limit")
count += 1
super.isEmpty
}
}
assertThrows[IllegalStateException](ls.toString, _ == "limit")
assertThrows[IllegalStateException](ls.head, _ == "limit")
assertThrows[IllegalStateException](ls.tail, _ == "limit")
}
@Test def `linear seq is semicoherent`: Unit = {
val ls = new LinearSeq[Int] {
override def isEmpty = true
}
assertEquals("LinearSeq()", ls.toString)
assertThrows[NoSuchElementException](ls.head)
assertThrows[UnsupportedOperationException](ls.tail)
}
}

0 comments on commit 41620c5

Please sign in to comment.