Skip to content

Commit 039452f

Browse files
committed
Add docs on getting precise type within quotes
1 parent 1e397e0 commit 039452f

File tree

1 file changed

+41
-0
lines changed

1 file changed

+41
-0
lines changed

docs/docs/reference/metaprogramming/macros.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -689,6 +689,47 @@ private def sumExpr(args1: Seq[Expr[Int]])(given QuoteContext): Expr[Int] = {
689689
}
690690
```
691691

692+
#### Recovering precise types using patterns
693+
694+
Sometimes it is necessary to get a more precise type for an expression. This can be achived using the following pattern match.
695+
696+
```scala
697+
def f(exp: Expr[Any]) =
698+
expr match
699+
case '{ $x: $t } =>
700+
// There there exists some local `type T` for which we have `x: Expr[T]` and a `given t: Type[T]`
701+
```
702+
703+
This might be used to then prerorm an implicit search as in:
704+
705+
706+
```scala
707+
inline def (sc: StringContext) showMe(args: =>Any*): String = ${ showMeExpr('sc, 'args) }
708+
709+
private def showMeExpr(sc: Expr[StringContext], argsExpr: Expr[Seq[Any]])(given qctx: QuoteContext): Expr[String] = {
710+
argsExpr match {
711+
case ExprSeq(argExprs) =>
712+
val argShowedExprs = argExprs.map {
713+
case '{ $arg: $tp } =>
714+
val showTp = '[Show[$tp]]
715+
summonExpr(given showTp), summon[QuoteContext]) match {
716+
case Some(showExpr) => '{ $showExpr.show($arg) }
717+
case None => qctx.error(s"could not find implicit for ${showTp.show}", arg); '{???}
718+
}
719+
}
720+
val newArgsExpr = Expr.ofSeq(argShowedExprs)
721+
'{ $sc.s($newArgsExpr: _*) }
722+
case _ =>
723+
// `new StringContext(...).showMeExpr(args: _*)` not an explicit `showMeExpr"..."`
724+
qctx.error(s"Args must be explicit", argsExpr)
725+
'{???}
726+
}
727+
}
728+
729+
trait Show[-T] {
730+
def show(x: T): String
731+
}
732+
```
692733

693734
### More details
694735
[More details](./macros-spec.md)

0 commit comments

Comments
 (0)