Skip to content

Commit

Permalink
Make error reporting resilient to exception thrown while reporting (s…
Browse files Browse the repository at this point in the history
…cala#20158)

Previously the added test failed with `1 error reported` but no actual
error message printed, because a stack overflow is thrown while
reporting the original error. This is then caught and handled to emit a
RecursionOverflow error, but that second error is non-sensical and
non-sensical errors are only printed if `hasErrors` returns false.

We fix this by deferring incrementing the error count (and therefore
having `hasErrors` return true) until after having displayed the error.
We also defer calling `markReported` otherwise the second error will
also be suppressed. A similar change is necessary in our testing
infrastructure to keep the error count is coherent.
  • Loading branch information
odersky authored Apr 11, 2024
2 parents 881c6c4 + e7a1f7b commit dfff8f6
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 2 deletions.
8 changes: 7 additions & 1 deletion compiler/src/dotty/tools/dotc/reporting/Reporter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import java.io.{BufferedReader, PrintWriter}
import scala.annotation.internal.sharable
import scala.collection.mutable
import core.Decorators.em
import core.handleRecursive

object Reporter {
/** Convert a SimpleReporter into a real Reporter */
Expand Down Expand Up @@ -155,6 +156,12 @@ abstract class Reporter extends interfaces.ReporterResult {
addUnreported(key, 1)
case _ =>
if !isHidden(dia) then // avoid isHidden test for summarized warnings so that message is not forced
try
withMode(Mode.Printing)(doReport(dia))
catch case ex: Throwable =>
// #20158: Don't increment the error count, otherwise we might suppress
// the RecursiveOverflow error and not print any error at all.
handleRecursive("error reporting", dia.message, ex)
dia match {
case w: Warning =>
warnings = w :: warnings
Expand All @@ -168,7 +175,6 @@ abstract class Reporter extends interfaces.ReporterResult {
// match error if d is something else
}
markReported(dia)
withMode(Mode.Printing)(doReport(dia))
end issueUnconfigured

def issueIfNotSuppressed(dia: Diagnostic)(using Context): Unit =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ extends Reporter with UniqueMessagePositions with HideNonSensicalMessages with M
}

if dia.level >= WARNING then
_diagnosticBuf.append(dia)
_consoleReporter.doReport(dia)
_diagnosticBuf.append(dia)
printMessageAndPos(dia, extra)
}
}
Expand Down
16 changes: 16 additions & 0 deletions tests/neg/mt-deskolemize.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
trait Expr:
type Value
object Expr:
type Of[V] = Expr { type Value = V }
type ExtractValue[F <: Expr] = F match
case Expr.Of[v] => v
import Expr.ExtractValue

class SimpleLoop1 extends Expr:
type Value = ExtractValue[SimpleLoop2]

class SimpleLoop2 extends Expr:
type Value = ExtractValue[SimpleLoop1]

object Test1:
val x: ExtractValue[SimpleLoop1] = 1 // error

0 comments on commit dfff8f6

Please sign in to comment.