diff --git a/compiler/src/dotty/tools/dotc/ast/tpd.scala b/compiler/src/dotty/tools/dotc/ast/tpd.scala index 21bc91de2806..5f1717124a8c 100644 --- a/compiler/src/dotty/tools/dotc/ast/tpd.scala +++ b/compiler/src/dotty/tools/dotc/ast/tpd.scala @@ -1228,7 +1228,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo { val argType = if (baseType != NoType) baseType.argTypesHi.head else defn.NothingType - ref(defn.InternalQuoted_exprSplice).appliedToType(argType).appliedTo(tree) + ref(defn.InternalQuoted_exprSplice).appliedToTypes(List(argType, defn.QuoteContextClass.typeRef)).appliedTo(tree) } def unapply(tree: Tree)(implicit ctx: Context): Option[Tree] = tree match { case Apply(fn, arg :: Nil) if fn.symbol == defn.InternalQuoted_exprSplice => Some(arg) diff --git a/compiler/src/dotty/tools/dotc/core/StagingContext.scala b/compiler/src/dotty/tools/dotc/core/StagingContext.scala index b3f85b1ae589..6caba252cc90 100644 --- a/compiler/src/dotty/tools/dotc/core/StagingContext.scala +++ b/compiler/src/dotty/tools/dotc/core/StagingContext.scala @@ -1,6 +1,7 @@ package dotty.tools.dotc.core import dotty.tools.dotc.core.Contexts._ +import dotty.tools.dotc.ast.tpd import dotty.tools.dotc.util.Property import scala.collection.mutable @@ -10,6 +11,11 @@ object StagingContext { /** A key to be used in a context property that tracks the quoteation level */ private val QuotationLevel = new Property.Key[Int] + /** A key to be used in a context property that tracks the quoteation stack. + * Stack containing the QuoteContext references recieved by the surrounding quotes. + */ + private val QuoteContextStack = new Property.Key[List[tpd.Tree]] + /** All enclosing calls that are currently inlined, from innermost to outermost. */ def level(implicit ctx: Context): Int = ctx.property(QuotationLevel).getOrElse(0) @@ -18,8 +24,27 @@ object StagingContext { def quoteContext(implicit ctx: Context): Context = ctx.fresh.setProperty(QuotationLevel, level + 1) + /** Context with an incremented quotation level and pushes a refecence to a QuoteContext on the quote context stack */ + def pushQuoteContext(qctxRef: tpd.Tree)(implicit ctx: Context): Context = + val old = ctx.property(QuoteContextStack).getOrElse(List.empty) + ctx.fresh.setProperty(QuotationLevel, level + 1) + .setProperty(QuoteContextStack, qctxRef :: old) + /** Context with a decremented quotation level. */ def spliceContext(implicit ctx: Context): Context = ctx.fresh.setProperty(QuotationLevel, level - 1) -} + /** Context with a decremented quotation level and pops the Some of top of the quote context stack or None if the stack is empty. + * The quotation stack could be empty if we are in a top level splice or an eroneous splice directly witin a top level splice. + */ + def popQuoteContext()(implicit ctx: Context): (Option[tpd.Tree], Context) = + val ctx1 = ctx.fresh.setProperty(QuotationLevel, level - 1) + val head = + ctx.property(QuoteContextStack) match + case Some(x :: xs) => + ctx1.setProperty(QuoteContextStack, xs) + Some(x) + case _ => + None // Splice at level 0 or lower + (head, ctx1) +} diff --git a/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala b/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala index 6af4be1f943e..8ebc2386353a 100644 --- a/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala +++ b/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala @@ -60,7 +60,7 @@ object PickledQuotes { }.apply(tp) /** Unpickle the tree contained in the TastyExpr */ - def unpickleExpr(tasty: PickledQuote, args: PickledExprArgs)(implicit ctx: Context): Tree = { + def unpickleExpr(tasty: PickledQuote, args: PickledArgs)(implicit ctx: Context): Tree = { val tastyBytes = TastyString.unpickle(tasty) val unpickled = unpickle(tastyBytes, args, isType = false)(ctx.addMode(Mode.ReadPositions)) /** Force unpickling of the tree, removes the spliced type `@quotedTypeTag type` definitions and dealiases references to `@quotedTypeTag type` */ @@ -76,7 +76,7 @@ object PickledQuotes { } /** Unpickle the tree contained in the TastyType */ - def unpickleType(tasty: PickledQuote, args: PickledTypeArgs)(implicit ctx: Context): Tree = { + def unpickleType(tasty: PickledQuote, args: PickledArgs)(implicit ctx: Context): Tree = { val tastyBytes = TastyString.unpickle(tasty) val unpickled = unpickle(tastyBytes, args, isType = true)(ctx.addMode(Mode.ReadPositions)) val tpt = unpickled match { diff --git a/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala b/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala index 17d8d8fef925..4f074a3fcd89 100644 --- a/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala +++ b/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala @@ -35,10 +35,10 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend // QUOTE UNPICKLING // ////////////////////// - def unpickleExpr(repr: Unpickler.PickledQuote, args: Unpickler.PickledExprArgs): scala.quoted.Expr[?] = + def unpickleExpr(repr: Unpickler.PickledQuote, args: Unpickler.PickledArgs): scala.quoted.Expr[?] = new TastyTreeExpr(PickledQuotes.unpickleExpr(repr, args), compilerId) - def unpickleType(repr: Unpickler.PickledQuote, args: Unpickler.PickledTypeArgs): scala.quoted.Type[?] = + def unpickleType(repr: Unpickler.PickledQuote, args: Unpickler.PickledArgs): scala.quoted.Type[?] = new TreeType(PickledQuotes.unpickleType(repr, args), compilerId) @@ -67,7 +67,7 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend def Context_requiredMethod(self: Context)(path: String): Symbol = self.requiredMethod(path) def Context_isJavaCompilationUnit(self: Context): Boolean = self.compilationUnit.isInstanceOf[fromtasty.JavaCompilationUnit] def Context_isScala2CompilationUnit(self: Context): Boolean = self.compilationUnit.isInstanceOf[fromtasty.Scala2CompilationUnit] - def Context_compilationUnitClassname(self: Context): String = + def Context_compilationUnitClassname(self: Context): String = self.compilationUnit match { case cu: fromtasty.JavaCompilationUnit => cu.className case cu: fromtasty.Scala2CompilationUnit => cu.className diff --git a/compiler/src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala b/compiler/src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala index 254f03ffd61a..dda62deed5f2 100644 --- a/compiler/src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala +++ b/compiler/src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala @@ -68,11 +68,11 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages( protected def transformSplice(body: Tree, splice: Tree)(implicit ctx: Context): Tree = { val body1 = transform(body)(spliceContext) splice match { - case Apply(fun: TypeApply, _) if splice.isTerm => + case Apply(fun @ TypeApply(_, _ :: qctx :: Nil), _) if splice.isTerm => // Type of the splice itsel must also be healed // internal.Quoted.expr[F[T]](... T ...) --> internal.Quoted.expr[F[$t]](... T ...) val tp = checkType(splice.sourcePos).apply(splice.tpe.widenTermRefExpr) - cpy.Apply(splice)(cpy.TypeApply(fun)(fun.fun, tpd.TypeTree(tp) :: Nil), body1 :: Nil) + cpy.Apply(splice)(cpy.TypeApply(fun)(fun.fun, tpd.TypeTree(tp) :: qctx :: Nil), body1 :: Nil) case splice: Select => cpy.Select(splice)(body1, splice.name) } } diff --git a/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala b/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala index 404cdb1e4c52..9cafe398161c 100644 --- a/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala +++ b/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala @@ -230,11 +230,8 @@ class ReifyQuotes extends MacroTransform { val meth = if (isType) ref(defn.Unpickler_unpickleType).appliedToType(originalTp) else ref(defn.Unpickler_unpickleExpr).appliedToType(originalTp.widen) - val spliceResType = - if (isType) defn.QuotedTypeClass.typeRef.appliedTo(WildcardType) - else defn.FunctionType(1, isContextual = true).appliedTo(defn.QuoteContextClass.typeRef, defn.QuotedExprClass.typeRef.appliedTo(defn.AnyType)) | defn.QuotedTypeClass.typeRef.appliedTo(WildcardType) val pickledQuoteStrings = liftList(PickledQuotes.pickleQuote(body).map(x => Literal(Constant(x))), defn.StringType) - val splicesList = liftList(splices, defn.FunctionType(1).appliedTo(defn.SeqType.appliedTo(defn.AnyType), spliceResType)) + val splicesList = liftList(splices, defn.FunctionType(1).appliedTo(defn.SeqType.appliedTo(defn.AnyType), defn.AnyType)) meth.appliedTo(pickledQuoteStrings, splicesList) } @@ -394,7 +391,7 @@ class ReifyQuotes extends MacroTransform { val body = capturers(tree.symbol).apply(tree) val splice: Tree = if (tree.isType) body.select(tpnme.splice) - else ref(defn.InternalQuoted_exprSplice).appliedToType(tree.tpe).appliedTo(body) + else ref(defn.InternalQuoted_exprSplice).appliedToTypes(List(tree.tpe, defn.QuoteContextClass.typeRef)).appliedTo(body) transformSplice(body, splice) diff --git a/compiler/src/dotty/tools/dotc/transform/TreeMapWithStages.scala b/compiler/src/dotty/tools/dotc/transform/TreeMapWithStages.scala index 1f74062cf9c3..6e86c25d526a 100644 --- a/compiler/src/dotty/tools/dotc/transform/TreeMapWithStages.scala +++ b/compiler/src/dotty/tools/dotc/transform/TreeMapWithStages.scala @@ -90,7 +90,10 @@ abstract class TreeMapWithStages(@constructorOnly ictx: Context) extends TreeMap case Quoted(quotedTree) => dropEmptyBlocks(quotedTree) match { - case Spliced(t) => transform(t) // '{ $x } --> x + case Spliced(t) => + // '{ $x } --> x + // and adapt the refinment of `QuoteContext { type tasty: ... } ?=> Expr[T]` + transform(t).asInstance(tree.tpe) case _ => transformQuotation(quotedTree, tree) } diff --git a/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala b/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala index 643509cd829a..5279282452bc 100644 --- a/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala +++ b/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala @@ -45,10 +45,16 @@ trait QuotesAndSplices { ctx.warning("Canceled splice directly inside a quote. '[ ${ XYZ } ] is equivalent to XYZ.", tree.sourcePos) case _ => } + val qctx = inferImplicitArg(defn.QuoteContextClass.typeRef, tree.span) + if (level == 0 && qctx.tpe.isInstanceOf[SearchFailureType]) + ctx.error(missingArgMsg(qctx, defn.QuoteContextClass.typeRef, ""), ctx.source.atSpan(tree.span)) val tree1 = - if (ctx.mode.is(Mode.Pattern) && level == 0) typedQuotePattern(tree, pt) - else if (tree.quoted.isType) typedTypeApply(untpd.TypeApply(untpd.ref(defn.InternalQuoted_typeQuote.termRef), tree.quoted :: Nil), pt)(quoteContext) - else typedApply(untpd.Apply(untpd.ref(defn.InternalQuoted_exprQuote.termRef), tree.quoted), pt)(quoteContext) + if ctx.mode.is(Mode.Pattern) && level == 0 then + typedQuotePattern(tree, pt, qctx) + else if (tree.quoted.isType) + typedTypeApply(untpd.TypeApply(untpd.ref(defn.InternalQuoted_typeQuote.termRef), tree.quoted :: Nil), pt)(quoteContext) + else + typedApply(untpd.Apply(untpd.ref(defn.InternalQuoted_exprQuote.termRef), tree.quoted), pt)(pushQuoteContext(qctx)).select(nme.apply).appliedTo(qctx) tree1.withSpan(tree.span) } @@ -85,19 +91,23 @@ trait QuotesAndSplices { markAsMacro(ctx) } + val (outerQctx, ctx1) = popQuoteContext() + // Explicitly provide the given QuoteContext of the splice. // * Avoids leaking implementation details of scala.internal.quoted.CompileTime.exprSplice, // such as exprSplice taking a ?=> function argument // * Provide meaningful names for QuoteContext synthesized by within `${ ... }` - // * TODO preserve QuoteContext.tasty path dependent type (see comment below and #8045) - val qctxParamName = NameKinds.UniqueName.fresh(s"qctx${level - 1}_".toTermName) - // TODO: Refine QuoteContext with the tasty context that the quote received - // If encoloseing quote receives `qctx` then this type should be `QuoteContext { val tasty: qxtx.tasty.type }` - val qctxParamTpt = untpd.TypedSplice(TypeTree(defn.QuoteContextClass.typeRef)) + // * If within a quote, provide a QuoteContext is linked typewise with the outer QuoteContext + val qctxParamName = NameKinds.UniqueName.fresh(s"qctx${if level > 0 then level - 1 else ""}_".toTermName) + val qctxParamTpe = outerQctx match { + case Some(qctxRef) => qctxRef.tpe.select("NestedContext".toTypeName) + case _ => defn.QuoteContextClass.typeRef // splice at level 0 (or lower) + } + val qctxParamTpt = untpd.TypedSplice(TypeTree(qctxParamTpe)) val qctxParam = untpd.makeParameter(qctxParamName, qctxParamTpt, untpd.Modifiers(Given)) val expr = untpd.Function(List(qctxParam), tree.expr).withSpan(tree.span) - typedApply(untpd.Apply(untpd.ref(defn.InternalQuoted_exprSplice.termRef), expr), pt)(spliceContext).withSpan(tree.span) + typedApply(untpd.Apply(untpd.ref(defn.InternalQuoted_exprSplice.termRef), expr), pt)(ctx1).withSpan(tree.span) } } @@ -326,11 +336,7 @@ trait QuotesAndSplices { * ) => ... * ``` */ - private def typedQuotePattern(tree: untpd.Quote, pt: Type)(implicit ctx: Context): Tree = { - val qctx = inferImplicitArg(defn.QuoteContextClass.typeRef, tree.span) - if (level == 0 && qctx.tpe.isInstanceOf[SearchFailureType]) - ctx.error(missingArgMsg(qctx, defn.QuoteContextClass.typeRef, ""), ctx.source.atSpan(tree.span)) - + private def typedQuotePattern(tree: untpd.Quote, pt: Type, qctx: Tree)(implicit ctx: Context): Tree = { val quoted = tree.quoted val exprPt = pt.baseType(if quoted.isType then defn.QuotedTypeClass else defn.QuotedExprClass) val quotedPt = exprPt.argInfos.headOption match { diff --git a/library/src-bootstrapped/scala/internal/quoted/CompileTime.scala b/library/src-bootstrapped/scala/internal/quoted/CompileTime.scala new file mode 100644 index 000000000000..bd96f1f8f734 --- /dev/null +++ b/library/src-bootstrapped/scala/internal/quoted/CompileTime.scala @@ -0,0 +1,48 @@ +package scala.internal.quoted + +import scala.annotation.{Annotation, compileTimeOnly} +import scala.quoted._ + +@compileTimeOnly("Illegal reference to `scala.internal.quoted.CompileTime`") +object CompileTime { + + /** A term quote is desugared by the compiler into a call to this method */ + @compileTimeOnly("Illegal reference to `scala.internal.quoted.CompileTime.exprQuote`") + def exprQuote[T](x: T): QuoteContext ?=> Expr[T] = ??? + + /** A term splice is desugared by the compiler into a call to this method */ + @compileTimeOnly("Illegal reference to `scala.internal.quoted.CompileTime.exprSplice`") + def exprSplice[T, QCtx <: QuoteContext](x: QCtx ?=> Expr[T]): T = ??? + + /** A type quote is desugared by the compiler into a call to this method */ + @compileTimeOnly("Illegal reference to `scala.internal.quoted.CompileTime.typeQuote`") + def typeQuote[T <: AnyKind]: Type[T] = ??? + + /** A splice in a quoted pattern is desugared by the compiler into a call to this method */ + @compileTimeOnly("Illegal reference to `scala.internal.quoted.CompileTime.patternHole`") + def patternHole[T]: T = ??? + + /** A splice of a name in a quoted pattern is desugared by wrapping getting this annotation */ + @compileTimeOnly("Illegal reference to `scala.internal.quoted.CompileTime.patternBindHole`") + class patternBindHole extends Annotation + + /** A splice of a name in a quoted pattern is that marks the definition of a type splice */ + @compileTimeOnly("Illegal reference to `scala.internal.quoted.CompileTime.patternType`") + class patternType extends Annotation + + /** A type pattern that must be aproximated from above */ + @compileTimeOnly("Illegal reference to `scala.internal.quoted.CompileTime.fromAbove`") + class fromAbove extends Annotation + + /** Artifact of pickled type splices + * + * During quote reification a quote `'{ ... F[$t] ... }` will be transformed into + * `'{ @quoteTypeTag type T$1 = $t ... F[T$1] ... }` to have a tree for `$t`. + * This artifact is removed during quote unpickling. + * + * See ReifyQuotes.scala and PickledQuotes.scala + */ + @compileTimeOnly("Illegal reference to `scala.internal.quoted.CompileTime.quoteTypeTag`") + class quoteTypeTag extends Annotation + +} diff --git a/library/src/scala/internal/quoted/CompileTime.scala b/library/src-non-bootstrapped/scala/internal/quoted/CompileTime.scala similarity index 100% rename from library/src/scala/internal/quoted/CompileTime.scala rename to library/src-non-bootstrapped/scala/internal/quoted/CompileTime.scala diff --git a/library/src/scala/internal/quoted/Unpickler.scala b/library/src/scala/internal/quoted/Unpickler.scala index 2fab9bfc01be..14dd501c4cee 100644 --- a/library/src/scala/internal/quoted/Unpickler.scala +++ b/library/src/scala/internal/quoted/Unpickler.scala @@ -6,19 +6,18 @@ import scala.quoted.{Expr, QuoteContext, Type} object Unpickler { type PickledQuote = List[String] - type PickledExprArgs = Seq[Seq[Any] => ((QuoteContext ?=> Expr[Any]) | Type[_])] - type PickledTypeArgs = Seq[Seq[Any] => Type[_]] + type PickledArgs = Seq[Seq[Any] => Any/*(([QCtx <: QuoteContext] =>> QCtx ?=> Expr[Any]) | Type[_])*/] /** Unpickle `repr` which represents a pickled `Expr` tree, * replacing splice nodes with `args` */ - def unpickleExpr[T](repr: PickledQuote, args: PickledExprArgs): QuoteContext ?=> Expr[T] = + def unpickleExpr[T](repr: PickledQuote, args: PickledArgs): QuoteContext ?=> Expr[T] = summon[QuoteContext].tasty.internal.unpickleExpr(repr, args).asInstanceOf[Expr[T]] /** Unpickle `repr` which represents a pickled `Type` tree, * replacing splice nodes with `args` */ - def unpickleType[T](repr: PickledQuote, args: PickledTypeArgs): QuoteContext ?=> Type[T] = + def unpickleType[T](repr: PickledQuote, args: PickledArgs): QuoteContext ?=> Type[T] = summon[QuoteContext].tasty.internal.unpickleType(repr, args).asInstanceOf[Type[T]] } diff --git a/library/src/scala/quoted/QuoteContext.scala b/library/src/scala/quoted/QuoteContext.scala index e169f7ef5fb5..84cf66c75581 100644 --- a/library/src/scala/quoted/QuoteContext.scala +++ b/library/src/scala/quoted/QuoteContext.scala @@ -10,13 +10,32 @@ import scala.quoted.show.SyntaxHighlight * * @param tasty Typed AST API. Usage: `def f(qctx: QuoteContext) = { import qctx.tasty.{_, given}; ... }`. */ -class QuoteContext(val tasty: scala.tasty.Reflection) { +class QuoteContext(val tasty: scala.tasty.Reflection) { self => + /** Type of a QuoteContext profided by a splice within a quote that took this context. + * It is only required if working with the reflection API. + * + * Usually it is infered by the quotes an splices typing. But sometimes it is necessary + * to explicitly state that a context is nested as in the following example: + * + * ```scala + * def run(using qctx: QuoteContext)(tree: qctx.tasty.Tree): Unit = + * def nested()(using qctx.NestedContext): Expr[Int] = '{ ${ makeExpr(tree) } + 1 } + * '{ ${ nested() } + 2 } + * def makeExpr(using qctx: QuoteContext)(tree: qctx.tasty.Tree): Expr[Int] = ??? + * ``` + */ + type NestedContext = QuoteContext { + val tasty: self.tasty.type + } + + /** Show the fully elaborated source code representation of an expression */ def show(expr: Expr[_], syntaxHighlight: SyntaxHighlight): String = { import tasty.{_, given} expr.unseal.showWith(syntaxHighlight) } + /** Show the fully elaborated source code representation of a type */ def show(tpe: Type[_], syntaxHighlight: SyntaxHighlight): String = { import tasty.{_, given} tpe.unseal.showWith(syntaxHighlight) diff --git a/library/src/scala/tasty/reflect/CompilerInterface.scala b/library/src/scala/tasty/reflect/CompilerInterface.scala index 4d8bde281daf..150e8c11cc8e 100644 --- a/library/src/scala/tasty/reflect/CompilerInterface.scala +++ b/library/src/scala/tasty/reflect/CompilerInterface.scala @@ -125,12 +125,12 @@ trait CompilerInterface { /** Unpickle `repr` which represents a pickled `Expr` tree, * replacing splice nodes with `args` */ - def unpickleExpr(repr: Unpickler.PickledQuote, args: Unpickler.PickledExprArgs): scala.quoted.Expr[_] + def unpickleExpr(repr: Unpickler.PickledQuote, args: Unpickler.PickledArgs): scala.quoted.Expr[_] /** Unpickle `repr` which represents a pickled `Type` tree, * replacing splice nodes with `args` */ - def unpickleType(repr: Unpickler.PickledQuote, args: Unpickler.PickledTypeArgs): scala.quoted.Type[_] + def unpickleType(repr: Unpickler.PickledQuote, args: Unpickler.PickledArgs): scala.quoted.Type[_] ///////////// diff --git a/tests/pos/i8045.scala b/tests/pos/i8045.scala new file mode 100644 index 000000000000..2e49b6b3fe09 --- /dev/null +++ b/tests/pos/i8045.scala @@ -0,0 +1,5 @@ +import scala.quoted._ +object Test + def run(using qctx: QuoteContext)(tree: qctx.tasty.Tree): Unit = + '{ ${ makeExpr(tree) } + 1 } + def makeExpr(using qctx: QuoteContext)(tree: qctx.tasty.Tree): Expr[Int] = ??? diff --git a/tests/pos/i8045b.scala b/tests/pos/i8045b.scala new file mode 100644 index 000000000000..98cd489ab4f0 --- /dev/null +++ b/tests/pos/i8045b.scala @@ -0,0 +1,8 @@ +import scala.quoted._ +object Test + def run(using qctx: QuoteContext)(tree: qctx.tasty.Tree): Unit = + def nested()(using qctx.NestedContext): Expr[Int] = + '{ ${ makeExpr(tree) } + 1 } + '{ ${ nested() } + 2 } + + def makeExpr(using qctx: QuoteContext)(tree: qctx.tasty.Tree): Expr[Int] = ??? diff --git a/tests/run-staging/quote-nested-2.check b/tests/run-staging/quote-nested-2.check index f1e228066874..18f09dc182ee 100644 --- a/tests/run-staging/quote-nested-2.check +++ b/tests/run-staging/quote-nested-2.check @@ -1,4 +1,4 @@ ((qctx: scala.quoted.QuoteContext) ?=> { val a: scala.quoted.Expr[scala.Int] = scala.internal.quoted.CompileTime.exprQuote[scala.Int](4).apply(using qctx) - ((qctx1_$1: scala.quoted.QuoteContext) ?=> a).apply(using qctx) + ((qctx1_$1: qctx.NestedContext) ?=> a).asInstanceOf[scala.ContextFunction1[scala.quoted.QuoteContext, scala.quoted.Expr[scala.Int]]].apply(using qctx) }) diff --git a/tests/run-staging/quote-nested-5.check b/tests/run-staging/quote-nested-5.check index 02d099124875..0296b75b63af 100644 --- a/tests/run-staging/quote-nested-5.check +++ b/tests/run-staging/quote-nested-5.check @@ -1,4 +1,4 @@ ((qctx: scala.quoted.QuoteContext) ?=> { val a: scala.quoted.Expr[scala.Int] = scala.internal.quoted.CompileTime.exprQuote[scala.Int](4).apply(using qctx) - ((qctx2: scala.quoted.QuoteContext) ?=> ((qctx1_$1: scala.quoted.QuoteContext) ?=> a).apply(using qctx2)).apply(using qctx) + ((qctx2: scala.quoted.QuoteContext) ?=> ((qctx1_$1: qctx2.NestedContext) ?=> a).asInstanceOf[scala.ContextFunction1[scala.quoted.QuoteContext, scala.quoted.Expr[scala.Int]]].apply(using qctx2)).apply(using qctx) })