Skip to content

Commit aadd17f

Browse files
committed
Handle QuotedError when evaluating holes in quotes
These holes are exapnded while unpickling in PickledQuotes.quotedExprToTree
1 parent 80764e0 commit aadd17f

File tree

3 files changed

+34
-18
lines changed

3 files changed

+34
-18
lines changed

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

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,22 @@ object Splicer {
3636
val liftedArgs = getLiftedArgs(call, bindings)
3737
val interpreter = new Interpreter(pos, classLoader)
3838
val interpreted = interpreter.interpretCallToSymbol[Seq[Any] => Object](call.symbol)
39-
interpreted.flatMap(lambda => evaluateLambda(lambda, liftedArgs, pos)).fold(tree)(PickledQuotes.quotedExprToTree)
39+
try {
40+
val evaluated = interpreted.map(lambda => lambda(liftedArgs).asInstanceOf[scala.quoted.Expr[Nothing]])
41+
evaluated.fold(tree)(PickledQuotes.quotedExprToTree)
42+
} catch {
43+
case ex: scala.quoted.QuoteError =>
44+
ctx.error(ex.getMessage, pos)
45+
EmptyTree
46+
case NonFatal(ex) =>
47+
val msg =
48+
s"""Failed to evaluate inlined quote.
49+
| Caused by ${ex.getClass}: ${if (ex.getMessage == null) "" else ex.getMessage}
50+
| ${ex.getStackTrace.takeWhile(_.getClassName != "dotty.tools.dotc.transform.Splicer$").init.mkString("\n ")}
51+
""".stripMargin
52+
ctx.error(msg, pos)
53+
EmptyTree
54+
}
4055
}
4156

4257
/** Given the inline code and bindings, compute the lifted arguments that will be used to execute the macro
@@ -72,23 +87,6 @@ object Splicer {
7287
liftArgs(call.symbol.info, allArgs(call, Nil))
7388
}
7489

75-
private def evaluateLambda(lambda: Seq[Any] => Object, args: Seq[Any], pos: Position)(implicit ctx: Context): Option[scala.quoted.Expr[Nothing]] = {
76-
try Some(lambda(args).asInstanceOf[scala.quoted.Expr[Nothing]])
77-
catch {
78-
case ex: scala.quoted.QuoteError =>
79-
ctx.error(ex.getMessage, pos)
80-
None
81-
case NonFatal(ex) =>
82-
val msg =
83-
s"""Failed to evaluate inlined quote.
84-
| Caused by: ${ex.getMessage}
85-
| ${ex.getStackTrace.takeWhile(_.getClassName != "dotty.tools.dotc.transform.Splicer$").init.mkString("\n ")}
86-
""".stripMargin
87-
ctx.error(msg, pos)
88-
None
89-
}
90-
}
91-
9290
/** Tree interpreter that can interpret calls to static methods with it's default arguments
9391
*
9492
* The interpreter assumes that all calls in the trees are to code that was

tests/neg/quote-error-2/Macro_1.scala

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
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+
'(println(~msg(b)))
7+
8+
def msg(b: Boolean): Expr[String] =
9+
if (b) '("foo(true)")
10+
else QuoteError("foo cannot be called with false")
11+
12+
}

tests/neg/quote-error-2/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)