Skip to content

Commit 1fc3916

Browse files
committed
Improve incorrect classloader reporting in staging
* do not println staging crashes to stdout * enrich the errors coming from the compiler with additional hints about using the correct classloader
1 parent 3cad257 commit 1fc3916

File tree

7 files changed

+52
-2
lines changed

7 files changed

+52
-2
lines changed

compiler/src/dotty/tools/dotc/Run.scala

+2
Original file line numberDiff line numberDiff line change
@@ -661,4 +661,6 @@ object Run {
661661
report.enrichErrorMessage(errorMessage)
662662
else
663663
errorMessage
664+
def doNotEnrichErrorMessage: Unit =
665+
if run != null then run.myEnrichedErrorMessage = true
664666
}

staging/src/scala/quoted/staging/QuoteCompiler.scala

+3-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,9 @@ private class QuoteCompiler extends Compiler:
4848

4949
override def newRun(implicit ctx: Context): ExprRun =
5050
reset()
51-
new ExprRun(this, ctx.addMode(Mode.ReadPositions))
51+
val run = new ExprRun(this, ctx.addMode(Mode.ReadPositions))
52+
run.doNotEnrichErrorMessage
53+
run
5254

5355
def outputClassName: TypeName = "Generated$Code$From$Quoted".toTypeName
5456

staging/src/scala/quoted/staging/QuoteDriver.scala

+15-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import dotty.tools.dotc.quoted.QuotesCache
88
import dotty.tools.io.{AbstractFile, Directory, PlainDirectory, VirtualDirectory}
99
import dotty.tools.repl.AbstractFileClassLoader
1010
import dotty.tools.dotc.reporting._
11+
import dotty.tools.dotc.config.Settings.Setting.value
1112
import dotty.tools.dotc.util.ClasspathFromClassloader
1213
import scala.quoted._
1314
import scala.quoted.staging.Compiler
@@ -40,7 +41,20 @@ private class QuoteDriver(appClassloader: ClassLoader) extends Driver:
4041
setCompilerSettings(ctx1.fresh.setSetting(ctx1.settings.outputDir, outDir), settings)
4142
}
4243

43-
new QuoteCompiler().newRun(ctx).compileExpr(exprBuilder) match
44+
val compiledExpr =
45+
try
46+
new QuoteCompiler().newRun(ctx).compileExpr(exprBuilder)
47+
catch case ex: dotty.tools.FatalError =>
48+
val enrichedMessage =
49+
s"""An unhandled exception was thrown in the staging compiler.
50+
|This might be caused by using an incorrect classloader
51+
|when creating the `staging.Compiler` instance with `staging.Compiler.make`.
52+
|For details, please refer to the documentation.
53+
|For non-enriched exceptions, compile with -Yno-enrich-error-messages.""".stripMargin
54+
if ctx.settings.YnoEnrichErrorMessages.value(using ctx) then throw ex
55+
else throw new Exception(enrichedMessage, ex)
56+
57+
compiledExpr match
4458
case Right(value) =>
4559
value.asInstanceOf[T]
4660

tests/run-staging/i19170c.check

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
exception thrown, no additional printlns

tests/run-staging/i19170c.scala

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import scala.quoted.*
2+
3+
given staging.Compiler =
4+
staging.Compiler.make(getClass.getClassLoader.getParent) // different classloader that 19170b.scala
5+
class A(i: Int)
6+
7+
def f(i: Expr[Int])(using Quotes): Expr[A] = { '{ new A($i) } }
8+
9+
@main def Test = {
10+
try
11+
val g: Int => A = staging.run { '{ (i: Int) => ${ f('{i}) } } }
12+
println(g(3))
13+
catch case ex: Exception =>
14+
assert(ex.getMessage().startsWith("An unhandled exception was thrown in the staging compiler."), ex.getMessage())
15+
println("exception thrown, no additional printlns")
16+
}

tests/run-staging/i19176b.check

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
exception thrown, no additional printlns

tests/run-staging/i19176b.scala

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import scala.quoted.*
2+
3+
given staging.Compiler =
4+
staging.Compiler.make(getClass.getClassLoader.getParent) // we want to make sure the classloader is incorrect
5+
6+
class A
7+
8+
@main def Test =
9+
try
10+
val f: (A, Int) => Int = staging.run { '{ (q: A, x: Int) => x } }
11+
f(new A, 3)
12+
catch case ex: Exception =>
13+
assert(ex.getMessage().startsWith("An unhandled exception was thrown in the staging compiler."), ex.getMessage())
14+
println("exception thrown, no additional printlns")

0 commit comments

Comments
 (0)