diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 674052959cdf..40e4cc82f4e5 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -1933,18 +1933,27 @@ class Typer extends Namer * while tracking the quotation level in the context. */ def typedQuote(tree: untpd.Quote, pt: Type)(implicit ctx: Context): Tree = track("typedQuote") { - val tree1 = - if (tree.t.isType) - typedTypeApply(untpd.TypeApply(untpd.ref(defn.InternalQuoted_typeQuoteR), List(tree.t)), pt)(quoteContext) - else - typedApply(untpd.Apply(untpd.ref(defn.InternalQuoted_exprQuoteR), tree.t), pt)(quoteContext) - tree1.withSpan(tree.span) + tree.t match { + case untpd.Splice(innerExpr) => + ctx.warning("Canceled splice directly inside a quote. '{ ${ XYZ } } is equivalent to XYZ.", tree.sourcePos) + typed(innerExpr, pt) + case t if t.isType => + typedTypeApply(untpd.TypeApply(untpd.ref(defn.InternalQuoted_typeQuoteR), List(tree.t)), pt)(quoteContext).withSpan(tree.span) + case t=> + typedApply(untpd.Apply(untpd.ref(defn.InternalQuoted_exprQuoteR), tree.t), pt)(quoteContext).withSpan(tree.span) + } } /** Translate `${ t: Expr[T] }` into expresiion `t.splice` while tracking the quotation level in the context */ def typedSplice(tree: untpd.Splice, pt: Type)(implicit ctx: Context): Tree = track("typedSplice") { checkSpliceOutsideQuote(tree) - typedSelect(untpd.Select(tree.expr, nme.splice), pt)(spliceContext).withSpan(tree.span) + tree.expr match { + case untpd.Quote(innerExpr) => + ctx.warning("Canceled quote directly inside a splice. ${ '{ XYZ } } is equivalent to XYZ.", tree.sourcePos) + typed(innerExpr, pt) + case expr => + typedSelect(untpd.Select(expr, nme.splice), pt)(spliceContext).withSpan(tree.span) + } } /** Translate ${ t: Type[T] }` into type `t.splice` while tracking the quotation level in the context */ diff --git a/tests/neg-custom-args/fatal-warnings/quote-simple-hole.scala b/tests/neg-custom-args/fatal-warnings/quote-simple-hole.scala new file mode 100644 index 000000000000..da11aa9325c1 --- /dev/null +++ b/tests/neg-custom-args/fatal-warnings/quote-simple-hole.scala @@ -0,0 +1,13 @@ +class Test { + val x = '{0} + val y = '{ // error: Canceled splice directly inside a quote. '{ ${ XYZ } } is equivalent to XYZ. + $x + } + val z = '{ + val a = ${ // error: Canceled quote directly inside a splice. ${ '{ XYZ } } is equivalent to XYZ. + '{ + $y + } + } + } +} diff --git a/tests/run-with-compiler/quote-nested-2.check b/tests/run-with-compiler/quote-nested-2.check index f4fa770eb373..87a43aeeee24 100644 --- a/tests/run-with-compiler/quote-nested-2.check +++ b/tests/run-with-compiler/quote-nested-2.check @@ -1,4 +1,5 @@ { val a: scala.quoted.Expr[scala.Int] = '{4} - a + + (a: scala.quoted.Expr[scala.Int]) } diff --git a/tests/run-with-compiler/quote-nested-5.check b/tests/run-with-compiler/quote-nested-5.check index f4fa770eb373..87a43aeeee24 100644 --- a/tests/run-with-compiler/quote-nested-5.check +++ b/tests/run-with-compiler/quote-nested-5.check @@ -1,4 +1,5 @@ { val a: scala.quoted.Expr[scala.Int] = '{4} - a + + (a: scala.quoted.Expr[scala.Int]) }