Skip to content

Commit 8ac5b72

Browse files
committed
Remove scala.quoted.unsafe.UnsafeExpr
The library should not provide those operattion on Expr. These can still be done using reflection and we keep testing that they can be encoded.
1 parent 70bcb28 commit 8ac5b72

File tree

6 files changed

+91
-80
lines changed

6 files changed

+91
-80
lines changed

library/src-bootstrapped/scala/quoted/unsafe/UnsafeExpr.scala

Lines changed: 0 additions & 70 deletions
This file was deleted.

tests/run-macros/i7898/Macro_1.scala

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import quoted._
2-
import quoted.unsafe._
1+
import scala.quoted._
2+
33
object Main {
44

55
def myMacroImpl(body: Expr[_])(using qctx: QuoteContext) : Expr[_] = {
66
import qctx.reflect._
7-
val bodyTerm = UnsafeExpr.underlyingArgument(body).unseal
7+
val bodyTerm = underlyingArgument(body).unseal
88
val showed = bodyTerm.show
99
'{
1010
println(${Expr(showed)})
@@ -15,4 +15,7 @@ object Main {
1515
transparent inline def myMacro(body: => Any): Any = ${
1616
myMacroImpl('body)
1717
}
18+
19+
def underlyingArgument[T](expr: Expr[T])(using qctx: QuoteContext): Expr[T] =
20+
expr.unseal.underlyingArgument.seal.asInstanceOf[Expr[T]]
1821
}

tests/run-macros/quote-matcher-symantics-2/quoted_1.scala

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import scala.quoted._
22

3-
import scala.quoted.unsafe._
4-
53
object Macros {
64

75
inline def liftString(inline a: DSL): String = ${implStringNum('a)}
@@ -64,6 +62,29 @@ object Macros {
6462

6563
}
6664

65+
object UnsafeExpr {
66+
def open[T1, R, X](f: Expr[T1 => R])(content: (Expr[R], [t] => Expr[t] => Expr[T1] => Expr[t]) => X)(using qctx: QuoteContext): X = {
67+
val (params, bodyExpr) = paramsAndBody[R](f)
68+
content(bodyExpr, [t] => (e: Expr[t]) => (v: Expr[T1]) => bodyFn[t](e.unseal, params, List(v.unseal)).seal.asInstanceOf[Expr[t]])
69+
}
70+
private def paramsAndBody[R](using qctx: QuoteContext)(f: Expr[Any]): (List[qctx.reflect.ValDef], Expr[R]) = {
71+
import qctx.reflect._
72+
val Block(List(DefDef("$anonfun", Nil, List(params), _, Some(body))), Closure(Ident("$anonfun"), None)) = f.unseal.etaExpand
73+
(params, body.seal.asInstanceOf[Expr[R]])
74+
}
75+
76+
private def bodyFn[t](using qctx: QuoteContext)(e: qctx.reflect.Term, params: List[qctx.reflect.ValDef], args: List[qctx.reflect.Term]): qctx.reflect.Term = {
77+
import qctx.reflect._
78+
val map = params.map(_.symbol).zip(args).toMap
79+
new TreeMap {
80+
override def transformTerm(tree: Term)(using ctx: Context): Term =
81+
super.transformTerm(tree) match
82+
case tree: Ident => map.getOrElse(tree.symbol, tree)
83+
case tree => tree
84+
}.transformTerm(e)
85+
}
86+
}
87+
6788
def freshEnvVar()(using QuoteContext): (Int, Expr[DSL]) = {
6889
v += 1
6990
(v, '{envVar(${Expr(v)})})

tests/run-macros/quote-matcher-symantics-3/quoted_1.scala

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import scala.quoted._
22

3-
import scala.quoted.unsafe._
4-
53
object Macros {
64

75

@@ -76,6 +74,29 @@ object Macros {
7674

7775
}
7876

77+
object UnsafeExpr {
78+
def open[T1, R, X](f: Expr[T1 => R])(content: (Expr[R], [t] => Expr[t] => Expr[T1] => Expr[t]) => X)(using qctx: QuoteContext): X = {
79+
val (params, bodyExpr) = paramsAndBody[R](f)
80+
content(bodyExpr, [t] => (e: Expr[t]) => (v: Expr[T1]) => bodyFn[t](e.unseal, params, List(v.unseal)).seal.asInstanceOf[Expr[t]])
81+
}
82+
private def paramsAndBody[R](using qctx: QuoteContext)(f: Expr[Any]): (List[qctx.reflect.ValDef], Expr[R]) = {
83+
import qctx.reflect._
84+
val Block(List(DefDef("$anonfun", Nil, List(params), _, Some(body))), Closure(Ident("$anonfun"), None)) = f.unseal.etaExpand
85+
(params, body.seal.asInstanceOf[Expr[R]])
86+
}
87+
88+
private def bodyFn[t](using qctx: QuoteContext)(e: qctx.reflect.Term, params: List[qctx.reflect.ValDef], args: List[qctx.reflect.Term]): qctx.reflect.Term = {
89+
import qctx.reflect._
90+
val map = params.map(_.symbol).zip(args).toMap
91+
new TreeMap {
92+
override def transformTerm(tree: Term)(using ctx: Context): Term =
93+
super.transformTerm(tree) match
94+
case tree: Ident => map.getOrElse(tree.symbol, tree)
95+
case tree => tree
96+
}.transformTerm(e)
97+
}
98+
}
99+
79100
def freshEnvVar[T: Type]()(using QuoteContext): (Int, Expr[T]) = {
80101
v += 1
81102
(v, '{envVar[T](${Expr(v)})})

tests/run-macros/quote-matching-open/Macro_1.scala

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import scala.quoted._
2-
import scala.quoted.unsafe._
2+
33
object Macro {
44

55
inline def openTest(inline x: Any): Any = ${ Macro.impl('x) }
@@ -13,3 +13,36 @@ object Macro {
1313
}
1414

1515
}
16+
17+
18+
object UnsafeExpr {
19+
def open[T1, R, X](f: Expr[T1 => R])(content: (Expr[R], [t] => Expr[t] => Expr[T1] => Expr[t]) => X)(using qctx: QuoteContext): X = {
20+
val (params, bodyExpr) = paramsAndBody[R](f)
21+
content(bodyExpr, [t] => (e: Expr[t]) => (v: Expr[T1]) => bodyFn[t](e.unseal, params, List(v.unseal)).seal.asInstanceOf[Expr[t]])
22+
}
23+
def open[T1, T2, R, X](f: Expr[(T1, T2) => R])(content: (Expr[R], [t] => Expr[t] => (Expr[T1], Expr[T2]) => Expr[t]) => X)(using qctx: QuoteContext)(using DummyImplicit): X = {
24+
val (params, bodyExpr) = paramsAndBody[R](f)
25+
content(bodyExpr, [t] => (e: Expr[t]) => (v1: Expr[T1], v2: Expr[T2]) => bodyFn[t](e.unseal, params, List(v1.unseal, v2.unseal)).seal.asInstanceOf[Expr[t]])
26+
}
27+
28+
def open[T1, T2, T3, R, X](f: Expr[(T1, T2, T3) => R])(content: (Expr[R], [t] => Expr[t] => (Expr[T1], Expr[T2], Expr[T3]) => Expr[t]) => X)(using qctx: QuoteContext)(using DummyImplicit, DummyImplicit): X = {
29+
val (params, bodyExpr) = paramsAndBody[R](f)
30+
content(bodyExpr, [t] => (e: Expr[t]) => (v1: Expr[T1], v2: Expr[T2], v3: Expr[T3]) => bodyFn[t](e.unseal, params, List(v1.unseal, v2.unseal, v3.unseal)).seal.asInstanceOf[Expr[t]])
31+
}
32+
private def paramsAndBody[R](using qctx: QuoteContext)(f: Expr[Any]): (List[qctx.reflect.ValDef], Expr[R]) = {
33+
import qctx.reflect._
34+
val Block(List(DefDef("$anonfun", Nil, List(params), _, Some(body))), Closure(Ident("$anonfun"), None)) = f.unseal.etaExpand
35+
(params, body.seal.asInstanceOf[Expr[R]])
36+
}
37+
38+
private def bodyFn[t](using qctx: QuoteContext)(e: qctx.reflect.Term, params: List[qctx.reflect.ValDef], args: List[qctx.reflect.Term]): qctx.reflect.Term = {
39+
import qctx.reflect._
40+
val map = params.map(_.symbol).zip(args).toMap
41+
new TreeMap {
42+
override def transformTerm(tree: Term)(using ctx: Context): Term =
43+
super.transformTerm(tree) match
44+
case tree: Ident => map.getOrElse(tree.symbol, tree)
45+
case tree => tree
46+
}.transformTerm(e)
47+
}
48+
}

tests/run-macros/quoted-matching-docs/Macro_1.scala

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import scala.quoted._
22

3-
import scala.quoted.unsafe._
4-
53
inline def sum(args: Int*): Int = ${ sumExpr('args) }
64

75
inline def sumShow(args: Int*): String = ${ sumExprShow('args) }
@@ -27,4 +25,9 @@ private def sumExpr(argsExpr: Expr[Seq[Int]])(using qctx: QuoteContext) : Expr[I
2725
case _ =>
2826
'{ $argsExpr.sum }
2927
}
28+
}
29+
30+
object UnsafeExpr {
31+
def underlyingArgument[T](expr: Expr[T])(using qctx: QuoteContext): Expr[T] =
32+
expr.unseal.underlyingArgument.seal.asInstanceOf[Expr[T]]
3033
}

0 commit comments

Comments
 (0)