diff --git a/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala b/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala index a95bd7a4f44d..8af0f7acee12 100644 --- a/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala +++ b/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala @@ -77,7 +77,6 @@ class ReifyQuotes extends MacroTransform { case tree: RefTree if !Inliner.inInlineMethod => assert(!tree.symbol.isQuote) assert(!tree.symbol.isExprSplice) - assert(!tree.symbol.isTypeSplice) case _ : TypeDef => assert(!tree.symbol.hasAnnotation(defn.InternalQuoted_QuoteTypeTagAnnot), s"${tree.symbol} should have been removed by PickledQuotes because it has a @quoteTypeTag") @@ -210,16 +209,15 @@ class ReifyQuotes extends MacroTransform { * are in the body of an inline method. */ protected def transformSpliceType(body: Tree, splice: Select)(using Context): Tree = - if (level > 1) { + if level > 1 then val body1 = nested(isQuote = false).transform(body)(using spliceContext) cpy.Select(splice)(body1, splice.name) - } - else { - assert(level == 1, "unexpected top splice outside quote") + else if level == 1 then val (body1, quotes) = nested(isQuote = false).splitSplice(body)(using spliceContext) val tpe = outer.embedded.getHoleType(body, splice) makeHole(splice.isTerm, body1, quotes, tpe).withSpan(splice.span) - } + else + splice /** Transforms the contents of a nested splice * Assuming diff --git a/tests/neg-macros/i6997.scala b/tests/neg-macros/i6997.scala index c90239ef986a..f48f8a8af2e6 100644 --- a/tests/neg-macros/i6997.scala +++ b/tests/neg-macros/i6997.scala @@ -2,7 +2,7 @@ import scala.quoted._ class Foo { def mcrImpl(body: Expr[Any])(using t: Type[_ <: Any])(using ctx: QuoteContext): Expr[Any] = '{ - val tmp = ???.asInstanceOf[$t] // error // error + val tmp = ???.asInstanceOf[t.Underlying] // error // error tmp } } diff --git a/tests/neg-macros/i7048e.scala b/tests/neg-macros/i7048e.scala index 1ad1891afab6..ffe4f843a4ed 100644 --- a/tests/neg-macros/i7048e.scala +++ b/tests/neg-macros/i7048e.scala @@ -16,18 +16,18 @@ abstract class Test { import t.given println(summon[Type[t.T]].show) // val r = '{Option.empty[t.T]} // access to value t from wrong staging level - val r2 = '{Option.empty[${t.T}]} // works + val r2 = '{Option.empty[t.T.Underlying]} // works } { - val r1 = '{Option.empty[${T}]} // works - val r2 = '{Option.empty[List[${T}]]} // works - val r3 = '{summon[Type[${T}]]} // error: is not stable - val r4 = '{summon[${T} <:< Any]} // error: is not stable + val r1 = '{Option.empty[T.Underlying]} // works + val r2 = '{Option.empty[List[T.Underlying]]} // works + val r3 = '{summon[Type[T.Underlying]]} // error: is not stable + val r4 = '{summon[T.Underlying <:< Any]} // error: is not stable } { - val s = '{Option.empty[${T}]} // works + val s = '{Option.empty[T.Underlying]} // works val r = '{identity($s)} // works val r2 = '{identity(${s: Expr[Option[T]]})} // error // error : is not stable } diff --git a/tests/pos-macros/i4023c/Macro_1.scala b/tests/pos-macros/i4023c/Macro_1.scala index 7998b9166beb..3a6e8d52f090 100644 --- a/tests/pos-macros/i4023c/Macro_1.scala +++ b/tests/pos-macros/i4023c/Macro_1.scala @@ -1,5 +1,5 @@ import scala.quoted._ object Macro { inline def ff[T](x: T): T = ${ impl('x) } - def impl[T](x: Expr[T])(implicit t: Type[T], qctx: QuoteContext): Expr[T] = '{ $x: $t } + def impl[T](x: Expr[T])(implicit t: Type[T], qctx: QuoteContext): Expr[T] = '{ $x: T } } diff --git a/tests/pos-macros/i4774a.scala b/tests/pos-macros/i4774a.scala index 4fa5e5aa0bc0..d525451a3e63 100644 --- a/tests/pos-macros/i4774a.scala +++ b/tests/pos-macros/i4774a.scala @@ -3,7 +3,7 @@ import scala.quoted._ object Test { def loop[T](x: Expr[T])(implicit t: Type[T], qctx: QuoteContext): Expr[T] = '{ - val y: $t = $x + val y: T = $x ${loop('y)} } } diff --git a/tests/neg-macros/i4774b.scala b/tests/pos-macros/i4774b.scala similarity index 71% rename from tests/neg-macros/i4774b.scala rename to tests/pos-macros/i4774b.scala index efb4b591564e..f16197dc0b3f 100644 --- a/tests/neg-macros/i4774b.scala +++ b/tests/pos-macros/i4774b.scala @@ -3,8 +3,8 @@ import scala.quoted._ object Test { def loop[T](x: Expr[T])(implicit t: Type[T], qctx: QuoteContext): Expr[T] = '{ - val y: $t = $x; - ${loop[$t]( // error + val y: t.Underlying = $x; + ${loop[t.Underlying]( 'y )} } diff --git a/tests/pos-macros/i6210/Macros_1.scala b/tests/pos-macros/i6210/Macros_1.scala index b54747d9d20b..69342a6a1777 100644 --- a/tests/pos-macros/i6210/Macros_1.scala +++ b/tests/pos-macros/i6210/Macros_1.scala @@ -7,8 +7,8 @@ object Macro { def impl[A : Type, B : Type](using QuoteContext): Expr[Any] = { val t = Type[Map[A, B]] '{ - new Object().asInstanceOf[$t] - ???.asInstanceOf[$t] + new Object().asInstanceOf[t.Underlying] + ???.asInstanceOf[t.Underlying] } } } diff --git a/tests/pos-macros/i7048e.scala b/tests/pos-macros/i7048e.scala index 5d08d59dd841..ea27dd3ef141 100644 --- a/tests/pos-macros/i7048e.scala +++ b/tests/pos-macros/i7048e.scala @@ -16,18 +16,18 @@ abstract class Test { import t.given println(summon[Type[t.T]].show) // val r = '{Option.empty[t.T]} // access to value t from wrong staging level - val r2 = '{Option.empty[${t.T}]} + val r2 = '{Option.empty[t.T.Underlying]} } { - val r1 = '{Option.empty[${T}]} // works - val r2 = '{Option.empty[List[${T}]]} // works - // val r3 = '{summon[Type[${T}]]} // access to Test.this from wrong staging level - val r4 = '{summon[${T} <:< Any]} + val r1 = '{Option.empty[T.Underlying]} // works + val r2 = '{Option.empty[List[T.Underlying]]} // works + // val r3 = '{summon[Type[T.Underlying]]} // access to Test.this from wrong staging level + val r4 = '{summon[T.Underlying <:< Any]} } { - val s = '{Option.empty[${T}]} + val s = '{Option.empty[T.Underlying]} val r = '{identity($s)} // works val r2 = '{identity(${s: Expr[Option[T]]})} } diff --git a/tests/pos-macros/i7405.scala b/tests/pos-macros/i7405.scala index c90445068ad7..8a4aa80a7094 100644 --- a/tests/pos-macros/i7405.scala +++ b/tests/pos-macros/i7405.scala @@ -6,7 +6,7 @@ class Foo { val x: X = ??? ${ val t: Type[X] = Type[X] // Level 0 - '{ val y: $t = x } + '{ val y: t.Underlying = x } } } } diff --git a/tests/pos-macros/i7405b.scala b/tests/pos-macros/i7405b.scala index 6b4cf9233153..a55551d160b6 100644 --- a/tests/pos-macros/i7405b.scala +++ b/tests/pos-macros/i7405b.scala @@ -11,7 +11,8 @@ class Foo { type Z = x.Y ${ val t: Type[Z] = Type[Z] - '{ val y: $t = x.y } + '{ val y: Z = x.y } + '{ val y: t.Underlying = x.y } } } } diff --git a/tests/pos-macros/i7887.scala b/tests/pos-macros/i7887.scala index f4b10710942b..3d3fc82db3de 100644 --- a/tests/pos-macros/i7887.scala +++ b/tests/pos-macros/i7887.scala @@ -1,7 +1,7 @@ def typed[A](using t: quoted.Type[A], qctx: quoted.QuoteContext): Unit = { import qctx.reflect._ '{ - type T = $t + type T = A ${'{???}.cast[T]} } } diff --git a/tests/pos-macros/i9020-b/Macro_1.scala b/tests/pos-macros/i9020-b/Macro_1.scala index 2062988d3f00..a6aee0d04e82 100644 --- a/tests/pos-macros/i9020-b/Macro_1.scala +++ b/tests/pos-macros/i9020-b/Macro_1.scala @@ -8,8 +8,8 @@ object Show { import quoted._ def impl[T](using ctx: QuoteContext, tpe: Type[T]): Expr[Show[T]] = '{ - new Show[$tpe] { - def show(t: $tpe): String = "TODO" + new Show[tpe.Underlying] { + def show(t: tpe.Underlying): String = "TODO" } } } diff --git a/tests/pos-macros/quote-1.scala b/tests/pos-macros/quote-1.scala index 0790c2eeb74b..34afa62cf090 100644 --- a/tests/pos-macros/quote-1.scala +++ b/tests/pos-macros/quote-1.scala @@ -3,7 +3,7 @@ import scala.quoted._ class Test(using QuoteContext) { def f[T](x: Expr[T])(implicit t: Type[T]) = '{ - val y: $t = $x + val y: T = $x val z = $x } diff --git a/tests/run-macros/i7887/Macro_1.scala b/tests/run-macros/i7887/Macro_1.scala index bca9ad31bf9e..c605a8135240 100644 --- a/tests/run-macros/i7887/Macro_1.scala +++ b/tests/run-macros/i7887/Macro_1.scala @@ -3,7 +3,7 @@ def myMacroImpl(a: quoted.Expr[_])(using qctx: quoted.QuoteContext) = { def typed[A] = { implicit val t: quoted.Type[A] = a.unseal.tpe.widen.seal.asInstanceOf[quoted.Type[A]] '{ - type T = $t + type T = A ${a.unseal.seal.cast[T]} } } diff --git a/tests/run-macros/refined-selectable-macro/Macro_2.scala b/tests/run-macros/refined-selectable-macro/Macro_2.scala index 0102259c912f..d2f610bc9705 100644 --- a/tests/run-macros/refined-selectable-macro/Macro_2.scala +++ b/tests/run-macros/refined-selectable-macro/Macro_2.scala @@ -14,10 +14,10 @@ object Macro2 { object Record extends SelectableRecordCompanion[Record] { import scala.quoted._ - inline def apply[R <: Record](elems: (String, Any)*) : R = ${ applyImpl('elems, Type[R]) } + inline def apply[R <: Record](elems: (String, Any)*) : R = ${ applyImpl[R]('elems) } - def applyImpl[R <: Record: Type](elems: Expr[Seq[(String, Any)]], ev: Type[R])(using qctx: QuoteContext) = { - '{ new Record($elems:_*).asInstanceOf[$ev] } + def applyImpl[R <: Record: Type](elems: Expr[Seq[(String, Any)]])(using qctx: QuoteContext) = { + '{ new Record($elems:_*).asInstanceOf[R] } } def fromUntypedTuple(elems: (String, Any)*): Record = Record(elems: _*) diff --git a/tests/run-staging/i3823-b.scala b/tests/run-staging/i3823-b.scala index 94fa2dfb402e..0b9b978a00ba 100644 --- a/tests/run-staging/i3823-b.scala +++ b/tests/run-staging/i3823-b.scala @@ -4,7 +4,7 @@ object Test { given Toolbox = Toolbox.make(getClass.getClassLoader) def main(args: Array[String]): Unit = withQuoteContext { def f[T](x: Expr[T])(implicit t: Type[T]) = '{ - val z: $t = $x + val z: t.Underlying = $x } println(f('{2})(Type[Int]).show) } diff --git a/tests/run-staging/i3823.scala b/tests/run-staging/i3823.scala index b02df1212d8a..30e33dca6267 100644 --- a/tests/run-staging/i3823.scala +++ b/tests/run-staging/i3823.scala @@ -3,9 +3,9 @@ import scala.quoted.staging._ object Test { given Toolbox = Toolbox.make(getClass.getClassLoader) def main(args: Array[String]): Unit = withQuoteContext { - def f[T: Type](x: Expr[T])(t: Type[T]) = '{ - val z: $t = $x + def f[T](x: Expr[T])(using t: Type[T]) = '{ + val z: t.Underlying = $x } - println(f('{2})(Type[Int]).show) + println(f('{2})(using Type[Int]).show) } } \ No newline at end of file diff --git a/tests/run-staging/i3847-b.scala b/tests/run-staging/i3847-b.scala index 43d75b08949f..f941a1487f4a 100644 --- a/tests/run-staging/i3847-b.scala +++ b/tests/run-staging/i3847-b.scala @@ -6,7 +6,7 @@ object Arrays { implicit def ArrayIsLiftable[T: Liftable](implicit t: Type[T], qctx: QuoteContext): Liftable[Array[List[T]]] = { new Liftable[Array[List[T]]] { def toExpr(arr: Array[List[T]]) = '{ - new Array[List[$t]](${Expr(arr.length)}) + new Array[List[T]](${Expr(arr.length)}) // TODO add elements } } diff --git a/tests/run-staging/i3847.scala b/tests/run-staging/i3847.scala index 2fe1d02d6690..da68f1379995 100644 --- a/tests/run-staging/i3847.scala +++ b/tests/run-staging/i3847.scala @@ -6,7 +6,7 @@ object Arrays { implicit def ArrayIsLiftable[T: Liftable](implicit t: Type[T], ct: Expr[ClassTag[T]]): Liftable[Array[T]] = { new Liftable[Array[T]] { def toExpr(arr: Array[T]) = '{ - new Array[$t](${Expr(arr.length)})($ct) + new Array[t.Underlying](${Expr(arr.length)})($ct) // TODO add elements } } diff --git a/tests/run-staging/i4044e.scala b/tests/run-staging/i4044e.scala index 4a9c7f35c833..6449bfba50b1 100644 --- a/tests/run-staging/i4044e.scala +++ b/tests/run-staging/i4044e.scala @@ -7,7 +7,7 @@ class Foo { val e: Expr[Int] = '{3} val f: Expr[Int] = '{5} val t: Type[Int] = Type[Int] - val q = '{ ${ '{ ($e + $f).asInstanceOf[$t] } } } + val q = '{ ${ '{ ($e + $f).asInstanceOf[t.Underlying] } } } println(q.show) } } diff --git a/tests/run-staging/i5247.scala b/tests/run-staging/i5247.scala index 983e8070a842..a7d5c2da5690 100644 --- a/tests/run-staging/i5247.scala +++ b/tests/run-staging/i5247.scala @@ -9,10 +9,10 @@ object Test { } def foo[H : Type](using QuoteContext): Expr[H] = { val t = Type[H] - '{ null.asInstanceOf[$t] } + '{ null.asInstanceOf[t.Underlying] } } def bar[H : Type](using QuoteContext): Expr[List[H]] = { val t = Type[List[H]] - '{ null.asInstanceOf[$t] } + '{ null.asInstanceOf[t.Underlying] } } } diff --git a/tests/run-staging/quote-lib.scala b/tests/run-staging/quote-lib.scala index d1c3016669a0..794ac02cb205 100644 --- a/tests/run-staging/quote-lib.scala +++ b/tests/run-staging/quote-lib.scala @@ -127,12 +127,12 @@ package liftable { } object Lets { - def letVal[T, U: Type](expr: Expr[T])(body: Expr[T] => Expr[U])(implicit t: Type[T], qctx: QuoteContext): Expr[U] = - '{ val letVal: $t = $expr; ${ body('letVal) } } - def letLazyVal[T, U: Type](expr: Expr[T])(body: Expr[T] => Expr[U])(implicit t: Type[T], qctx: QuoteContext): Expr[U] = - '{ lazy val letLazyVal: $t = $expr; ${ body('letLazyVal) } } - def letDef[T, U: Type](expr: Expr[T])(body: Expr[T] => Expr[U])(implicit t: Type[T], qctx: QuoteContext): Expr[U] = - '{ def letDef: $t = $expr; ${ body('letDef) } } + def letVal[T: Type, U: Type](expr: Expr[T])(body: Expr[T] => Expr[U])(implicit qctx: QuoteContext): Expr[U] = + '{ val letVal: T = $expr; ${ body('letVal) } } + def letLazyVal[T: Type, U: Type](expr: Expr[T])(body: Expr[T] => Expr[U])(implicit qctx: QuoteContext): Expr[U] = + '{ lazy val letLazyVal: T = $expr; ${ body('letLazyVal) } } + def letDef[T: Type, U: Type](expr: Expr[T])(body: Expr[T] => Expr[U])(implicit qctx: QuoteContext): Expr[U] = + '{ def letDef: T = $expr; ${ body('letDef) } } } object Loops { @@ -145,7 +145,7 @@ package liftable { implicit class LiftedOps[T: Liftable](list: Expr[List[T]])(implicit t: Type[T]) { def foldLeft[U](acc: Expr[U])(f: Expr[(U, T) => U])(implicit u: Type[U], qctx: QuoteContext): Expr[U] = - '{ ($list).foldLeft[$u]($acc)($f) } + '{ ($list).foldLeft[U]($acc)($f) } def foreach(f: Expr[T => Unit])(using QuoteContext): Expr[Unit] = '{ ($list).foreach($f) } } diff --git a/tests/run-staging/quote-owners-2.scala b/tests/run-staging/quote-owners-2.scala index 616ecae54732..49a4cab34fca 100644 --- a/tests/run-staging/quote-owners-2.scala +++ b/tests/run-staging/quote-owners-2.scala @@ -12,8 +12,8 @@ object Test { def f(t: Type[List[Int]])(using QuoteContext): Expr[Int] = '{ def ff: Int = { - val a: $t = { - type T = $t + val a: t.Underlying = { + type T = t.Underlying val b: T = 3 :: Nil b } diff --git a/tests/run-staging/quote-type-tags.scala b/tests/run-staging/quote-type-tags.scala index d589669e5a01..3cc564de5102 100644 --- a/tests/run-staging/quote-type-tags.scala +++ b/tests/run-staging/quote-type-tags.scala @@ -5,7 +5,7 @@ object Test { given Toolbox = Toolbox.make(getClass.getClassLoader) def main(args: Array[String]): Unit = run { def asof[T: Type, U](x: Expr[T], t: Type[U]): Expr[U] = - '{$x.asInstanceOf[$t]} + '{$x.asInstanceOf[t.Underlying]} println(asof('{}, Type[Unit]).show) println(asof('{true}, Type[Boolean]).show) diff --git a/tests/run-staging/quote-unrolled-foreach.scala b/tests/run-staging/quote-unrolled-foreach.scala index c58958444ac9..93641d50cc12 100644 --- a/tests/run-staging/quote-unrolled-foreach.scala +++ b/tests/run-staging/quote-unrolled-foreach.scala @@ -57,7 +57,7 @@ object Test { val size = ($arrRef).length var i = 0 while (i < size) { - val element: $t = ($arrRef)(i) + val element: T = ($arrRef)(i) ($f)(element) i += 1 }