Skip to content

Commit 0628792

Browse files
committed
Add error reporter for inlined quotes
1 parent 4a3e33d commit 0628792

File tree

5 files changed

+38
-2
lines changed

5 files changed

+38
-2
lines changed

compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ class ReifyQuotes extends MacroTransformWithImplicits {
336336
}
337337

338338
val tree1 =
339-
if (level == 0) cpy.Inlined(tree)(call, stagedBindings, Splicer.splice(seq(splicedBindings, body)))
339+
if (level == 0) cpy.Inlined(tree)(call, stagedBindings, Splicer.splice(seq(splicedBindings, body).withPos(tree.pos)))
340340
else seq(stagedBindings, cpy.Select(expansion)(cpy.Inlined(tree)(call, splicedBindings, body), name))
341341
val tree2 = transform(tree1)
342342

compiler/src/dotty/tools/dotc/transform/Splicer.scala

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ import dotty.tools.dotc.ast.tpd
55
import dotty.tools.dotc.core.Contexts._
66
import dotty.tools.dotc.core.quoted._
77
import dotty.tools.dotc.interpreter._
8+
import dotty.tools.dotc.core.Decorators._
9+
10+
import java.lang.reflect.InvocationTargetException
811

912
/** Utility class to splice quoted expressions */
1013
object Splicer {
@@ -22,7 +25,18 @@ object Splicer {
2225
/** Splice the Tree for a Quoted expression which is constructed via a reflective call to the given method */
2326
private def reflectiveSplice(tree: Tree)(implicit ctx: Context): Tree = {
2427
val interpreter = new Interpreter
25-
interpreter.interpretTree[scala.quoted.Expr[_]](tree).map(PickledQuotes.quotedExprToTree).getOrElse(tree)
28+
try {
29+
interpreter.interpretTree[scala.quoted.Expr[_]](tree).map(PickledQuotes.quotedExprToTree).getOrElse(tree)
30+
} catch {
31+
case ex: InvocationTargetException => tryRecoverFromTargetException(tree, ex)
32+
}
33+
}
34+
35+
private def tryRecoverFromTargetException(tree: Tree, ex: InvocationTargetException)(implicit ctx: Context): Tree = ex.getCause match {
36+
case ex: scala.quoted.InlineQuote.QuoteError =>
37+
ctx.error(ex.getMessage, tree.pos)
38+
EmptyTree
39+
case _ => throw ex
2640
}
2741

2842
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package scala.quoted
2+
3+
object InlineQuote {
4+
/** Throwing this error in the implementation of an inline macro
5+
* will result in a compilation error with the given message.
6+
*/
7+
class QuoteError(message: String) extends Throwable(message)
8+
}

tests/neg/quote-error/Macro_1.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import quoted._
2+
3+
object Macro_1 {
4+
inline def foo(inline b: Boolean): Unit = ~fooImpl(b)
5+
def fooImpl(b: Boolean): Expr[Unit] =
6+
if (b) '(println("foo(true)"))
7+
else throw new InlineQuote.QuoteError("foo cannot be called with false")
8+
}

tests/neg/quote-error/Test_2.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import Macro_1._
2+
3+
object Test_2 {
4+
foo(true)
5+
foo(false) // error: foo cannot be called with false
6+
}

0 commit comments

Comments
 (0)