8000 Ensure ZLayer macros use the trace from implicit scope by joroKr21 · Pull Request #9361 · zio/zio · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Ensure ZLayer macros use the trace from implicit scope #9361

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 2, 2024
Merged
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
17 changes: 17 additions & 0 deletions core-tests/shared/src/test/scala/zio/autowire/AutoWireSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import zio._
import zio.internal.macros.StringUtils.StringOps
import zio.test.Assertion.{anything, equalTo, isLeft}
import zio.test._

import scala.annotation.nowarn

object AutoWireSpec extends ZIOBaseSpec {
Expand Down Expand Up @@ -212,6 +213,22 @@ object AutoWireSpec extends ZIOBaseSpec {
s1 <- ZIO.service[String].provideLayer(tree)
s2 <- ZIO.service[String].provideLayer(mermaid)
} yield assertTrue(s1 == "Hello 1!", s2 == "Hello 2!")
},
test("takes trace from the implicit scope") {
var numTraces: Int = 0
val layer = {
implicit def trace: Trace = {
numTraces += 1
Trace.empty
}

ZLayer.make[String](
ZLayer.succeed(42),
ZLayer.fromFunction((_: Int).toString)
)
}

assertZIO(layer.build.as(numTraces))(equalTo(3))
Comment on lines +216 to +231
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, at least now I won't have to remember why we had to do use explicit tags in the macros in the future 🥲

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test was really hard to come up with 🤣

}
),
suite("`ZLayer.makeSome`")(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import zio._
import zio.internal.TerminalRendering

import scala.reflect.macros.blackbox
import zio.internal.stacktracer.Tracer

private[zio] trait LayerMacroUtils {
val c: blackbox.Context
Expand Down Expand Up @@ -49,16 +48,17 @@ private[zio] trait LayerMacroUtils {
case Expr(q"$prefix.mermaid") if prefix.symbol == debug => ZLayer.Debug.Mermaid
}

val trace = c.freshName(TermName("trace"))
val compose = c.freshName(TermName("compose"))
var usesEnvironment = false
var usesCompose = false

def typeToNode(tpe: Type): Node[Type, LayerExpr] = {
usesEnvironment = true
Node(Nil, List(tpe), c.Expr(q"${reify(ZLayer)}.environment[$tpe]"))
Node(Nil, List(tpe), c.Expr(q"${reify(ZLayer)}.environment[$tpe]($trace)"))
}

def buildFinalTree(tree: LayerTree[LayerExpr]): LayerExpr = {
val compose = c.freshName(TermName("compose"))
val memoList: List[(LayerExpr, LayerExpr)] =
tree.toList.map(_ -> c.Expr[ZLayer[_, _, _]](q"${c.freshName(TermName("layer"))}"))
val definitions = memoList.map { case (expr, memoizedNode) =>
Expand All @@ -79,10 +79,7 @@ private[zio] trait LayerMacroUtils {
)

val traceVal = if (usesEnvironment || usesCompose) {
val trace = c.freshName(TermName("trace"))
val suppress = typeOf[SuppressWarnings]
val wartRemover = q"""${reify(Array)}("org.wartremover.warts.ExplicitImplicitTypes")"""
List(q"@$suppress($wartRemover) implicit val $trace: ${typeOf[Trace]} = ${reify(Tracer)}.newTrace")
List(q"val $trace = ${reify(Predef)}.implicitly[${typeOf[Trace]}]")
} else {
Nil
}
Expand All @@ -93,7 +90,12 @@ private[zio] trait LayerMacroUtils {
val E = c.freshName(TypeName("E"))
val O1 = c.freshName(TypeName("O1"))
val O2 = c.freshName(TypeName("O2"))
List(q"def $compose[$R, $E, $O1, $O2](lhs: $ZLayer[$R, $E, $O1], rhs: $ZLayer[$O1, $E, $O2]) = lhs >>> rhs")
List(q"""
def $compose[$R, $E, $O1, $O2](
lhs: $ZLayer[$R, $E, $O1],
rhs: $ZLayer[$O1, $E, $O2]
) = lhs.>>>(rhs)($trace)
""")
} else {
Nil
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@ import zio.internal.stacktracer.Tracer
private[zio] object LayerMacroUtils {
type LayerExpr[E] = Expr[ZLayer[_, E, _]]

def composeLayer[R1, E, O1, O2](lhs: ZLayer[R1, E, O1], rhs: ZLayer[O1, E, O2])(using Trace): ZLayer[R1, E, O2] =
lhs.to(rhs)
def composeLayer[R1, E, O1, O2](
lhs: ZLayer[R1, E, O1],
rhs: ZLayer[O1, E, O2]
)(using Trace): ZLayer[R1, E, O2] =
lhs >>> rhs

def constructLayer[R0: Type, R: Type, E: Type](using Quotes)(
layers: Seq[LayerExpr[E]],
Expand Down Expand Up @@ -48,20 +51,19 @@ private[zio] object LayerMacroUtils {
}

'{
val trace = Tracer.newTrace
given Trace = trace
val trace = summonInline[Trace]

${
def typeToNode(tpe: TypeRepr): Node[TypeRepr, LayerExpr[E]] =
Node(Nil, List(tpe), tpe.asType match { case '[t] => '{ ZLayer.environment[t] } })
Node(Nil, List(tpe), tpe.asType match { case '[t] => '{ ZLayer.environment[t](trace) } })

def composeH(lhs: LayerExpr[E], rhs: LayerExpr[E]): LayerExpr[E] =
lhs match {
case '{ $lhs: ZLayer[i, E, o] } =>
rhs match {
case '{ $rhs: ZLayer[i2, E, o2] } =>
rhs.asTerm match {
case _: Ident => '{ $lhs.and($rhs)(summonInline) }
case _: Ident => '{ $lhs.++($rhs)(summonInline) }
case _ => '{ $lhs +!+ $rhs }
}
}
Expand All @@ -72,7 +74,7 @@ private[zio] object LayerMacroUtils {
case '{ $lhs: ZLayer[i, E, o] } =>
rhs match {
case '{ $rhs: ZLayer[`o`, E, o2] } =>
'{ composeLayer($lhs, $rhs) }
'{ composeLayer($lhs, $rhs)(using trace) }
}
}

Expand Down
Loading
0