@@ -24,6 +24,9 @@ import java.util.Objects.requireNonNull
2424import java .io .{IOException , NotSerializableException , ObjectInputStream , ObjectOutputStream }
2525
2626import language .experimental .captureChecking
27+ import scala .annotation .unchecked .uncheckedCaptures
28+ import caps .cap
29+ import caps .consume
2730import caps .unsafe .*
2831
2932/**
@@ -66,15 +69,15 @@ private[concurrent] object Promise {
6669 /**
6770 * Compresses this chain and returns the currently known root of this chain of Links.
6871 **/
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} = {
7073 val c = get()
7174 compressed(current = c, target = c, owner = owner)
7275 }
7376
7477 /**
7578 * The combination of traversing and possibly unlinking of a given `target` DefaultPromise.
7679 **/
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} = {
7881 val value = target.get()
7982 if (value.isInstanceOf [Callbacks [_]]) {
8083 if (compareAndSet(current, target)) target // Link
@@ -127,6 +130,7 @@ private[concurrent] object Promise {
127130 /**
128131 * Returns the associated `Future` with this `Promise`
129132 */
133+ @ consume
130134 override final def future : Future [T ]^ = (this : Future [T ]^ )
131135
132136 override final def transform [S ](f : Try [T ] => Try [S ])(implicit executor : ExecutionContext ): Future [S ] =
@@ -135,7 +139,7 @@ private[concurrent] object Promise {
135139 override final def transformWith [S ](f : Try [T ] => Future [S ])(implicit executor : ExecutionContext ): Future [S ] =
136140 dispatchOrAddCallbacks(get(), new Transformation [T , S ](Xform_transformWith , f, executor))
137141
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 ] = {
139143 val state = get()
140144 if (state.isInstanceOf [Try [_]]) {
141145 if (state.asInstanceOf [Try [T ]].isFailure) this .asInstanceOf [Future [R ]]
@@ -414,11 +418,14 @@ private[concurrent] object Promise {
414418 * function's type parameters are erased, and the _xform tag will be used to reify them.
415419 **/
416420 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 ,
419423 private [this ] final var _arg : Try [F ],
420424 private [this ] final val _xform : Int
421425 ) 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+
422429 final def this (xform : Int , f : _ => _, ec : ExecutionContext ) =
423430 this (f.asInstanceOf [Any => Any ], ec.prepare(): @ nowarn(" cat=deprecation" ), null , xform)
424431
@@ -434,9 +441,9 @@ private[concurrent] object Promise {
434441 try e.execute(this .unsafeAssumePure) /* Safe publication of _arg, _fun, _ec */
435442 catch {
436443 case t : Throwable =>
437- // _fun = null // allow to GC
444+ _fun = null // allow to GC
438445 _arg = null // see above
439- // _ec = null // see above again
446+ _ec = null // see above again
440447 handleFailure(t, e)
441448 }
442449
@@ -460,9 +467,9 @@ private[concurrent] object Promise {
460467 val v = _arg
461468 val fun = _fun
462469 val ec = _ec
463- // _fun = null // allow to GC
470+ _fun = null // allow to GC
464471 _arg = null // see above
465- // _ec = null // see above
472+ _ec = null // see above
466473 try {
467474 val resolvedResult : Try [_] =
468475 (_xform : @ switch) match {
0 commit comments