Skip to content

Commit 1199f85

Browse files
committed
Add tasty.reflect.utils
With implementation of `def let(rhs: Term)(in: Term.Ident => Term): Term`
1 parent fb0e3bc commit 1199f85

File tree

9 files changed

+96
-3
lines changed

9 files changed

+96
-3
lines changed

compiler/src/dotty/tools/dotc/tastyreflect/QuotedOpsImpl.scala

+7
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,11 @@ trait QuotedOpsImpl extends scala.tasty.reflect.QuotedOps with CoreImpl {
4848
}
4949
}
5050
}
51+
52+
def TypeToQuoteDeco(tpe: Types.Type): TypeToQuotedAPI = new TypeToQuotedAPI {
53+
def seal(implicit ctx: Context): quoted.Type[_] = {
54+
val dummyPos = ctx.owner.pos // FIXME
55+
new scala.quoted.Types.TreeType(tpd.TypeTree(tpe).withPos(dummyPos))
56+
}
57+
}
5158
}

compiler/src/dotty/tools/dotc/transform/Staging.scala

-2
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,6 @@ class Staging extends MacroTransformWithImplicits {
174174
val rhs = transform(tag.select(tpnme.UNARY_~))
175175
val alias = ctx.typeAssigner.assignType(untpd.TypeBoundsTree(rhs, rhs), rhs, rhs)
176176

177-
val original = typeRef.symbol.asType
178-
179177
val local = ctx.newSymbol(
180178
owner = ctx.owner,
181179
name = UniqueName.fresh("T".toTermName).toTypeName,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package scala.tasty
2+
package reflect.utils
3+
4+
import scala.quoted._
5+
6+
trait TreeUtils {
7+
8+
val reflect: Reflection
9+
import reflect._
10+
11+
def let(rhs: Term)(in: Term.Ident => Term): Term = {
12+
type T // TODO probably it is better to use the Sealed contruct rather than let the user create their own existential type
13+
implicit val rhsTpe: quoted.Type[T] = rhs.tpe.seal.asInstanceOf[quoted.Type[T]]
14+
val rhsExpr = rhs.seal[T]
15+
val expr = '{
16+
val x = ~rhsExpr
17+
~in(('(x)).unseal.asInstanceOf[Term.Ident]).seal[Any]
18+
}
19+
expr.unseal
20+
}
21+
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package scala.tasty
2+
package reflect.utils
3+
4+
trait TreeUtils {
5+
6+
val reflect: Reflection
7+
import reflect._
8+
9+
def let(rhs: Term)(in: Term.Ident => Term): Term = throw new Exception("non bootstrpped lib")
10+
11+
}

library/src/scala/tasty/Reflection.scala

+5-1
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,14 @@ abstract class Reflection
2121
with TreeOps
2222
with TreeUtils
2323
with TypeOrBoundsTreeOps
24-
with TypeOrBoundsOps {
24+
with TypeOrBoundsOps { self =>
2525

2626
def typeOf[T: scala.quoted.Type]: Type =
2727
implicitly[scala.quoted.Type[T]].unseal.tpe
28+
29+
val util: reflect.utils.TreeUtils { val reflect: self.type } = new reflect.utils.TreeUtils {
30+
val reflect: self.type = self
31+
}
2832
}
2933

3034
object Reflection {

library/src/scala/tasty/reflect/QuotedOps.scala

+5
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,9 @@ trait QuotedOps extends Core {
2121
}
2222
implicit def TermToQuoteDeco(term: Term): TermToQuotedAPI
2323

24+
trait TypeToQuotedAPI {
25+
/** Convert `Type` to an `quoted.Type[T]` */
26+
def seal(implicit ctx: Context): scala.quoted.Type[_]
27+
}
28+
implicit def TypeToQuoteDeco(tpe: Type): TypeToQuotedAPI
2429
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
1
2+
1
3+
null
4+
null
5+
foo
6+
bar
7+
bar
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import scala.quoted._
2+
3+
import scala.tasty._
4+
5+
object Macros {
6+
7+
inline def let[T](rhs: T)(body: => T => Unit): Unit =
8+
~impl('(rhs), '(body))
9+
10+
private def impl[T](rhs: Expr[T], body: Expr[T => Unit])(implicit reflect: Reflection): Expr[Unit] = {
11+
import reflect._
12+
13+
val rhsTerm = rhs.unseal
14+
15+
import reflect.util.{let => letTerm}
16+
letTerm(rhsTerm) { rhsId =>
17+
body(rhsId.seal[Any].asInstanceOf[Expr[T]]).unseal // Dangerous uncheked cast!
18+
}.seal[Unit]
19+
}
20+
21+
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
2+
import Macros._
3+
4+
object Test {
5+
def main(args: Array[String]): Unit = {
6+
let(1)(x => { println(x); println(x) })
7+
let(null)(x => { println(x); println(x) })
8+
let {
9+
println("foo")
10+
"bar"
11+
} { x =>
12+
println(x)
13+
println(x)
14+
}
15+
}
16+
17+
}

0 commit comments

Comments
 (0)