Skip to content

Commit 4f6eb18

Browse files
committed
Don't have Diagnostic inherit from Exception
Creating diagnostics should be cheap, whereas reportiong them can be expensive. The reason is that often diagnsotics are created nd then later discarded in normal backtracking during Typer. But the way it was set up, every diagnostic computed a stack trace, which is quite expensive.
1 parent 668084b commit 4f6eb18

File tree

4 files changed

+10
-7
lines changed

4 files changed

+10
-7
lines changed

compiler/src/dotty/tools/dotc/reporting/Diagnostic.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ class Diagnostic(
8989
val msg: Message,
9090
val pos: SourcePosition,
9191
val level: Int
92-
) extends Exception with interfaces.Diagnostic:
92+
) extends interfaces.Diagnostic:
9393
private var verbose: Boolean = false
9494
def isVerbose: Boolean = verbose
9595
def setVerbose(): this.type =
@@ -102,5 +102,4 @@ class Diagnostic(
102102
msg.message.replaceAll("\u001B\\[[;\\d]*m", "")
103103

104104
override def toString: String = s"$getClass at $pos: $message"
105-
override def getMessage(): String = message
106105
end Diagnostic

compiler/src/dotty/tools/dotc/reporting/ThrowingReporter.scala

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,16 @@ import core.Contexts._
66
import Diagnostic.Error
77

88
/**
9-
* This class implements a Reporter that throws all errors and sends warnings and other
10-
* info to the underlying reporter.
9+
* This class implements a Reporter that throws all errors as UnhandledError exceptions
10+
* and sends warnings and other info to the underlying reporter.
1111
*/
1212
class ThrowingReporter(reportInfo: Reporter) extends Reporter {
1313
def doReport(dia: Diagnostic)(using Context): Unit = dia match {
14-
case _: Error => throw dia
14+
case dia: Error => throw UnhandledError(dia)
1515
case _ => reportInfo.doReport(dia)
1616
}
1717
}
18+
19+
class UnhandledError(val diagnostic: Error) extends Exception:
20+
override def getMessage = diagnostic.message
21+

compiler/src/dotty/tools/dotc/typer/Applications.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2401,7 +2401,7 @@ trait Applications extends Compatibility {
24012401
else
24022402
None
24032403
catch
2404-
case NonFatal(_) => None
2404+
case ex: UnhandledError => None
24052405

24062406
def isApplicableExtensionMethod(methodRef: TermRef, receiverType: Type)(using Context): Boolean =
24072407
methodRef.symbol.is(ExtensionMethod) && !receiverType.isBottomType &&

tests/run-staging/i7142.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ object Test {
77
def main(args: Array[String]): Unit =
88
try run {returning('{ { (x: Int) => ${ throwReturn('x) }} apply 0 })}
99
catch {
10-
case ex: dotty.tools.dotc.reporting.Diagnostic.Error =>
10+
case ex: dotty.tools.dotc.reporting.UnhandledError =>
1111
assert(ex.getMessage == "While expanding a macro, a reference to parameter x was used outside the scope where it was defined", ex.getMessage)
1212
}
1313
}

0 commit comments

Comments
 (0)