File tree Expand file tree Collapse file tree 3 files changed +74
-0
lines changed
tests/run-macros/quoted-liftable-derivation-macro Expand file tree Collapse file tree 3 files changed +74
-0
lines changed Original file line number Diff line number Diff line change
1
+ import scala .compiletime .{erasedValue , summonFrom }
2
+ import scala .deriving ._
3
+ import scala .quoted ._
4
+
5
+
6
+ trait Lft [T ]:
7
+ def toExpr (x : T ): QuoteContext ?=> Expr [T ]
8
+
9
+ object Lft {
10
+ given Lft [Int ]:
11
+ def toExpr (x : Int ) = Expr (x)
12
+
13
+ inline given derived [T ](using inline m : Mirror .Of [T ]) as Lft [T ] = $ { derivedExpr(' m ) }
14
+
15
+ private def derivedExpr [T ](mirrorExpr : Expr [Mirror .Of [T ]])(using qctx : QuoteContext , tpe : Type [T ]): Expr [Lft [T ]] = {
16
+ def elemTypesLfts (tp : Type [_]): List [Expr [Lft [_]]] =
17
+ tp match
18
+ case ' [ $head *: $tail ] =>
19
+ Expr .summon(using ' [Lft [$head]]).getOrElse(qctx.throwError(s " Could not find given Lft[ ${head.show}] " )) :: elemTypesLfts(tail)
20
+ case ' [ Unit ] => Nil
21
+
22
+ mirrorExpr match {
23
+ case ' { $mirrorExpr : Mirror .Sum { type MirroredElemTypes = $mirroredElemTypes } } =>
24
+ val liftableExprs = elemTypesLfts(mirroredElemTypes)
25
+ ' {
26
+ new Lft [T ]:
27
+ def toExpr (x : T ) =
28
+ val mirror = $mirrorExpr
29
+ val liftable = $ {Expr .ofSeq(liftableExprs)}.apply(mirror.ordinal(x)).asInstanceOf [Lft [T ]] // TODO generate switch
30
+ liftable.toExpr(x)
31
+ }
32
+
33
+ case ' { $mirrorExpr : Mirror .Product { type MirroredElemTypes = $mirroredElemTypes } } =>
34
+ val liftableExprs = Expr .ofList(elemTypesLfts(mirroredElemTypes))
35
+ ' {
36
+ new Lft [T ]:
37
+ def toExpr (x : T ) =
38
+ val liftables = $liftableExprs
39
+ val lifted = Expr .ofSeq(liftables.zipWithIndex.map { (liftable, i) =>
40
+ liftable.asInstanceOf [Lft [AnyRef ]].toExpr(productElement(x, i))
41
+ })
42
+ val liftedProduct = ' { new ArrayProduct (Array [AnyRef ]($lifted : _* )) }
43
+ val mirror = Expr .summon(using ' [Mirror .ProductOf [T ]]).get
44
+ ' { $mirror.fromProduct($liftedProduct) }
45
+ }
46
+ }
47
+ }
48
+
49
+ }
Original file line number Diff line number Diff line change
1
+
2
+ sealed trait Opt [+ T ] derives Lft
3
+ case class Sm [T ](t : T ) extends Opt [T ] derives Lft
4
+ case object Nn extends Opt [Nothing ] derives Lft
5
+
6
+ object Lib {
7
+
8
+ import scala .quoted ._
9
+ import Opt .{given _ }
10
+
11
+ inline def smTwo = $ {smTwoExpr}
12
+ inline def none = $ {noneExpr}
13
+
14
+ private def smTwoExpr (using QuoteContext ): Expr [Opt [Int ]] =
15
+ summon[Lft [Sm [Int ]]].toExpr(Sm (2 ))
16
+
17
+ private def noneExpr (using QuoteContext ): Expr [Opt [Int ]] =
18
+ summon[Lft [Nn .type ]].toExpr(Nn )
19
+ }
20
+
Original file line number Diff line number Diff line change
1
+ object Test extends App {
2
+ import Opt ._
3
+ assert(Lib .smTwo == Sm (2 ))
4
+ assert(Lib .none == Nn )
5
+ }
You can’t perform that action at this time.
0 commit comments