Skip to content
16 changes: 7 additions & 9 deletions compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -662,15 +662,13 @@ trait BCodeHelpers(val backendUtils: BackendUtils)(using ctx: Context) extends B
import scala.tools.asm.util.CheckClassAdapter
def wrap(body: => Unit): Unit = {
try body
catch {
case ex: Throwable =>
report.error(
em"""|compiler bug: created invalid generic signature for $sym in ${sym.denot.owner.showFullName}
|signature: $sig
|if this is reproducible, please report bug at https://github.com/scala/scala3/issues
""", sym.sourcePos)
throw ex
}
catch case ex: Exception =>
report.error(
em"""|compiler bug: created invalid generic signature for $sym in ${sym.denot.owner.showFullName}
|signature: $sig
|if this is reproducible, please report bug at https://github.com/scala/scala3/issues
""", sym.sourcePos)
throw ex
}

wrap {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ class ClassfileWriters(frontendAccess: PostProcessorFrontendAccess)(using ctx: C
catch {
case ex: ClosedByInterruptException =>
try Files.deleteIfExists(path) // don't leave a empty of half-written classfile around after an interrupt
catch { case _: Throwable => () }
catch { case _: java.io.IOException => () }
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for the IO-related ones I followed the Javadoc, and in one case removed a catch because it was calling one of our own util methods that already catches and ignores internally

throw ex
}
os.close()
Expand Down
5 changes: 1 addition & 4 deletions compiler/src/dotty/tools/backend/jvm/CodeGen.scala
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,7 @@ class CodeGen(val backendUtils: BackendUtils, val primitives: ScalaPrimitives, v
registerGeneratedClass(mainClassNode, isArtifact = false)
registerGeneratedClass(mirrorClassNode, isArtifact = true)
catch
case ex: InterruptedException => throw ex
case ex: CompilationUnit.SuspendException => throw ex
case ex: Throwable =>
if !ex.isInstanceOf[TypeError] then ex.printStackTrace()
case ex: TypeError =>
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

given that we were willing to print a stack trace for non-typeerrors, I think letting it bubble up to "compiler bug" is better

Copy link
Copy Markdown
Contributor Author

@SolalPirelli SolalPirelli Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: double check that if something bad happens in the backend we get the usual compiler "plz file a bug" message (says Seb)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup, we do

report.error(s"Error while emitting ${unit.source}\n${ex.getMessage}", cd.sourcePos)


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,8 @@ import dotty.tools.dotc.core.Contexts.*
import dotty.tools.io.AbstractFile
import dotty.tools.dotc.profile.ThreadPoolFactory

import scala.util.control.NonFatal
import dotty.tools.dotc.core.Phases
import dotty.tools.dotc.core.Decorators.em
import dotty.tools.dotc.core.Types.IdentityTypeMap.mapCtx
import dotty.tools.dotc.report

import scala.compiletime.uninitialized
Expand Down Expand Up @@ -155,10 +153,10 @@ private[jvm] object GeneratedClassHandler {
unitInPostProcess.task.value.get.get
catch
case _: ClosedByInterruptException => throw new InterruptedException()
case NonFatal(t) =>
t.printStackTrace()
case e: Exception =>
e.printStackTrace()
given Context = ctx
report.error(em"unable to write ${unitInPostProcess.sourceFile} $t")
report.error(em"unable to write ${unitInPostProcess.sourceFile} $e")
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import scala.tools.asm.{ClassReader, Type, Handle }
import scala.tools.asm.tree.*

import scala.collection.mutable
import scala.util.control.{NoStackTrace, NonFatal}
import scala.util.control.NoStackTrace
import scala.annotation.*
import scala.jdk.CollectionConverters.*
import BTypes.InternalName
Expand Down Expand Up @@ -47,7 +47,7 @@ abstract class GenericSignatureVisitor(nestedOnly: Boolean) {

@inline def safely(f: => Unit): Unit = try f catch {
case Aborted =>
case NonFatal(e) => raiseError(s"Exception thrown during signature parsing", sig, Some(e))
case e: Exception => raiseError(s"Exception thrown during signature parsing", sig, Some(e))
}

private def current = {
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/backend/jvm/PostProcessor.scala
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class PostProcessor(val frontendAccess: PostProcessorFrontendAccess,
case e: java.lang.RuntimeException if e.getMessage != null && e.getMessage.contains("too large!") =>
report.error(em"Could not write class $internalName because it exceeds JVM code size limits. ${e.getMessage}")
null
case ex: Throwable =>
case ex: Exception =>
if frontendAccess.compilerSettings.debug then ex.printStackTrace()
report.error(em"Error while emitting $internalName\n${ex.getMessage}")
null
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package dotty.tools.debug

import java.nio.file.Path
import scala.util.control.NonFatal
import dotty.tools.dotc.core.Contexts.Context
import dotty.tools.dotc.Driver

Expand Down Expand Up @@ -29,6 +28,6 @@ class ExpressionCompilerBridge:
driver.process(args, reporter)
!reporter.hasErrors
catch
case NonFatal(cause) =>
case cause: Exception =>
cause.printStackTrace()
throw cause
9 changes: 2 additions & 7 deletions compiler/src/dotty/tools/dotc/Driver.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import reporting.*
import core.Decorators.*
import util.chaining.*

import scala.util.control.NonFatal
import fromtasty.{TASTYCompiler, TastyFileUtil}

/** Run the Dotty compiler.
Expand Down Expand Up @@ -39,13 +38,13 @@ class Driver {
catch
case ex: FatalError =>
report.error(ex.getMessage) // signals that we should fail compilation.
case ex: Throwable if ctx.usedBestEffortTasty =>
case ex: Exception if ctx.usedBestEffortTasty =>
report.bestEffortError(ex, "Some best-effort tasty files were not able to be read.")
throw ex
case ex: TypeError if !runOrNull.enrichedErrorMessage =>
println(runOrNull.enrichErrorMessage(s"${ex.toMessage} while compiling ${files.map(_.path).mkString(", ")}"))
throw ex
case ex: Throwable if !runOrNull.enrichedErrorMessage =>
case ex: Exception if !runOrNull.enrichedErrorMessage =>
println(runOrNull.enrichErrorMessage(s"Exception while compiling ${files.map(_.path).mkString(", ")}"))
throw ex
ctx.reporter
Expand Down Expand Up @@ -215,10 +214,6 @@ class Driver {
}

def main(args: Array[String]): Unit = {
// Preload scala.util.control.NonFatal. Otherwise, when trying to catch a StackOverflowError,
// we may try to load it but fail with another StackOverflowError and lose the original exception,
// see <https://groups.google.com/forum/#!topic/scala-user/kte6nak-zPM>.
val _ = NonFatal
sys.exit(if (process(args).hasErrors) 1 else 0)
}
}
3 changes: 1 addition & 2 deletions compiler/src/dotty/tools/dotc/Run.scala
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import java.io.{BufferedWriter, OutputStreamWriter}
import java.nio.charset.StandardCharsets

import scala.collection.mutable, mutable.ListBuffer
import scala.util.control.NonFatal
import scala.io.Codec

import Run.Progress
Expand Down Expand Up @@ -323,7 +322,7 @@ extends ImplicitRunInfo, ConstraintRunInfo, cc.CaptureRunInfo {

def compile(files: List[AbstractFile]): Unit =
try compileSources(files.map(runContext.getSource(_)))
catch case NonFatal(ex) if !this.enrichedErrorMessage =>
catch case ex: Exception if !this.enrichedErrorMessage =>
val files1 = if units.isEmpty then files else units.map(_.source.file)
report.echo(this.enrichErrorMessage(s"exception occurred while compiling ${files1.map(_.path)}"))
throw ex
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import PlainFile.toPlainFile

import scala.jdk.CollectionConverters.*
import scala.collection.immutable.ArraySeq
import scala.util.control.NonFatal

/**
* A trait allowing to look for classpath entries in directories. It provides common logic for
Expand Down Expand Up @@ -134,7 +133,7 @@ object JrtClassPath {
val ctSym = Paths.get(Properties.javaHome).resolve("lib").resolve("ct.sym")
if (Files.notExists(ctSym)) None
else Some(new CtSymClassPath(ctSym, v.toInt))
catch case NonFatal(_) => None
catch case _: Exception => None
case _ =>
try Some(new JrtClassPath(FileSystems.getFileSystem(URI.create("jrt:/"))))
catch case _: ProviderNotFoundException | _: FileSystemNotFoundException => None
Expand Down
3 changes: 1 addition & 2 deletions compiler/src/dotty/tools/dotc/core/Decorators.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ package core

import scala.annotation.tailrec
import scala.collection.mutable.ListBuffer
import scala.util.control.NonFatal

import Contexts.*, Names.*, Phases.*, Symbols.*
import printing.{ Printer, Showable }, printing.Formatting.*, printing.Texts.*
Expand Down Expand Up @@ -286,7 +285,7 @@ object Decorators {
try x.show
catch
case ex: CyclicReference => "... (caught cyclic reference) ..."
case NonFatal(ex)
case ex: Exception
if !ctx.settings.YshowPrintErrors.value =>
s"... (cannot display due to ${ex.className} ${ex.getMessage}) ..."
case _ => String.valueOf(x)
Expand Down
5 changes: 2 additions & 3 deletions compiler/src/dotty/tools/dotc/core/Phases.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import cc.CheckCaptures
import typer.ImportInfo.withRootImports
import ast.{tpd, untpd}
import scala.annotation.internal.sharable
import scala.util.control.NonFatal
import scala.compiletime.uninitialized

object Phases {
Expand Down Expand Up @@ -413,7 +412,7 @@ object Phases {
catch
case _: CompilationUnit.SuspendException => // this unit will be run again in `Run#compileSuspendedUnits`
unitCtx.typerState.resetTo(previousTyperState)
case ex: Throwable if !ctx.run.enrichedErrorMessage =>
case ex: Exception if !ctx.run.enrichedErrorMessage =>
println(ctx.run.enrichErrorMessage(s"unhandled exception while running $phaseName on $unit"))
throw ex
finally ctx.run.advanceUnit()
Expand Down Expand Up @@ -537,7 +536,7 @@ object Phases {
ctx.run.enterUnit(ctx.compilationUnit)
&& {
try {body; true}
catch case NonFatal(ex) if !ctx.run.enrichedErrorMessage =>
catch case ex: Exception if !ctx.run.enrichedErrorMessage =>
report.echo(ctx.run.enrichErrorMessage(s"exception occurred while $doing ${ctx.compilationUnit}"))
throw ex
finally ctx.run.advanceUnit()
Expand Down
8 changes: 3 additions & 5 deletions compiler/src/dotty/tools/dotc/core/SymDenotations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import annotation.tailrec
import util.SimpleIdentityMap
import util.Stats
import java.util.WeakHashMap
import scala.util.control.NonFatal
import config.Config
import reporting.*
import collection.mutable
Expand Down Expand Up @@ -2388,7 +2387,7 @@ object SymDenotations {
}
}
catch {
case ex: Throwable =>
case ex: Exception =>
tp match
case tp: CachedType => btrCache.remove(tp)
case _ =>
Expand Down Expand Up @@ -2429,8 +2428,7 @@ object SymDenotations {
names
}
catch {
case ex: Throwable =>
handleRecursive("member names", i"of $this", ex)
case ex: Throwable => handleRecursive("member names", i"of $this", ex)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed the formatting for the handleRecursives where it was easy to do so they're easier to look at in search results, since I'll deal with those in the next step

}
}

Expand Down Expand Up @@ -2618,7 +2616,7 @@ object SymDenotations {
// since the older file might have been loaded from a jar earlier in the
// classpath.
def sameContainer(f: AbstractFile): Boolean =
try f.container == chosen.container catch case NonFatal(ex) => true
try f.container == chosen.container catch case ex: Exception => true
if !ambiguityWarningIssued then
for conflicting <- assocFiles.find(!sameContainer(_)) do
report.warning(em"""${ambiguousFilesMsg(conflicting)}
Expand Down
8 changes: 2 additions & 6 deletions compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ package core
import java.io.{IOException, File}
import java.nio.channels.ClosedByInterruptException

import scala.util.control.NonFatal

import dotty.tools.dotc.classpath.{ ClassPathFactory, PackageNameUtils }
import dotty.tools.dotc.classpath.FileUtils.{hasTastyExtension, hasBetastyExtension}
import dotty.tools.io.{ ClassPath, ClassRepresentation, AbstractFile, NoAbstractFile }
Expand Down Expand Up @@ -437,16 +435,14 @@ abstract class SymbolLoader extends LazyType { self =>
report.informTime("loaded " + description, start)
}
catch {
case ex: InterruptedException =>
throw ex
case ex: ClosedByInterruptException =>
throw new InterruptedException
case ex: IOException =>
signalError(ex)
case NonFatal(ex: TypeError) =>
case ex: TypeError =>
println(s"exception caught when loading $root: ${ex.toMessage}")
throw ex
case NonFatal(ex) =>
case ex: Exception =>
println(s"exception caught when loading $root: $ex")
throw ex
}
Expand Down
20 changes: 11 additions & 9 deletions compiler/src/dotty/tools/dotc/core/TypeApplications.scala
Original file line number Diff line number Diff line change
Expand Up @@ -393,15 +393,17 @@ class TypeApplications(val self: Type) extends AnyVal {
case _ => false
}
}
if ((dealiased eq stripped) || followAlias)
try
val instantiated = dealiased.instantiate(args)
if (followAlias) instantiated.normalized else instantiated
catch
case ex: IndexOutOfBoundsException =>
AppliedType(self, args)
case ex: Throwable =>
handleRecursive("try to instantiate", i"$dealiased[$args%, %]", ex)
if (dealiased eq stripped) || followAlias then
val paramsWithoutArg = dealiased.typeParams.drop(args.length).map(_.paramRef)
val hasParamsWithoutArg = paramsWithoutArg.nonEmpty && dealiased.resType.existsPart(paramsWithoutArg.contains, forceLazy = false)
if hasParamsWithoutArg then
AppliedType(self, args)
else
try
val instantiated = dealiased.instantiate(args)
if (followAlias) instantiated.normalized else instantiated
catch
case ex: Throwable => handleRecursive("try to instantiate", i"$dealiased[$args%, %]", ex)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is the only non-mechanical change, I had to add a specific guard for what the catch case IndexOutOfBoundsException was trying to prevent


else AppliedType(self, args)
}
Expand Down
21 changes: 13 additions & 8 deletions compiler/src/dotty/tools/dotc/core/TypeComparer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import TypeErasure.{erasedLub, erasedGlb}
import TypeApplications.*
import Variances.{Variance, variancesConform}
import Constants.Constant
import scala.util.control.NonFatal
import typer.ProtoTypes.constrained
import typer.Applications.productSelectorTypes
import reporting.trace
Expand Down Expand Up @@ -1637,12 +1636,18 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
needsGc = false
if (Stats.monitored) recordStatistics(result, savedSuccessCount)
result
catch case NonFatal(ex) =>
if ex.isInstanceOf[AssertionError] then showGoal(tp1, tp2)
recCount -= 1
restore()
successCount = savedSuccessCount
throw ex
catch
case ex: AssertionError =>
showGoal(tp1, tp2)
recCount -= 1
restore()
successCount = savedSuccessCount
throw ex
case ex: Exception =>
recCount -= 1
restore()
successCount = savedSuccessCount
throw ex
}

/** Undo all actions in undoLog following prevSize */
Expand Down Expand Up @@ -2988,7 +2993,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
explainPoly(tp1)
explainPoly(tp2)
}
catch case NonFatal(ex) =>
catch case ex: Exception =>
report.echo(s"assertion failure [[cannot display since $ex was thrown]]")

/** Record statistics about the total number of subtype checks
Expand Down
3 changes: 1 addition & 2 deletions compiler/src/dotty/tools/dotc/core/TypeErasure.scala
Original file line number Diff line number Diff line change
Expand Up @@ -933,8 +933,7 @@ class TypeErasure(sourceLanguage: SourceLanguage, semiEraseVCs: Boolean, isConst
try erasureFn(sourceLanguage, semiEraseVCs = false, isConstructor, isSymbol, inSigName)(elemtp) match
case _: WildcardType => WildcardType
case elem => JavaArrayType(elem)
catch case ex: Throwable =>
handleRecursive("erase array type", tp.show, ex)
catch case ex: Throwable => handleRecursive("erase array type", tp.show, ex)
}

private def erasePair(tp: Type)(using Context): Type = {
Expand Down
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/core/TypeErrors.scala
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ abstract class TypeError(using creationContext: Context) extends Exception(""):

/** Uses creationContext to produce the message */
override def getMessage: String =
try toMessage.message catch case ex: Throwable => "TypeError"
try toMessage.message catch case _: Exception => "TypeError"

object TypeError:
def apply(msg: Message)(using Context) = new TypeError:
Expand Down Expand Up @@ -131,7 +131,7 @@ end RecursionOverflow
// Beware: Since this object is only used when handling a StackOverflow, this code
// cannot consume significant amounts of stack.
object handleRecursive:
inline def underlyingStackOverflowOrNull(exc: Throwable): Throwable | Null =
private inline def underlyingStackOverflowOrNull(exc: Throwable): Throwable | Null =
var e: Throwable | Null = exc
while e != null && !e.isInstanceOf[StackOverflowError] do e = e.getCause
e
Expand Down
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/core/TypeEval.scala
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ object TypeEval:
def runConstantOp[T](op: => T)(using Constant.ValueToConstant[T]): Type =
val result =
try op
catch case e: Throwable =>
throw TypeError(em"${e.getMessage}")
catch case ex: Exception =>
throw TypeError(em"${ex.getMessage}")
ConstantType(Constant.fromValue(result))

def fieldsOf: Option[Type] =
Expand Down
Loading
Loading