Implements Promise.become(fiber) to address #9877. The issue identifies that when a Fiber forks work which will eventually complete a Promise, and then awaits that Promise, we pay unnecessary overhead:

The forked fiber allocates a callback to complete the promise promise.await allocates an asyncInterrupt callback to register itself These two callbacks communicate indirectly through the Promise state machine

Solution Promise.become(fiber) wires a fiber directly to a promise by registering an observer via fiber.unsafe.addObserver. When the fiber completes, the observer fires completeWith(ZIO.done(exit)), completing the promise with zero extra allocation on the completion path. scala// Before: indirect, allocates intermediate callback for { promise <- Promise.make[E, A] fiber <- (work >>= promise.succeed).fork result <- promise.await } yield result

// After: direct observer registration, no intermediate callback for { promise <- Promise.make[E, A] fiber <- work.fork _ <- promise.become(fiber) result <- promise.await } yield result Key properties

Race-safe: fiber.unsafe.addObserver handles the race between registration and completion — if the fiber has already completed, the observer fires immediately Idempotent completion: completeWith uses CAS internally, so multiple observers or concurrent completions are safe Short-circuit: the isDone check avoids unnecessary observer registration when the promise is already complete

Changes

Promise.scala: Add become to the public API, UnsafeAPI trait, and the concrete AtomicReference-based implementation PromiseSpec.scala: Add 4 tests covering success, failure, no-op, and already-completed fiber cases

https://www.loom.com/share/bb6f6a5ee79f46d091d16e9ae41f7a73

Fixes #9877 /claim #9877

Claim

Total prize pool $750
Total paid $0
Status Pending
Submitted March 21, 2026
Last updated March 21, 2026

Contributors

NI

Nithinfgs

@Nithinfgs

100%

Sponsors

ZI

ZIO

@ZIO

$750