@@ -24,6 +24,9 @@ import java.util.Objects.requireNonNull
24
24
import java .io .{IOException , NotSerializableException , ObjectInputStream , ObjectOutputStream }
25
25
26
26
import language .experimental .captureChecking
27
+ import scala .annotation .unchecked .uncheckedCaptures
28
+ import caps .cap
29
+ import caps .consume
27
30
import caps .unsafe .*
28
31
29
32
/**
@@ -66,15 +69,15 @@ private[concurrent] object Promise {
66
69
/**
67
70
* Compresses this chain and returns the currently known root of this chain of Links.
68
71
**/
69
- final def promise (owner : DefaultPromise [T ]^ ): DefaultPromise [T ]^ {this , to, owner} = {
72
+ final def promise (owner : DefaultPromise [T ]^ ): DefaultPromise [T ]^ {cap.rd, this , to, owner} = {
70
73
val c = get()
71
74
compressed(current = c, target = c, owner = owner)
72
75
}
73
76
74
77
/**
75
78
* The combination of traversing and possibly unlinking of a given `target` DefaultPromise.
76
79
**/
77
- @ inline @ tailrec private [this ] final def compressed (current : DefaultPromise [T ]^ , target : DefaultPromise [T ]^ , owner : DefaultPromise [T ]^ ): DefaultPromise [T ]^ {this , current, target, owner} = {
80
+ @ inline @ tailrec private [this ] final def compressed (current : DefaultPromise [T ]^ {cap.rd, this } , target : DefaultPromise [T ]^ , owner : DefaultPromise [T ]^ ): DefaultPromise [T ]^ {this , current, target, owner} = {
78
81
val value = target.get()
79
82
if (value.isInstanceOf [Callbacks [_]]) {
80
83
if (compareAndSet(current, target)) target // Link
@@ -127,6 +130,7 @@ private[concurrent] object Promise {
127
130
/**
128
131
* Returns the associated `Future` with this `Promise`
129
132
*/
133
+ @ consume
130
134
override final def future : Future [T ]^ = (this : Future [T ]^ )
131
135
132
136
override final def transform [S ](f : Try [T ] => Try [S ])(implicit executor : ExecutionContext ): Future [S ] =
@@ -135,7 +139,7 @@ private[concurrent] object Promise {
135
139
override final def transformWith [S ](f : Try [T ] => Future [S ])(implicit executor : ExecutionContext ): Future [S ] =
136
140
dispatchOrAddCallbacks(get(), new Transformation [T , S ](Xform_transformWith , f, executor))
137
141
138
- override final def zipWith [U , R ](that : Future [U ])(f : (T , U ) => R )(implicit executor : ExecutionContext ): Future [R ] = {
142
+ override final def zipWith [U , R ](that : Future [U ])(@ consume f : (T , U ) => R )(implicit executor : ExecutionContext ): Future [R ] = {
139
143
val state = get()
140
144
if (state.isInstanceOf [Try [_]]) {
141
145
if (state.asInstanceOf [Try [T ]].isFailure) this .asInstanceOf [Future [R ]]
@@ -414,11 +418,14 @@ private[concurrent] object Promise {
414
418
* function's type parameters are erased, and the _xform tag will be used to reify them.
415
419
**/
416
420
final class Transformation [- F , T ] private [this ] (
417
- private [ this ] final val _fun : Any => Any ,
418
- private [ this ] final val _ec : ExecutionContext ,
421
+ __fun : Any => Any ,
422
+ __ec : ExecutionContext ,
419
423
private [this ] final var _arg : Try [F ],
420
424
private [this ] final val _xform : Int
421
425
) extends DefaultPromise [T ]() with Callbacks [F ] with Runnable with Batchable {
426
+ @ uncheckedCaptures private [this ] final var _fun : Any => Any = __fun
427
+ @ uncheckedCaptures private [this ] final var _ec : ExecutionContext = __ec
428
+
422
429
final def this (xform : Int , f : _ => _, ec : ExecutionContext ) =
423
430
this (f.asInstanceOf [Any => Any ], ec.prepare(): @ nowarn(" cat=deprecation" ), null , xform)
424
431
@@ -434,9 +441,9 @@ private[concurrent] object Promise {
434
441
try e.execute(this .unsafeAssumePure) /* Safe publication of _arg, _fun, _ec */
435
442
catch {
436
443
case t : Throwable =>
437
- // _fun = null // allow to GC
444
+ _fun = null // allow to GC
438
445
_arg = null // see above
439
- // _ec = null // see above again
446
+ _ec = null // see above again
440
447
handleFailure(t, e)
441
448
}
442
449
@@ -460,9 +467,9 @@ private[concurrent] object Promise {
460
467
val v = _arg
461
468
val fun = _fun
462
469
val ec = _ec
463
- // _fun = null // allow to GC
470
+ _fun = null // allow to GC
464
471
_arg = null // see above
465
- // _ec = null // see above
472
+ _ec = null // see above
466
473
try {
467
474
val resolvedResult : Try [_] =
468
475
(_xform : @ switch) match {
0 commit comments