diff --git a/project/ScalaOptionParser.scala b/project/ScalaOptionParser.scala index 64d9db857982..f2cc8b725e1f 100644 --- a/project/ScalaOptionParser.scala +++ b/project/ScalaOptionParser.scala @@ -84,16 +84,16 @@ object ScalaOptionParser { // TODO retrieve these data programmatically, ala https://github.com/scala/scala-tool-support/blob/master/bash-completion/src/main/scala/BashCompletion.scala private def booleanSettingNames = List("-X", "-Xasync", "-Xcheckinit", "-Xdev", "-Xdisable-assertions", "-Xexperimental", "-Xfatal-warnings", "-Xlog-free-terms", "-Xlog-free-types", "-Xlog-implicit-conversions", "-Xlog-reflective-calls", "-Xno-forwarders", "-Xno-patmat-analysis", "-Xnon-strict-patmat-analysis", "-Xprint-pos", "-Xprint-types", "-Xprompt", "-Xresident", "-Xshow-phases", "-Xverify", "-Y", - "-Ybreak-cycles", "-Ydebug", "-Ycompact-trees", "-YdisableFlatCpCaching", "-Ydoc-debug", + "-Ybreak-cycles", "-Ydebug", "-Ydebug-type-error", "-Ycompact-trees", "-YdisableFlatCpCaching", "-Ydoc-debug", "-Yide-debug", - "-Yissue-debug", "-Ylog-classpath", "-Ymacro-debug-lite", "-Ymacro-debug-verbose", "-Ymacro-no-expand", + "-Ylog-classpath", "-Ymacro-debug-lite", "-Ymacro-debug-verbose", "-Ymacro-no-expand", "-Yno-completion", "-Yno-generic-signatures", "-Yno-imports", "-Yno-predef", "-Ymacro-annotations", "-Ypatmat-debug", "-Yno-adapted-args", "-Ypos-debug", "-Ypresentation-debug", "-Ypresentation-strict", "-Ypresentation-verbose", "-Yquasiquote-debug", "-Yrangepos", "-Yreify-copypaste", "-Yreify-debug", "-Yrepl-class-based", "-Yrepl-sync", "-Yshow-member-pos", "-Yshow-symkinds", "-Yshow-symowners", "-Yshow-syms", "-Yshow-trees", "-Yshow-trees-compact", "-Yshow-trees-stringified", "-Ytyper-debug", "-Ywarn-dead-code", "-Ywarn-numeric-widen", "-Ywarn-value-discard", "-Ywarn-extra-implicit", "-Ywarn-self-implicit", "-V", - "-Vclasspath", "-Vdebug", "-Vdebug-tasty", "-Vdoc", "-Vfree-terms", "-Vfree-types", + "-Vclasspath", "-Vdebug", "-Vdebug-tasty", "-Vdebug-type-error", "-Vdoc", "-Vfree-terms", "-Vfree-types", "-Vhot-statistics", "-Vide", "-Vimplicit-conversions", "-Vimplicits", "-Vissue", "-Vmacro", "-Vmacro-lite", "-Vpatmat", "-Vphases", "-Vpos", "-Vprint-pos", "-Vprint-types", "-Vquasiquote", "-Vreflective-calls", "-Vreify", diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala index 82bf5d02b37b..e69a0eb99f26 100644 --- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala @@ -487,10 +487,11 @@ trait ScalaSettings extends StandardScalaSettings with Warnings { _: MutableSett val Vhelp = BooleanSetting("-V", "Print a synopsis of verbose options.") val browse = PhasesSetting("-Vbrowse", "Browse the abstract syntax tree after") withAbbreviation "-Ybrowse" val debug = BooleanSetting("-Vdebug", "Increase the quantity of debugging output.") withAbbreviation "-Ydebug" withPostSetHook (s => if (s.value) StatisticsStatics.enableDebugAndDeoptimize()) - val YdebugTasty = BooleanSetting("-Vdebug-tasty", "Increase the quantity of debugging output when unpickling tasty.") withAbbreviation "-Ydebug-tasty" - val Ydocdebug = BooleanSetting("-Vdoc", "Trace scaladoc activity.") withAbbreviation "-Ydoc-debug" + val YdebugTasty = BooleanSetting("-Vdebug-tasty", "Increase the quantity of debugging output when unpickling tasty.") withAbbreviation "-Ydebug-tasty" + val VdebugTypeError = BooleanSetting("-Vdebug-type-error", "Print the stack trace when any error is caught.") withAbbreviation "-Ydebug-type-error" + val Ydocdebug = BooleanSetting("-Vdoc", "Trace scaladoc activity.") withAbbreviation "-Ydoc-debug" val Yidedebug = BooleanSetting("-Vide", "Generate, validate and output trees using the interactive compiler.") withAbbreviation "-Yide-debug" - val Yissuedebug = BooleanSetting("-Vissue", "Print stack traces when a context issues an error.") withAbbreviation "-Yissue-debug" +// val Yissuedebug = BooleanSetting("-Vissue", "Print stack traces when a context issues an error.") withAbbreviation "-Yissue-debug" val log = PhasesSetting("-Vlog", "Log operations during") withAbbreviation "-Ylog" val Ylogcp = BooleanSetting("-Vclasspath", "Output information about what classpath is being applied.") withAbbreviation "-Ylog-classpath" val YmacrodebugLite = BooleanSetting("-Vmacro-lite", "Trace macro activities with less output.") withAbbreviation "-Ymacro-debug-lite" diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index 5c7e3128b8ed..4d28468e74bb 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -808,7 +808,7 @@ trait Contexts { self: Analyzer => /** Issue/buffer/throw the given implicit ambiguity error according to the current mode for error reporting. */ private[typechecker] def issueAmbiguousError(err: AbsAmbiguousTypeError) = reporter.issueAmbiguousError(err)(this) /** Issue/throw the given error message according to the current mode for error reporting. */ - def error(pos: Position, msg: String) = reporter.error(fixPosition(pos), msg) + def error(pos: Position, msg: String) = reporter.errorAndDumpIfDebug(fixPosition(pos), msg) /** Issue/throw the given error message according to the current mode for error reporting. */ def warning(pos: Position, msg: String, category: WarningCategory) = reporter.warning(fixPosition(pos), msg, category, owner) def warning(pos: Position, msg: String, category: WarningCategory, site: Symbol) = reporter.warning(fixPosition(pos), msg, category, site) @@ -1643,7 +1643,7 @@ trait Contexts { self: Analyzer => type Error = AbsTypeError type Warning = (Position, String, WarningCategory, Symbol) - def issue(err: AbsTypeError)(implicit context: Context): Unit = error(context.fixPosition(err.errPos), addDiagString(err.errMsg)) + def issue(err: AbsTypeError)(implicit context: Context): Unit = errorAndDumpIfDebug(context.fixPosition(err.errPos), addDiagString(err.errMsg)) def echo(msg: String): Unit = echo(NoPosition, msg) @@ -1655,6 +1655,13 @@ trait Contexts { self: Analyzer => def error(pos: Position, msg: String): Unit + final def errorAndDumpIfDebug(pos: Position, msg: String): Unit = { + error(pos, msg) + if (settings.VdebugTypeError.value) { + Thread.dumpStack() + } + } + protected def handleSuppressedAmbiguous(err: AbsAmbiguousTypeError): Unit = () def makeImmediate: ContextReporter = this @@ -1686,7 +1693,7 @@ trait Contexts { self: Analyzer => if (target.isBuffering) { target ++= errors } else { - errors.foreach(e => target.error(e.errPos, e.errMsg)) + errors.foreach(e => target.errorAndDumpIfDebug(e.errPos, e.errMsg)) } // TODO: is clearAllErrors necessary? (no tests failed when dropping it) // NOTE: even though `this ne target`, it may still be that `target.errorBuffer eq _errorBuffer`, diff --git a/test/files/run/debug-type-error.check b/test/files/run/debug-type-error.check new file mode 100644 index 000000000000..a201aa6756b1 --- /dev/null +++ b/test/files/run/debug-type-error.check @@ -0,0 +1,5 @@ +newSource1.scala:3: error: object dummy is not a member of package org + val a: org.dummy.Dummy = ??? + ^ +java.lang.Exception: Stack trace +java.lang.Exception: Stack trace diff --git a/test/files/run/debug-type-error.scala b/test/files/run/debug-type-error.scala new file mode 100644 index 000000000000..4a3e007a9d7d --- /dev/null +++ b/test/files/run/debug-type-error.scala @@ -0,0 +1,25 @@ +// filter: (\s*)at(.*) + +import scala.tools.partest._ + +object Test extends DirectTest { + override def extraSettings: String = "-usejavacp -Vdebug-type-error" + + def code: String = "" + + def noSuchType: String = """ +object Example +{ + val a: org.dummy.Dummy = ??? +} + """ + + def show(): Unit = { + val global = newCompiler() + + def run(code: String): Unit = + compileString(global)(code.trim) + + run(noSuchType) + } +}