Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions kernel/shared/src/main/scala/cats/effect/kernel/Fiber.scala
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,11 @@ trait Fiber[F[_], E, A] extends Serializable {
*
* If the fiber completes with [[Outcome.Succeeded]], the successful value is returned. If the
* fiber completes with [[Outcome.Errored]], the error is raised. If the fiber completes with
* [[Outcome.Canceled]], the caller is indefinitely suspended without termination.
* [[Outcome.Canceled]], attempt to self-cancel, and if the self-cancelation fails, the caller
* is indefinitely suspended without termination.
*/
def joinWithNever(implicit F: GenSpawn[F, E]): F[A] =
joinWith(F.never)
joinWith(F.canceled >> F.never)

/**
* Awaits the completion of the bound fiber and returns its result once it completes.
Expand Down
11 changes: 10 additions & 1 deletion tests/shared/src/test/scala/cats/effect/IOSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -428,11 +428,20 @@ class IOSpec extends BaseSpec with Discipline with IOPlatformSpecification {
} must completeAs(42)
}

"joinWithNever on a canceled fiber" in ticked { implicit ticker =>
"joinWithNever on a canceled cancelable fiber" in ticked { implicit ticker =>
(for {
fib <- IO.sleep(2.seconds).start
_ <- fib.cancel
_ <- fib.joinWithNever
} yield ()) must selfCancel
}

"joinWithNever on a canceled uncancelable fiber" in ticked { implicit ticker =>
(for {
fib <- IO.never[Unit].uncancelable.start
_ <- IO.sleep(1.second)
_ <- fib.cancel
_ <- fib.joinWithNever
} yield ()) must nonTerminate
}

Expand Down