diff --git a/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala b/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala index 91e18cb2791e..7a57b67d7f6a 100644 --- a/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala +++ b/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala @@ -53,7 +53,7 @@ trait QuotesAndSplices { ctx.error(em"Quotes require stable QuoteContext, but found non stable $qctx", qctx.sourcePos) val tree1 = - if ctx.mode.is(Mode.Pattern) && level == 0 then + if ctx.mode.is(Mode.Pattern) then typedQuotePattern(tree, pt, qctx) else if (tree.quoted.isType) typedTypeApply(untpd.TypeApply(untpd.ref(defn.InternalQuoted_typeQuote.termRef), tree.quoted :: Nil), pt)(using quoteContext) @@ -72,7 +72,7 @@ trait QuotesAndSplices { ctx.warning("Canceled quote directly inside a splice. ${ '{ XYZ } } is equivalent to XYZ.", tree.sourcePos) case _ => } - if (ctx.mode.is(Mode.QuotedPattern) && level == 1) + if (ctx.mode.is(Mode.QuotedPattern)) if (isFullyDefined(pt, ForceDegree.all)) { def spliceOwner(ctx: Context): Symbol = if (ctx.mode.is(Mode.QuotedPattern)) spliceOwner(ctx.outer) else ctx.owner @@ -99,24 +99,10 @@ trait QuotesAndSplices { 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 `${ ... }` - // * 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) - val internalSplice = outerQctx match - case Some(qctxRef) => untpd.Apply(untpd.Apply(untpd.ref(defn.InternalQuoted_exprNestedSplice.termRef), qctxRef), expr) - case _ => untpd.Apply(untpd.ref(defn.InternalQuoted_exprSplice.termRef), expr) + case Some(qctxRef) => untpd.Apply(untpd.Apply(untpd.ref(defn.InternalQuoted_exprNestedSplice.termRef), qctxRef), tree.expr) + case _ => untpd.Apply(untpd.ref(defn.InternalQuoted_exprSplice.termRef), tree.expr) typedApply(internalSplice, pt)(using ctx1).withSpan(tree.span) } diff --git a/tests/pos/splice-with-explicit-context.scala b/tests/pos/splice-with-explicit-context.scala new file mode 100644 index 000000000000..511b1ac7c422 --- /dev/null +++ b/tests/pos/splice-with-explicit-context.scala @@ -0,0 +1,7 @@ +import scala.quoted._ + +def f(a: Expr[Int])(using qctx: QuoteContext): Unit = + + '{ val x: Int = ${ (using qctx2) => a } } + + '{ val x: Int = ${ (using qctx2: qctx.NestedContext) => a } } diff --git a/tests/run-staging/quote-nested-2.check b/tests/run-staging/quote-nested-2.check index 18f09dc182ee..b64f13e441af 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: qctx.NestedContext) ?=> a).asInstanceOf[scala.ContextFunction1[scala.quoted.QuoteContext, scala.quoted.Expr[scala.Int]]].apply(using qctx) + ((evidence$2: 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 0296b75b63af..cafa92a05d1b 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: qctx2.NestedContext) ?=> a).asInstanceOf[scala.ContextFunction1[scala.quoted.QuoteContext, scala.quoted.Expr[scala.Int]]].apply(using qctx2)).apply(using qctx) + ((qctx2: scala.quoted.QuoteContext) ?=> ((evidence$3: qctx2.NestedContext) ?=> a).asInstanceOf[scala.ContextFunction1[scala.quoted.QuoteContext, scala.quoted.Expr[scala.Int]]].apply(using qctx2)).apply(using qctx) })