diff --git a/docs/docs/reference/contextual/derivation-macro.md b/docs/docs/reference/contextual/derivation-macro.md index bd81c7fa226f..e204fd5a52d6 100644 --- a/docs/docs/reference/contextual/derivation-macro.md +++ b/docs/docs/reference/contextual/derivation-macro.md @@ -44,11 +44,11 @@ from the signature. The body of the `derived` method is shown below: given derived[T: Type](using qctx: QuoteContext) as Expr[Eq[T]] = { import qctx.reflect._ - val ev: Expr[Mirror.Of[T]] = Expr.summon(using '[Mirror.Of[T]]).get + val ev: Expr[Mirror.Of[T]] = Expr.summon[Mirror.Of[T]].get ev match { - case '{ $m: Mirror.ProductOf[T] { type MirroredElemTypes = $elementTypes }} => - val elemInstances = summonAll(elementTypes) + case '{ $m: Mirror.ProductOf[T] { type MirroredElemTypes = elementTypes }} => + val elemInstances = summonAll[elementTypes] val eqProductBody: (Expr[T], Expr[T]) => Expr[Boolean] = (x, y) => { elemInstances.zipWithIndex.foldLeft(Expr(true: Boolean)) { case (acc, (elem, index)) => @@ -84,17 +84,17 @@ Instead we extract the tuple-type for element types using pattern matching over quotes and more specifically of the refined type: ```scala - case '{ $m: Mirror.ProductOf[T] { type MirroredElemTypes = $elementTypes } } => ... + case '{ $m: Mirror.ProductOf[T] { type MirroredElemTypes = elementTypes }} => ... ``` The implementation of `summonAll` as a macro can be show below assuming that we have the given instances for our primitive types: ```scala - def summonAll[T](t: Type[T])(using qctx: QuoteContext): List[Expr[Eq[_]]] = t match { - case '[String *: $tpes] => '{ summon[Eq[String]] } :: summonAll(tpes) - case '[Int *: $tpes] => '{ summon[Eq[Int]] } :: summonAll(tpes) - case '[$tpe *: $tpes] => derived(using tpe, qctx) :: summonAll(tpes) + def summonAll[T: Type](using qctx: QuoteContext): List[Expr[Eq[_]]] = t match { + case '[String *: tpes] => '{ summon[Eq[String]] } :: summonAll[tpes] + case '[Int *: tpes] => '{ summon[Eq[Int]] } :: summonAll[tpes] + case '[tpe *: tpes] => derived[tpe] :: summonAll[tpes] case '[EmptyTuple] => Nil } ``` @@ -120,8 +120,8 @@ Alternatively and what is shown below is that we can call the `eqv` method directly. The `eqGen` can trigger the derivation. ```scala -extension [T](x: =>T) - inline def === (y: =>T)(using eq: Eq[T]): Boolean = eq.eqv(x, y) +extension [T](inline x: T) + inline def === (inline y: T)(using eq: Eq[T]): Boolean = eq.eqv(x, y) implicit inline def eqGen[T]: Eq[T] = ${ Eq.derived[T] } ``` @@ -144,7 +144,7 @@ The full code is shown below: ```scala import scala.deriving._ import scala.quoted._ -import scala.quoted.matching._ + trait Eq[T] { def eqv(x: T, y: T): Boolean @@ -169,21 +169,21 @@ object Eq { def eqv(x: T, y: T): Boolean = body(x, y) } - def summonAll[T](t: Type[T])(using qctx: QuoteContext): List[Expr[Eq[_]]] = t match { - case '[String *: $tpes] => '{ summon[Eq[String]] } :: summonAll(tpes) - case '[Int *: $tpes] => '{ summon[Eq[Int]] } :: summonAll(tpes) - case '[$tpe *: $tpes] => derived(using tpe, qctx) :: summonAll(tpes) + def summonAll[T: Type](using qctx: QuoteContext): List[Expr[Eq[_]]] = t match { + case '[String *: tpes] => '{ summon[Eq[String]] } :: summonAll[tpes] + case '[Int *: tpes] => '{ summon[Eq[Int]] } :: summonAll[tpes] + case '[tpe *: tpes] => derived[tpe] :: summonAll[tpes] case '[EmptyTuple] => Nil } given derived[T: Type](using qctx: QuoteContext) as Expr[Eq[T]] = { import qctx.reflect._ - val ev: Expr[Mirror.Of[T]] = Expr.summon(using '[Mirror.Of[T]]).get + val ev: Expr[Mirror.Of[T]] = Expr.summon[Mirror.Of[T]].get ev match { - case '{ $m: Mirror.ProductOf[T] { type MirroredElemTypes = $elementTypes }} => - val elemInstances = summonAll(elementTypes) + case '{ $m: Mirror.ProductOf[T] { type MirroredElemTypes = elementTypes }} => + val elemInstances = summonAll[elementTypes] val eqProductBody: (Expr[T], Expr[T]) => Expr[Boolean] = (x, y) => { elemInstances.zipWithIndex.foldLeft(Expr(true: Boolean)) { case (acc, (elem, index)) => @@ -197,8 +197,8 @@ object Eq { eqProduct((x: T, y: T) => ${eqProductBody('x, 'y)}) } - case '{ $m: Mirror.SumOf[T] { type MirroredElemTypes = $elementTypes }} => - val elemInstances = summonAll(elementTypes) + case '{ $m: Mirror.SumOf[T] { type MirroredElemTypes = elementTypes }} => + val elemInstances = summonAll[elementTypes] val eqSumBody: (Expr[T], Expr[T]) => Expr[Boolean] = (x, y) => { val ordx = '{ $m.ordinal($x) } val ordy = '{ $m.ordinal($y) } @@ -217,8 +217,8 @@ object Eq { } object Macro3 { - extension [T](x: =>T) - inline def === (y: =>T)(using eq: Eq[T]): Boolean = eq.eqv(x, y) + extension [T](inline x: T) + inline def === (inline y: T)(using eq: Eq[T]): Boolean = eq.eqv(x, y) implicit inline def eqGen[T]: Eq[T] = ${ Eq.derived[T] } }