From 7921f1d0b96511c30b358aea09c6c54c82995fab Mon Sep 17 00:00:00 2001 From: Kyri Petrou Date: Mon, 10 Feb 2025 03:59:21 +0200 Subject: [PATCH 1/4] Use an `inline given` for CanFail evidence in Scala 3 --- core/shared/src/main/scala-3/zio/CanFail.scala | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/core/shared/src/main/scala-3/zio/CanFail.scala b/core/shared/src/main/scala-3/zio/CanFail.scala index dd0a9a557738..7efb690b495b 100644 --- a/core/shared/src/main/scala-3/zio/CanFail.scala +++ b/core/shared/src/main/scala-3/zio/CanFail.scala @@ -35,5 +35,10 @@ import scala.util.NotGiven sealed abstract class CanFail[-E] object CanFail extends CanFail[Any] { - implicit def canFail[E](implicit ev: NotGiven[E =:= Nothing]): CanFail[E] = CanFail + + inline given canFail[E](using inline ev: NotGiven[E =:= Nothing]): CanFail[E] = CanFail + + @targetName("canFail") + @deprecated("Kept for binary compatibility only, do not use", "2.1.16") + private[zio] def _canFailCompat[E](implicit ev: NotGiven[E =:= Nothing]): CanFail[E] = CanFail } From 74602fec144c0451d84c78a4add3e50b3f7483bb Mon Sep 17 00:00:00 2001 From: Kyri Petrou Date: Mon, 10 Feb 2025 04:06:36 +0200 Subject: [PATCH 2/4] Add missing import --- core/shared/src/main/scala-3/zio/CanFail.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/shared/src/main/scala-3/zio/CanFail.scala b/core/shared/src/main/scala-3/zio/CanFail.scala index 7efb690b495b..3fd375bccbb2 100644 --- a/core/shared/src/main/scala-3/zio/CanFail.scala +++ b/core/shared/src/main/scala-3/zio/CanFail.scala @@ -18,7 +18,7 @@ package zio import zio.stacktracer.TracingImplicits.disableAutoTrace -import scala.annotation.implicitNotFound +import scala.annotation.{implicitNotFound, targetName} import scala.util.NotGiven /** From 79ad628ae899695bfa421a670533e897055323b8 Mon Sep 17 00:00:00 2001 From: Kyri Petrou Date: Mon, 10 Feb 2025 04:18:33 +0200 Subject: [PATCH 3/4] Fix compiling error --- streams/shared/src/main/scala/zio/stream/ZChannel.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/streams/shared/src/main/scala/zio/stream/ZChannel.scala b/streams/shared/src/main/scala/zio/stream/ZChannel.scala index 46d03df56bc9..422301470384 100644 --- a/streams/shared/src/main/scala/zio/stream/ZChannel.scala +++ b/streams/shared/src/main/scala/zio/stream/ZChannel.scala @@ -1373,7 +1373,8 @@ sealed trait ZChannel[-Env, -InErr, -InElem, -InDone, +OutErr, +OutElem, +OutDon case ChannelState.Emit => Exit.succeed(exec.getEmit) case ChannelState.Effect(zio) => - zio.mapError(Left(_)) *> interpret(exec.run().asInstanceOf[ChannelState[Env, OutErr]]) + zio.asInstanceOf[ZIO[Any, OutErr, Any]].mapError(Left(_)) *> + interpret(exec.run().asInstanceOf[ChannelState[Env, OutErr]]) case r @ ChannelState.Read(upstream, onEffect, onEmit, onDone) => ChannelExecutor.readUpstream[Env, OutErr, Either[OutErr, OutDone], OutElem]( r.asInstanceOf[ChannelState.Read[Env, OutErr]], From 5aeca76e5b053b4eea251b609ac5b0bfa9356126 Mon Sep 17 00:00:00 2001 From: Kyri Petrou Date: Mon, 10 Feb 2025 05:09:34 +0200 Subject: [PATCH 4/4] Use a low priority implicit to maintain source compatibility --- core/shared/src/main/scala-3/zio/CanFail.scala | 9 +++++++-- streams/shared/src/main/scala/zio/stream/ZChannel.scala | 3 +-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/core/shared/src/main/scala-3/zio/CanFail.scala b/core/shared/src/main/scala-3/zio/CanFail.scala index 3fd375bccbb2..253b5e2c4f72 100644 --- a/core/shared/src/main/scala-3/zio/CanFail.scala +++ b/core/shared/src/main/scala-3/zio/CanFail.scala @@ -34,11 +34,16 @@ import scala.util.NotGiven ) sealed abstract class CanFail[-E] -object CanFail extends CanFail[Any] { - +object CanFail extends CanFail[Any] with CanFailLowPriority { inline given canFail[E](using inline ev: NotGiven[E =:= Nothing]): CanFail[E] = CanFail @targetName("canFail") @deprecated("Kept for binary compatibility only, do not use", "2.1.16") private[zio] def _canFailCompat[E](implicit ev: NotGiven[E =:= Nothing]): CanFail[E] = CanFail } + +private[zio] transparent trait CanFailLowPriority { self: CanFail.type => + // In some extremely extremely rare case the type inference prior to macro expansion doesn't work, + // so we need a non-inlined low priority as a fallback + implicit def canFailLowPriority[E](implicit ev: NotGiven[E =:= Nothing]): CanFail[E] = self +} diff --git a/streams/shared/src/main/scala/zio/stream/ZChannel.scala b/streams/shared/src/main/scala/zio/stream/ZChannel.scala index 422301470384..46d03df56bc9 100644 --- a/streams/shared/src/main/scala/zio/stream/ZChannel.scala +++ b/streams/shared/src/main/scala/zio/stream/ZChannel.scala @@ -1373,8 +1373,7 @@ sealed trait ZChannel[-Env, -InErr, -InElem, -InDone, +OutErr, +OutElem, +OutDon case ChannelState.Emit => Exit.succeed(exec.getEmit) case ChannelState.Effect(zio) => - zio.asInstanceOf[ZIO[Any, OutErr, Any]].mapError(Left(_)) *> - interpret(exec.run().asInstanceOf[ChannelState[Env, OutErr]]) + zio.mapError(Left(_)) *> interpret(exec.run().asInstanceOf[ChannelState[Env, OutErr]]) case r @ ChannelState.Read(upstream, onEffect, onEmit, onDone) => ChannelExecutor.readUpstream[Env, OutErr, Either[OutErr, OutDone], OutElem]( r.asInstanceOf[ChannelState.Read[Env, OutErr]],