@@ -24,6 +24,7 @@ import scala.language.implicitConversions
24
24
import scala .runtime .Statics
25
25
import language .experimental .captureChecking
26
26
import annotation .unchecked .uncheckedCaptures
27
+ import caps .untrackedCaptures
27
28
28
29
/** This class implements an immutable linked list. We call it "lazy"
29
30
* because it computes its elements only when they are needed.
@@ -245,14 +246,16 @@ import annotation.unchecked.uncheckedCaptures
245
246
* @define evaluatesAllElements This method evaluates all elements of the collection.
246
247
*/
247
248
@ SerialVersionUID (3L )
248
- final class LazyListIterable [+ A ] private (private [ this ] var lazyState : () => LazyListIterable .State [A ]^ )
249
+ final class LazyListIterable [+ A ] private (@ untrackedCaptures lazyState : () => LazyListIterable .State [A ]^ )
249
250
extends AbstractIterable [A ]
250
251
with Iterable [A ]
251
252
with IterableOps [A , LazyListIterable , LazyListIterable [A ]]
252
253
with IterableFactoryDefaults [A , LazyListIterable ]
253
254
with Serializable {
254
255
import LazyListIterable ._
255
256
257
+ private var myLazyState = lazyState
258
+
256
259
@ volatile private [this ] var stateEvaluated : Boolean = false
257
260
@ inline private def stateDefined : Boolean = stateEvaluated
258
261
private [this ] var midEvaluation = false
@@ -264,11 +267,11 @@ final class LazyListIterable[+A] private(private[this] var lazyState: () => Lazy
264
267
throw new RuntimeException (" self-referential LazyListIterable or a derivation thereof has no more elements" )
265
268
}
266
269
midEvaluation = true
267
- val res = try lazyState () finally midEvaluation = false
270
+ val res = try myLazyState () finally midEvaluation = false
268
271
// if we set it to `true` before evaluating, we may infinite loop
269
272
// if something expects `state` to already be evaluated
270
273
stateEvaluated = true
271
- lazyState = null // allow GC
274
+ myLazyState = null // allow GC
272
275
res
273
276
}
274
277
@@ -755,7 +758,7 @@ final class LazyListIterable[+A] private(private[this] var lazyState: () => Lazy
755
758
* The iterator returned by this method mostly preserves laziness;
756
759
* a single element ahead of the iterator is evaluated.
757
760
*/
758
- override def grouped (size : Int ): Iterator [LazyListIterable [A ]] = {
761
+ override def grouped (size : Int ): Iterator [LazyListIterable [A ]]^ { this } = {
759
762
require(size > 0 , " size must be positive, but was " + size)
760
763
slidingImpl(size = size, step = size)
761
764
}
@@ -765,12 +768,12 @@ final class LazyListIterable[+A] private(private[this] var lazyState: () => Lazy
765
768
* The iterator returned by this method mostly preserves laziness;
766
769
* `size - step max 1` elements ahead of the iterator are evaluated.
767
770
*/
768
- override def sliding (size : Int , step : Int ): Iterator [LazyListIterable [A ]] = {
771
+ override def sliding (size : Int , step : Int ): Iterator [LazyListIterable [A ]]^ { this } = {
769
772
require(size > 0 && step > 0 , s " size= $size and step= $step, but both must be positive " )
770
773
slidingImpl(size = size, step = step)
771
774
}
772
775
773
- @ inline private def slidingImpl (size : Int , step : Int ): Iterator [LazyListIterable [A ]] =
776
+ @ inline private def slidingImpl (size : Int , step : Int ): Iterator [LazyListIterable [A ]]^ { this } =
774
777
if (knownIsEmpty) Iterator .empty
775
778
else new SlidingIterator [A ](this , size = size, step = step)
776
779
@@ -996,7 +999,7 @@ object LazyListIterable extends IterableFactory[LazyListIterable] {
996
999
997
1000
private def filterImpl [A ](ll : LazyListIterable [A ]^ , p : A => Boolean , isFlipped : Boolean ): LazyListIterable [A ]^ {ll, p} = {
998
1001
// DO NOT REFERENCE `ll` ANYWHERE ELSE, OR IT WILL LEAK THE HEAD
999
- var restRef : LazyListIterable [A ]^ {ll* } = ll // restRef is captured by closure arg to newLL, so A is not recognized as parametric
1002
+ var restRef : LazyListIterable [A ]^ {ll} = ll // restRef is captured by closure arg to newLL, so A is not recognized as parametric
1000
1003
newLL {
1001
1004
var elem : A = null .asInstanceOf [A ]
1002
1005
var found = false
@@ -1013,7 +1016,7 @@ object LazyListIterable extends IterableFactory[LazyListIterable] {
1013
1016
1014
1017
private def collectImpl [A , B ](ll : LazyListIterable [A ]^ , pf : PartialFunction [A , B ]^ ): LazyListIterable [B ]^ {ll, pf} = {
1015
1018
// DO NOT REFERENCE `ll` ANYWHERE ELSE, OR IT WILL LEAK THE HEAD
1016
- var restRef : LazyListIterable [A ]^ {ll* } = ll // restRef is captured by closure arg to newLL, so A is not recognized as parametric
1019
+ var restRef : LazyListIterable [A ]^ {ll} = ll // restRef is captured by closure arg to newLL, so A is not recognized as parametric
1017
1020
newLL {
1018
1021
val marker = Statics .pfMarker
1019
1022
val toMarker = anyToMarker.asInstanceOf [A => B ] // safe because Function1 is erased
@@ -1032,7 +1035,7 @@ object LazyListIterable extends IterableFactory[LazyListIterable] {
1032
1035
1033
1036
private def flatMapImpl [A , B ](ll : LazyListIterable [A ]^ , f : A => IterableOnce [B ]^ ): LazyListIterable [B ]^ {ll, f} = {
1034
1037
// DO NOT REFERENCE `ll` ANYWHERE ELSE, OR IT WILL LEAK THE HEAD
1035
- var restRef : LazyListIterable [A ]^ {ll* } = ll // restRef is captured by closure arg to newLL, so A is not recognized as parametric
1038
+ var restRef : LazyListIterable [A ]^ {ll} = ll // restRef is captured by closure arg to newLL, so A is not recognized as parametric
1036
1039
newLL {
1037
1040
var it : Iterator [B ]^ {ll, f} = null
1038
1041
var itHasNext = false
@@ -1056,7 +1059,7 @@ object LazyListIterable extends IterableFactory[LazyListIterable] {
1056
1059
1057
1060
private def dropImpl [A ](ll : LazyListIterable [A ]^ , n : Int ): LazyListIterable [A ]^ {ll} = {
1058
1061
// DO NOT REFERENCE `ll` ANYWHERE ELSE, OR IT WILL LEAK THE HEAD
1059
- var restRef : LazyListIterable [A ]^ {ll* } = ll // restRef is captured by closure arg to newLL, so A is not recognized as parametric
1062
+ var restRef : LazyListIterable [A ]^ {ll} = ll // restRef is captured by closure arg to newLL, so A is not recognized as parametric
1060
1063
var iRef = n // val iRef = new IntRef(n)
1061
1064
newLL {
1062
1065
var rest = restRef // var rest = restRef.elem
@@ -1073,7 +1076,7 @@ object LazyListIterable extends IterableFactory[LazyListIterable] {
1073
1076
1074
1077
private def dropWhileImpl [A ](ll : LazyListIterable [A ]^ , p : A => Boolean ): LazyListIterable [A ]^ {ll, p} = {
1075
1078
// DO NOT REFERENCE `ll` ANYWHERE ELSE, OR IT WILL LEAK THE HEAD
1076
- var restRef : LazyListIterable [A ]^ {ll* } = ll // restRef is captured by closure arg to newLL, so A is not recognized as parametric
1079
+ var restRef : LazyListIterable [A ]^ {ll} = ll // restRef is captured by closure arg to newLL, so A is not recognized as parametric
1077
1080
newLL {
1078
1081
var rest = restRef // var rest = restRef.elem
1079
1082
while (! rest.isEmpty && p(rest.head)) {
@@ -1086,8 +1089,8 @@ object LazyListIterable extends IterableFactory[LazyListIterable] {
1086
1089
1087
1090
private def takeRightImpl [A ](ll : LazyListIterable [A ]^ , n : Int ): LazyListIterable [A ]^ {ll} = {
1088
1091
// DO NOT REFERENCE `ll` ANYWHERE ELSE, OR IT WILL LEAK THE HEAD
1089
- var restRef : LazyListIterable [A ]^ {ll* } = ll // restRef is captured by closure arg to newLL, so A is not recognized as parametric
1090
- var scoutRef : LazyListIterable [A ]^ {ll* } = ll // same situation
1092
+ var restRef : LazyListIterable [A ]^ {ll} = ll // restRef is captured by closure arg to newLL, so A is not recognized as parametric
1093
+ var scoutRef : LazyListIterable [A ]^ {ll} = ll // same situation
1091
1094
var remainingRef = n // val remainingRef = new IntRef(n)
1092
1095
newLL {
1093
1096
var scout = scoutRef // var scout = scoutRef.elem
@@ -1236,33 +1239,35 @@ object LazyListIterable extends IterableFactory[LazyListIterable] {
1236
1239
*/
1237
1240
def newBuilder [A ]: Builder [A , LazyListIterable [A ]] = new LazyBuilder [A ]
1238
1241
1239
- private class LazyIterator [+ A ](private [this ] var lazyList : LazyListIterable [A ]^ ) extends AbstractIterator [A ] {
1240
- override def hasNext : Boolean = ! lazyList.isEmpty
1242
+ private class LazyIterator [+ A ](lazyList : LazyListIterable [A ]^ ) extends AbstractIterator [A ] {
1243
+ private var myLazyList = lazyList
1244
+ override def hasNext : Boolean = ! myLazyList.isEmpty
1241
1245
1242
1246
override def next (): A =
1243
- if (lazyList .isEmpty) Iterator .empty.next()
1247
+ if (myLazyList .isEmpty) Iterator .empty.next()
1244
1248
else {
1245
- val res = lazyList .head
1246
- lazyList = lazyList .tail
1249
+ val res = myLazyList .head
1250
+ myLazyList = myLazyList .tail
1247
1251
res
1248
1252
}
1249
1253
}
1250
1254
1251
- private class SlidingIterator [A ](private [ this ] var lazyList : LazyListIterable [A ]^ , size : Int , step : Int )
1255
+ private class SlidingIterator [A ](lazyList : LazyListIterable [A ]^ , size : Int , step : Int )
1252
1256
extends AbstractIterator [LazyListIterable [A ]] {
1257
+ private var myLazyList = lazyList
1253
1258
private val minLen = size - step max 0
1254
1259
private var first = true
1255
1260
1256
1261
def hasNext : Boolean =
1257
- if (first) ! lazyList .isEmpty
1258
- else lazyList .lengthGt(minLen)
1262
+ if (first) ! myLazyList .isEmpty
1263
+ else myLazyList .lengthGt(minLen)
1259
1264
1260
1265
def next (): LazyListIterable [A ] = {
1261
1266
if (! hasNext) Iterator .empty.next()
1262
1267
else {
1263
1268
first = false
1264
- val list = lazyList
1265
- lazyList = list.drop(step)
1269
+ val list = myLazyList
1270
+ myLazyList = list.drop(step)
1266
1271
list.take(size)
1267
1272
}
1268
1273
}
@@ -1281,7 +1286,7 @@ object LazyListIterable extends IterableFactory[LazyListIterable] {
1281
1286
import LazyBuilder ._
1282
1287
1283
1288
private [this ] var next : DeferredState [A ] = _
1284
- private [this ] var list : LazyListIterable [A ] = _
1289
+ @ uncheckedCaptures private [this ] var list : LazyListIterable [A ]^ = _
1285
1290
1286
1291
clear()
1287
1292
0 commit comments