Skip to content

Commit 649cda8

Browse files
committed
Handle non fatal exceptions in splicer as compilation errors
1 parent 4910a43 commit 649cda8

File tree

3 files changed

+29
-9
lines changed

3 files changed

+29
-9
lines changed

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

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import dotty.tools.dotc.core.Decorators._
77
import dotty.tools.dotc.core.quoted._
88
import dotty.tools.dotc.interpreter._
99

10+
import scala.util.control.NonFatal
11+
1012
import java.lang.reflect.InvocationTargetException
1113

1214
/** Utility class to splice quoted expressions */
@@ -25,17 +27,21 @@ object Splicer {
2527
/** Splice the Tree for a Quoted expression which is constructed via a reflective call to the given method */
2628
private def reflectiveSplice(tree: Tree)(implicit ctx: Context): Tree = {
2729
val interpreter = new Interpreter
28-
try {
29-
interpreter.interpretTree[scala.quoted.Expr[_]](tree).map(PickledQuotes.quotedExprToTree).getOrElse(tree)
30-
} catch {
31-
case ex: InvocationTargetException => tryRecoverFromTargetException(tree, ex)
32-
}
30+
val interpreted =
31+
try interpreter.interpretTree[scala.quoted.Expr[_]](tree)
32+
catch { case ex: InvocationTargetException => handleTargetException(tree, ex); None }
33+
interpreted.fold(tree)(PickledQuotes.quotedExprToTree)
3334
}
3435

35-
private def tryRecoverFromTargetException(tree: Tree, ex: InvocationTargetException)(implicit ctx: Context): Tree = ex.getCause match {
36-
case ex: scala.quoted.QuoteError =>
37-
ctx.error(ex.getMessage, tree.pos)
38-
EmptyTree
36+
private def handleTargetException(tree: Tree, ex: InvocationTargetException)(implicit ctx: Context): Unit = ex.getCause match {
37+
case ex: scala.quoted.QuoteError => ctx.error(ex.getMessage, tree.pos)
38+
case NonFatal(ex) =>
39+
val msg =
40+
s"""Failed to evaluate inlined quote.
41+
| Caused by: ${ex.getMessage}
42+
| ${ex.getStackTrace.takeWhile(_.getClassName != "sun.reflect.NativeMethodAccessorImpl").mkString("\n ")}
43+
""".stripMargin
44+
ctx.error(msg, tree.pos)
3945
case _ => throw ex
4046
}
4147

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 ???
8+
}
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: Failed to evaluate inlined quote. Caused by: an implementation is missing
6+
}

0 commit comments

Comments
 (0)