Skip to content

Commit 7589e80

Browse files
authored
Merge pull request scala/scala#10818 from NthPortal/ll-better-error/PR
Improve `LazyList` self-reference error
2 parents f9d396f + fd8087d commit 7589e80

File tree

1 file changed

+25
-2
lines changed

1 file changed

+25
-2
lines changed

library/src/scala/collection/immutable/LazyList.scala

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ import scala.runtime.Statics
166166
* loop("Iterator3: ", it3.next(), it3)
167167
* }}}
168168
*
169-
* - In the `fibs` example earlier, the fact that `tail` works at all is of interest.
169+
* In the `fibs` example earlier, the fact that `tail` works at all is of interest.
170170
* `fibs` has an initial `(0, 1, LazyList(...))`, so `tail` is deterministic.
171171
* If we defined `fibs` such that only `0` were concretely known, then the act
172172
* of determining `tail` would require the evaluation of `tail`, so the
@@ -218,6 +218,27 @@ import scala.runtime.Statics
218218
* filtered.isEmpty // prints "getting empty LazyList"
219219
* }}}
220220
*
221+
* ----
222+
*
223+
* You may sometimes encounter an exception like the following:
224+
*
225+
* {{{
226+
* java.lang.RuntimeException: "LazyList evaluation depends on its own result (self-reference); see docs for more info
227+
* }}}
228+
*
229+
* This exception occurs when a `LazyList` is attempting to derive its next element
230+
* from itself, and is attempting to read the element currently being evaluated. A
231+
* trivial example of such might be
232+
*
233+
* {{{
234+
* lazy val a: LazyList[Int] = 1 #:: 2 #:: a.filter(_ > 2)
235+
* }}}
236+
*
237+
* When attempting to evaluate the third element of `a`, it will skip the first two
238+
* elements and read the third, but that element is already being evaluated. This is
239+
* often caused by a subtle logic error; in this case, using `>=` in the `filter`
240+
* would fix the error.
241+
*
221242
* @tparam A the type of the elements contained in this lazy list.
222243
*
223244
* @see [[https://docs.scala-lang.org/overviews/collections-2.13/concrete-immutable-collection-classes.html#lazylists "Scala's Collection Library overview"]]
@@ -253,7 +274,9 @@ final class LazyList[+A] private(private[this] var lazyState: () => LazyList.Sta
253274
// if it's already mid-evaluation, we're stuck in an infinite
254275
// self-referential loop (also it's empty)
255276
if (midEvaluation) {
256-
throw new RuntimeException("self-referential LazyList or a derivation thereof has no more elements")
277+
throw new RuntimeException(
278+
"LazyList evaluation depends on its own result (self-reference); see docs for more info"
279+
)
257280
}
258281
midEvaluation = true
259282
val res = try lazyState() finally midEvaluation = false

0 commit comments

Comments
 (0)