@@ -187,25 +187,25 @@ Indeed, the definition of `to` above uses `T` in the next stage, there is a
187
187
quote but no splice between the parameter binding of ` T ` and its
188
188
usage. But the code can be rewritten by adding a binding of a ` Type[T] ` tag:
189
189
``` scala
190
- def to [T , R : Type ](f : Expr [T ] => Expr [R ])(using t : Type [T ])( using QuoteContext ): Expr [T => R ] =
191
- ' { (x : $t ) => $ { f(' x ) } }
190
+ def to [T , R ](f : Expr [T ] => Expr [R ])(using Type [T ], Type [ R ], QuoteContext ): Expr [T => R ] =
191
+ ' { (x : T ) => $ { f(' x ) } }
192
192
```
193
193
In this version of ` to ` , the type of ` x ` is now the result of
194
194
splicing the ` Type ` value ` t ` . This operation _ is_ splice correct -- there
195
195
is one quote and one splice between the use of ` t ` and its definition.
196
196
197
197
To avoid clutter, the Scala implementation tries to convert any type
198
- reference to a type ` T ` in subsequent phases to a type-splice, by rewriting ` T ` to ` ${ summon[Type[T]] } ` .
198
+ reference to a type ` T ` in subsequent phases to a type-splice, by rewriting ` T ` to ` summon[Type[T]].Underlying ` .
199
199
For instance, the user-level definition of ` to ` :
200
200
201
201
``` scala
202
- def to [T : Type , R : Type ](f : Expr [T ] => Expr [R ])(using QuoteContext ): Expr [T => R ] =
202
+ def to [T , R ](f : Expr [T ] => Expr [R ])(using t : Type [ T ], r : Type [ R ], QuoteContext ): Expr [T => R ] =
203
203
' { (x : T ) => $ { f(' x ) } }
204
204
```
205
205
would be rewritten to
206
206
``` scala
207
- def to [T : Type , R : Type ](f : Expr [T ] => Expr [R ])(using QuoteContext ): Expr [T => R ] =
208
- ' { (x : $ { summon[ Type [ T ]] }) => $ { f(' x ) } }
207
+ def to [T , R ](f : Expr [T ] => Expr [R ])(using t : Type [ T ], r : Type [ R ], QuoteContext ): Expr [T => R ] =
208
+ ' { (x : t. Underlying }) => $ { f(' x ) } }
209
209
```
210
210
The ` summon ` query succeeds because there is a given instance of
211
211
type ` Type[T] ` available (namely the given parameter corresponding
@@ -499,10 +499,10 @@ function `f` and one `sum` that performs a sum by delegating to `map`.
499
499
500
500
``` scala
501
501
object Macros {
502
- def map [T ](arr : Expr [Array [T ]], f : Expr [T ] => Expr [Unit ])(using t : Type [T ], qctx : QuoteContext ): Expr [Unit ] = ' {
502
+ def map [T ](arr : Expr [Array [T ]], f : Expr [T ] => Expr [Unit ])(using Type [T ], QuoteContext ): Expr [Unit ] = ' {
503
503
var i : Int = 0
504
504
while (i < ($arr).length) {
505
- val element : $t = ($arr)(i)
505
+ val element : T = ($arr)(i)
506
506
$ {f(' element )}
507
507
i += 1
508
508
}
@@ -703,11 +703,11 @@ Sometimes it is necessary to get a more precise type for an expression. This can
703
703
``` scala
704
704
def f (exp : Expr [Any ])(using QuoteContext ) =
705
705
expr match
706
- case ' { $x : $t } =>
706
+ case ' { $x : $T } =>
707
707
// If the pattern match succeeds, then there is some type `T` such that
708
708
// - `x` is bound to a variable of type `Expr[T]`
709
- // - `t ` is bound to a given instance of type `Type[T]`
710
- // That is, we have `x: Expr[T]` and `given t: Type[T]`, for some (unknown) type `T`.
709
+ // - `T ` is bound to a new type T and a given instance `Type[T]` is provided for it
710
+ // That is, we have `x: Expr[T]` and `given Type[T]`, for some (unknown) type `T`.
711
711
```
712
712
713
713
This might be used to then perform an implicit search as in:
@@ -720,9 +720,8 @@ private def showMeExpr(sc: Expr[StringContext], argsExpr: Expr[Seq[Any]])(using
720
720
argsExpr match {
721
721
case Varargs (argExprs) =>
722
722
val argShowedExprs = argExprs.map {
723
- case ' { $arg : $tp } =>
724
- val showTp = ' [Show [$tp]]
725
- Expr .summon(using showTp) match {
723
+ case ' { $arg : $T } =>
724
+ Expr .summon[Show [T ]] match {
726
725
case Some (showExpr) => ' { $showExpr.show($arg) }
727
726
case None => Reporting .error(s " could not find implicit for ${showTp.show}" , arg); ' {??? }
728
727
}
0 commit comments