Skip to content

Commit 5adfd3a

Browse files
committed
Remove reflect refinement form nested quotes
This refinement is unsound as the nested `reflect` is not the same as the outer one. In theory we could make it work by using the refinement ``` type Nested = Quotes { type Tree >: self.reflect.Tree ... } ``` This refinement is unfortunately too large for the compiler to handle. Removing the refinement forces us to transform trees into `Expr` before using them in a splice. This is in general a better practice anyway.
1 parent 7f2c4f6 commit 5adfd3a

File tree

9 files changed

+24
-25
lines changed

9 files changed

+24
-25
lines changed

library/src/scala/quoted/Quotes.scala

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3697,21 +3697,7 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
36973697

36983698
}
36993699

3700-
/** Type of a Quotes provided by a splice within a quote that took this context.
3701-
* It is only required if working with the reflection API.
3702-
*
3703-
* Usually it is infered by the quotes an splices typing. But sometimes it is necessary
3704-
* to explicitly state that a context is nested as in the following example:
3705-
*
3706-
* ```scala
3707-
* def run(using Quotes)(tree: qctx.reflect.Tree): Unit =
3708-
* def nested()(using qctx.Nested): Expr[Int] = '{ ${ makeExpr(tree) } + 1 }
3709-
* '{ ${ nested() } + 2 }
3710-
* def makeExpr(using Quotes)(tree: qctx.reflect.Tree): Expr[Int] = ???
3711-
* ```
3712-
*/
3713-
type Nested = Quotes {
3714-
val reflect: self.reflect.type
3715-
}
3700+
/** Type of a `Quotes` provided by a splice within a quote that took this context. */
3701+
type Nested = Quotes
37163702

37173703
}

tests/neg-macros/i8045.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import scala.quoted._
2+
object Test
3+
def run(using Quotes)(tree: quotes.reflect.Tree): Unit =
4+
'{ ${ makeExpr(tree) } + 1 } // error
5+
def makeExpr(using Quotes)(tree: quotes.reflect.Tree): Expr[Int] = ???

tests/neg-macros/i8045b.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import scala.quoted._
2+
object Test
3+
def run(using q: Quotes)(tree: q.reflect.Tree): Unit =
4+
def nested()(using q.Nested): Expr[Int] =
5+
'{ ${ makeExpr(tree) } + 1 } // error
6+
'{ ${ nested() } + 2 }
7+
8+
def makeExpr(using q: Quotes)(tree: q.reflect.Tree): Expr[Int] = ???

tests/pos-macros/i8045.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import scala.quoted._
22
object Test
33
def run(using Quotes)(tree: quotes.reflect.Tree): Unit =
4+
def makeExpr(tree: quotes.reflect.Tree): Expr[Int] = ???
45
'{ ${ makeExpr(tree) } + 1 }
5-
def makeExpr(using Quotes)(tree: quotes.reflect.Tree): Expr[Int] = ???

tests/pos-macros/i8045b.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import scala.quoted._
22
object Test
33
def run(using q: Quotes)(tree: q.reflect.Tree): Unit =
4+
def makeExpr(tree: q.reflect.Tree): Expr[Int] = ???
45
def nested()(using q.Nested): Expr[Int] =
56
'{ ${ makeExpr(tree) } + 1 }
67
'{ ${ nested() } + 2 }
78

8-
def makeExpr(using q: Quotes)(tree: q.reflect.Tree): Expr[Int] = ???

tests/run-macros/tasty-macro-positions/quoted_1.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,20 @@ object Macros {
1010

1111
def impl(x: Expr[Any])(using Quotes) : Expr[Unit] = {
1212
import quotes.reflect._
13-
val pos = Term.of(x).underlyingArgument.pos
13+
val pos = posStr(Term.of(x).underlyingArgument.pos)
1414
val code = Term.of(x).underlyingArgument.show
1515
'{
16-
println(${posStr(pos)})
16+
println($pos)
1717
println(${Expr(code)})
1818
}
1919
}
2020

2121
def impl2[T](using x: Type[T])(using Quotes) : Expr[Unit] = {
2222
import quotes.reflect._
23-
val pos = TypeTree.of[T].pos
23+
val pos = posStr(TypeTree.of[T].pos)
2424
val code = TypeTree.of[T].show
2525
'{
26-
println(${posStr(pos)})
26+
println($pos)
2727
println(${Expr(code)})
2828
}
2929
}

tests/run-staging/multi-staging.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
stage1 code: ((q1: scala.quoted.Quotes) ?=> {
22
val x1: scala.Int = 2
3-
scala.quoted.runtime.Expr.quote[scala.Int](1.+(scala.quoted.runtime.Expr.nestedSplice[scala.Int](q1)(((evidence$5: q1.Nested) ?=> scala.quoted.Expr.apply[scala.Int](x1)(scala.quoted.Liftable.IntLiftable[scala.Int])(evidence$5))))).apply(using q1)
3+
scala.quoted.runtime.Expr.quote[scala.Int](1.+(scala.quoted.runtime.Expr.nestedSplice[scala.Int](q1)(((evidence$5: scala.quoted.Quotes) ?=> scala.quoted.Expr.apply[scala.Int](x1)(scala.quoted.Liftable.IntLiftable[scala.Int])(evidence$5))))).apply(using q1)
44
})
55
3
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
((q: scala.quoted.Quotes) ?=> {
22
val a: scala.quoted.Expr[scala.Int] = scala.quoted.runtime.Expr.quote[scala.Int](4).apply(using q)
3-
((evidence$2: q.Nested) ?=> a).asInstanceOf[scala.ContextFunction1[scala.quoted.Quotes, scala.quoted.Expr[scala.Int]]].apply(using q)
3+
((evidence$2: scala.quoted.Quotes) ?=> a).asInstanceOf[scala.ContextFunction1[scala.quoted.Quotes, scala.quoted.Expr[scala.Int]]].apply(using q)
44
})
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
((q: scala.quoted.Quotes) ?=> {
22
val a: scala.quoted.Expr[scala.Int] = scala.quoted.runtime.Expr.quote[scala.Int](4).apply(using q)
3-
((q2: scala.quoted.Quotes) ?=> ((evidence$3: q2.Nested) ?=> a).asInstanceOf[scala.ContextFunction1[scala.quoted.Quotes, scala.quoted.Expr[scala.Int]]].apply(using q2)).apply(using q)
3+
((q2: scala.quoted.Quotes) ?=> ((evidence$3: scala.quoted.Quotes) ?=> a).asInstanceOf[scala.ContextFunction1[scala.quoted.Quotes, scala.quoted.Expr[scala.Int]]].apply(using q2)).apply(using q)
44
})

0 commit comments

Comments
 (0)