diff --git a/core-tests/shared/src/test/scala/zio/ZLayerSpec.scala b/core-tests/shared/src/test/scala/zio/ZLayerSpec.scala index 2f42ebc0aaa7..b86586e71901 100644 --- a/core-tests/shared/src/test/scala/zio/ZLayerSpec.scala +++ b/core-tests/shared/src/test/scala/zio/ZLayerSpec.scala @@ -339,6 +339,23 @@ object ZLayerSpec extends ZIOBaseSpec { result <- ref.get } yield assert(result)(hasSize(equalTo(8))) } @@ nonFlaky, + test("fresh with combination of other operators maintains freshness") { + def makeLayer1(ref: Ref[Vector[String]]): ZLayer[Any, Nothing, Service1] = ZLayer { + ref.update(_ :+ "1").as(new Service1 {}) + } + def makeLayer2(ref: Ref[Vector[String]]): ZLayer[Service1, Nothing, Service2] = ZLayer { + (ZIO.service[Service1] *> ref.update(_ :+ "2")).as(new Service2 {}) + } + + for { + ref <- makeRef + layer1 = makeLayer1(ref) + layer2 = makeLayer2(ref) + _ <- (ZIO.service[Service1] *> ZIO.service[Service2]) + .provide(layer1.fresh.map(identity).update(a => a), layer2) + result <- ref.get + } yield assert(result)(hasSameElements(Vector("1", "1", "2"))) + } @@ nonFlaky, test("preserves identity of acquired resources") { for { testRef <- Ref.make(Vector[String]()) diff --git a/core/shared/src/main/scala/zio/ZLayer.scala b/core/shared/src/main/scala/zio/ZLayer.scala index 97a5559a49cf..de2ca18ad5d9 100644 --- a/core/shared/src/main/scala/zio/ZLayer.scala +++ b/core/shared/src/main/scala/zio/ZLayer.scala @@ -211,8 +211,10 @@ sealed abstract class ZLayer[-RIn, +E, +ROut] { self => final def foldCauseLayer[E1, RIn1 <: RIn, ROut2]( failure: Cause[E] => ZLayer[RIn1, E1, ROut2], success: ZEnvironment[ROut] => ZLayer[RIn1, E1, ROut2] - )(implicit ev: CanFail[E]): ZLayer[RIn1, E1, ROut2] = - ZLayer.Fold(self, failure, success) + )(implicit ev: CanFail[E]): ZLayer[RIn1, E1, ROut2] = { + val foldLayer = ZLayer.Fold(self, failure, success) + if (isFresh) ZLayer.Fresh(foldLayer) else foldLayer + } /** * Creates a fresh version of this layer that will not be shared.