Skip to content

Commit 073c7aa

Browse files
Merge pull request #6983 from dotty-staging/fix-#6976
Fix #6976: Improve macro exception stack handling
2 parents 10e3990 + b59fa73 commit 073c7aa

File tree

4 files changed

+40
-8
lines changed

4 files changed

+40
-8
lines changed

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

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ object Splicer {
282282

283283
val name = getDirectName(fn.info.finalResultType, fn.name.asTermName)
284284
val method = getMethod(clazz, name, paramsSig(fn))
285-
(args: List[Object]) => stopIfRuntimeException(method.invoke(inst, args: _*))
285+
(args: List[Object]) => stopIfRuntimeException(method.invoke(inst, args: _*), method)
286286
}
287287

288288
private def interpretModuleAccess(fn: Symbol)(implicit env: Env): Object =
@@ -339,7 +339,7 @@ object Splicer {
339339

340340
private def extraMsg = ". The most common reason for that is that you apply macros in the compilation run that defines them"
341341

342-
private def stopIfRuntimeException[T](thunk: => T): T = {
342+
private def stopIfRuntimeException[T](thunk: => T, method: Method): T = {
343343
try thunk
344344
catch {
345345
case ex: RuntimeException =>
@@ -352,13 +352,16 @@ object Splicer {
352352
throw new StopInterpretation(sw.toString, pos)
353353
case ex: InvocationTargetException =>
354354
val sw = new StringWriter()
355-
sw.write("An exception occurred while executing macro expansion: ")
356-
sw.write(ex.getTargetException.getMessage)
357-
sw.write("\n")
358-
for (stack <- ex.getTargetException.getStackTrace.iterator.takeWhile(_.getClassName != this.getClass.getName).drop(1)) {
359-
sw.write(stack.toString)
360-
sw.write("\n")
355+
sw.write("Exception occurred while executing macro expansion.\n")
356+
val targetException = ex.getTargetException
357+
if (!ctx.settings.Ydebug.value) {
358+
val end = targetException.getStackTrace.lastIndexWhere { x =>
359+
x.getClassName == method.getDeclaringClass.getCanonicalName && x.getMethodName == method.getName
360+
}
361+
val shortStackTrace = targetException.getStackTrace.take(end + 1)
362+
targetException.setStackTrace(shortStackTrace)
361363
}
364+
targetException.printStackTrace(new PrintWriter(sw))
362365
sw.write("\n")
363366
throw new StopInterpretation(sw.toString, pos)
364367
}

tests/neg-macros/i6976.check

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
2+
-- Error: tests/neg-macros/i6976/Test_2.scala:5:44 ---------------------------------------------------------------------
3+
5 | def main(args: Array[String]): Unit = mcr { 2 } // error
4+
| ^^^^^^^^^
5+
| Exception occurred while executing macro expansion.
6+
| scala.MatchError: Inlined(EmptyTree,List(),Literal(Constant(2))) (of class dotty.tools.dotc.ast.Trees$Inlined)
7+
| at playground.macros$.mcrImpl(Macro_1.scala:12)
8+
|
9+
| This location is in code that was inlined at Test_2.scala:5

tests/neg-macros/i6976/Macro_1.scala

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package playground
2+
3+
import scala.quoted._, scala.quoted.matching._
4+
import delegate scala.quoted._
5+
import scala.tasty._
6+
7+
object macros {
8+
inline def mcr(x: => Any) = ${mcrImpl('x)}
9+
10+
def mcrImpl(body: Expr[Any]) given (ctx: QuoteContext): Expr[Any] = {
11+
import ctx.tasty._
12+
body.unseal match { case Block(_, _) => '{2} }
13+
}
14+
}

tests/neg-macros/i6976/Test_2.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
import playground.macros._
3+
4+
object Test {
5+
def main(args: Array[String]): Unit = mcr { 2 } // error
6+
}

0 commit comments

Comments
 (0)