diff --git a/src/library/scala/collection/immutable/LazyList.scala b/src/library/scala/collection/immutable/LazyList.scala index dde413bd91ce..b532335999cb 100644 --- a/src/library/scala/collection/immutable/LazyList.scala +++ b/src/library/scala/collection/immutable/LazyList.scala @@ -249,6 +249,14 @@ final class LazyList[+A] private(private[this] var lazyState: () => LazyList.Sta @inline private def stateDefined: Boolean = stateEvaluated private[this] var midEvaluation = false + // see scala/scala#10118 + private def withNullLazyState[T](f: => T): T = { + val saved = lazyState + lazyState = null + try f + finally lazyState = saved + } + private lazy val state: State[A] = { // if it's already mid-evaluation, we're stuck in an infinite // self-referential loop (also it's empty) @@ -1370,7 +1378,7 @@ object LazyList extends SeqFactory[LazyList] { case a => init += a.asInstanceOf[A] } val tail = in.readObject().asInstanceOf[LazyList[A]] - coll = init ++: tail + coll = tail.withNullLazyState(tail.prependedAll(init)) } private[this] def readResolve(): Any = coll diff --git a/test/junit/scala/collection/immutable/LazyListTest.scala b/test/junit/scala/collection/immutable/LazyListTest.scala index 58798ec4cb9d..6a360f184679 100644 --- a/test/junit/scala/collection/immutable/LazyListTest.scala +++ b/test/junit/scala/collection/immutable/LazyListTest.scala @@ -14,6 +14,34 @@ import scala.util.Try @RunWith(classOf[JUnit4]) class LazyListTest { + @Test + def serialization(): Unit = { + import java.io._ + + def serialize(obj: AnyRef): Array[Byte] = { + val buffer = new ByteArrayOutputStream + val out = new ObjectOutputStream(buffer) + out.writeObject(obj) + buffer.toByteArray + } + def deserialize(a: Array[Byte]): AnyRef = { + val in = new ObjectInputStream(new ByteArrayInputStream(a)) + in.readObject + } + + def serializeDeserialize[T <: AnyRef](obj: T) = deserialize(serialize(obj)).asInstanceOf[T] + + val l = LazyList.from(10) + val ld = serializeDeserialize(l) + assertEquals(ld.toString, "LazyList()") + ld.head + assertEquals(ld.toString, "LazyList(10, )") + ld.tail.head + assertEquals(ld.toString, "LazyList(10, 11, )") + ld.tail.tail.head + assertEquals(ld.toString, "LazyList(10, 11, 12, )") + } + @Test def t6727_and_t6440_and_8627(): Unit = { assertTrue(LazyList.continually(()).filter(_ => true).take(2) == Seq((), ()))