diff options
-rw-r--r-- | src/dotty/tools/dotc/Driver.scala | 4 | ||||
-rw-r--r-- | src/dotty/tools/dotc/Resident.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/Run.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/ast/Trees.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/TyperState.scala | 4 | ||||
-rw-r--r-- | src/dotty/tools/dotc/reporting/ConsoleReporter.scala | 7 | ||||
-rw-r--r-- | src/dotty/tools/dotc/reporting/Reporter.scala | 32 | ||||
-rw-r--r-- | src/dotty/tools/dotc/reporting/StoreReporter.scala | 7 | ||||
-rw-r--r-- | src/dotty/tools/dotc/reporting/ThrowingReporter.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/TreeChecker.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Applications.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Implicits.scala | 2 | ||||
-rw-r--r-- | test/dotc/tests.scala | 5 | ||||
-rw-r--r-- | tests/neg/i866.scala | 9 |
14 files changed, 51 insertions, 31 deletions
diff --git a/src/dotty/tools/dotc/Driver.scala b/src/dotty/tools/dotc/Driver.scala index 7e9d4a5e4..24effb59d 100644 --- a/src/dotty/tools/dotc/Driver.scala +++ b/src/dotty/tools/dotc/Driver.scala @@ -12,7 +12,7 @@ abstract class Driver extends DotClass { protected def newCompiler(): Compiler - protected def emptyReporter: Reporter = new StoreReporter + protected def emptyReporter: Reporter = new StoreReporter(null) protected def doCompile(compiler: Compiler, fileNames: List[String])(implicit ctx: Context): Reporter = if (fileNames.nonEmpty) @@ -24,7 +24,7 @@ abstract class Driver extends DotClass { catch { case ex: FatalError => ctx.error(ex.getMessage) // signals that we should fail compilation. - ctx.typerState.reporter + ctx.reporter } else emptyReporter diff --git a/src/dotty/tools/dotc/Resident.scala b/src/dotty/tools/dotc/Resident.scala index 9578e7d2c..3ae369f27 100644 --- a/src/dotty/tools/dotc/Resident.scala +++ b/src/dotty/tools/dotc/Resident.scala @@ -47,7 +47,7 @@ class Resident extends Driver { nextCtx = rootCtx line = getLine() } - if (line.startsWith(quit)) ctx.typerState.reporter + if (line.startsWith(quit)) ctx.reporter else loop(line split "\\s+", nextCtx) } loop(args, rootCtx) diff --git a/src/dotty/tools/dotc/Run.scala b/src/dotty/tools/dotc/Run.scala index 553805d95..114f994be 100644 --- a/src/dotty/tools/dotc/Run.scala +++ b/src/dotty/tools/dotc/Run.scala @@ -84,7 +84,7 @@ class Run(comp: Compiler)(implicit ctx: Context) { /** Print summary; return # of errors encountered */ def printSummary(): Reporter = { ctx.runInfo.printMaxConstraint() - val r = ctx.typerState.reporter + val r = ctx.reporter r.printSummary r } diff --git a/src/dotty/tools/dotc/ast/Trees.scala b/src/dotty/tools/dotc/ast/Trees.scala index a10dfaa16..54ace3be4 100644 --- a/src/dotty/tools/dotc/ast/Trees.scala +++ b/src/dotty/tools/dotc/ast/Trees.scala @@ -146,7 +146,7 @@ object Trees { * type. (Overridden by empty trees) */ def withType(tpe: Type)(implicit ctx: Context): ThisTree[Type] = { - if (tpe == ErrorType) assert(ctx.errorsReported) + if (tpe == ErrorType) assert(ctx.reporter.errorsReported) withTypeUnchecked(tpe) } diff --git a/src/dotty/tools/dotc/core/TyperState.scala b/src/dotty/tools/dotc/core/TyperState.scala index 5617f568a..36f026107 100644 --- a/src/dotty/tools/dotc/core/TyperState.scala +++ b/src/dotty/tools/dotc/core/TyperState.scala @@ -98,7 +98,7 @@ extends TyperState(r) { override def fresh(isCommittable: Boolean): TyperState = - new MutableTyperState(this, new StoreReporter, isCommittable) + new MutableTyperState(this, new StoreReporter(reporter), isCommittable) override def withReporter(reporter: Reporter) = new MutableTyperState(this, reporter, isCommittable) @@ -169,7 +169,7 @@ extends TyperState(r) { * found a better solution. */ override def tryWithFallback[T](op: => T)(fallback: => T)(implicit ctx: Context): T = { - val storeReporter = new StoreReporter + val storeReporter = new StoreReporter(myReporter) val savedReporter = myReporter myReporter = storeReporter val savedConstraint = myConstraint diff --git a/src/dotty/tools/dotc/reporting/ConsoleReporter.scala b/src/dotty/tools/dotc/reporting/ConsoleReporter.scala index 26e6324eb..3e2aaa880 100644 --- a/src/dotty/tools/dotc/reporting/ConsoleReporter.scala +++ b/src/dotty/tools/dotc/reporting/ConsoleReporter.scala @@ -40,8 +40,9 @@ class ConsoleReporter( } } - override def doReport(d: Diagnostic)(implicit ctx: Context): Unit = - if (!d.isSuppressed || !hasErrors) d match { + override def doReport(d: Diagnostic)(implicit ctx: Context): Boolean = { + val issue = !(d.isSuppressed && hasErrors) + if (issue) d match { case d: Error => printMessageAndPos(s"error: ${d.msg}", d.pos) if (ctx.settings.prompt.value) displayPrompt() @@ -51,6 +52,8 @@ class ConsoleReporter( case _ => printMessageAndPos(d.msg, d.pos) } + issue + } def displayPrompt(): Unit = { writer.print("\na)bort, s)tack, r)esume: ") diff --git a/src/dotty/tools/dotc/reporting/Reporter.scala b/src/dotty/tools/dotc/reporting/Reporter.scala index 086575fb4..0358f71f6 100644 --- a/src/dotty/tools/dotc/reporting/Reporter.scala +++ b/src/dotty/tools/dotc/reporting/Reporter.scala @@ -173,8 +173,6 @@ trait Reporting { this: Context => throw ex } } - - def errorsReported: Boolean = outersIterator exists (_.reporter.hasErrors) } /** @@ -183,8 +181,10 @@ trait Reporting { this: Context => */ abstract class Reporter { - /** Report a diagnostic */ - def doReport(d: Diagnostic)(implicit ctx: Context): Unit + /** Report a diagnostic, unless it is suppressed because it is nonsensical + * @return a diagnostic was reported. + */ + def doReport(d: Diagnostic)(implicit ctx: Context): Boolean /** Whether very long lines can be truncated. This exists so important * debugging information (like printing the classpath) is not rendered @@ -213,20 +213,24 @@ abstract class Reporter { def hasErrors = errorCount > 0 def hasWarnings = warningCount > 0 + /** Have errors been reported by this reporter, or in the + * case where this is a StoreReporter, by an outer reporter? + */ + def errorsReported = hasErrors + val unreportedWarnings = new mutable.HashMap[String, Int] { override def default(key: String) = 0 } - def report(d: Diagnostic)(implicit ctx: Context): Unit = if (!isHidden(d)) { - doReport(d)(ctx.addMode(Mode.Printing)) - d match { - case d: ConditionalWarning if !d.enablingOption.value => unreportedWarnings(d.enablingOption.name) += 1 - case d: Warning => warningCount += 1 - case d: Error => errorCount += 1 - case d: Info => // nothing to do here - // match error if d is something else - } - } + def report(d: Diagnostic)(implicit ctx: Context): Unit = + if (!isHidden(d) && doReport(d)(ctx.addMode(Mode.Printing))) + d match { + case d: ConditionalWarning if !d.enablingOption.value => unreportedWarnings(d.enablingOption.name) += 1 + case d: Warning => warningCount += 1 + case d: Error => errorCount += 1 + case d: Info => // nothing to do here + // match error if d is something else + } def incomplete(d: Diagnostic)(implicit ctx: Context): Unit = incompleteHandler(d)(ctx) diff --git a/src/dotty/tools/dotc/reporting/StoreReporter.scala b/src/dotty/tools/dotc/reporting/StoreReporter.scala index 51d3df110..8209839eb 100644 --- a/src/dotty/tools/dotc/reporting/StoreReporter.scala +++ b/src/dotty/tools/dotc/reporting/StoreReporter.scala @@ -10,14 +10,15 @@ import config.Printers._ /** * This class implements a Reporter that stores all messages */ -class StoreReporter extends Reporter { +class StoreReporter(outer: Reporter) extends Reporter { private var infos: mutable.ListBuffer[Diagnostic] = null - def doReport(d: Diagnostic)(implicit ctx: Context): Unit = { + def doReport(d: Diagnostic)(implicit ctx: Context): Boolean = { typr.println(s">>>> StoredError: ${d.msg}") // !!! DEBUG if (infos == null) infos = new mutable.ListBuffer infos += d + true } override def hasPending: Boolean = infos != null && { @@ -33,4 +34,6 @@ class StoreReporter extends Reporter { infos foreach ctx.reporter.report infos = null } + + override def errorsReported = hasErrors || outer.errorsReported } diff --git a/src/dotty/tools/dotc/reporting/ThrowingReporter.scala b/src/dotty/tools/dotc/reporting/ThrowingReporter.scala index 026453036..7c63383e9 100644 --- a/src/dotty/tools/dotc/reporting/ThrowingReporter.scala +++ b/src/dotty/tools/dotc/reporting/ThrowingReporter.scala @@ -11,7 +11,7 @@ import Reporter._ * info to the underlying reporter. */ class ThrowingReporter(reportInfo: Reporter) extends Reporter { - def doReport(d: Diagnostic)(implicit ctx: Context): Unit = d match { + def doReport(d: Diagnostic)(implicit ctx: Context): Boolean = d match { case _: Error => throw d case _ => reportInfo.doReport(d) } diff --git a/src/dotty/tools/dotc/transform/TreeChecker.scala b/src/dotty/tools/dotc/transform/TreeChecker.scala index 2296ae658..1f47b4486 100644 --- a/src/dotty/tools/dotc/transform/TreeChecker.scala +++ b/src/dotty/tools/dotc/transform/TreeChecker.scala @@ -118,7 +118,7 @@ class TreeChecker extends Phase with SymTransformer { val squahsedPhase = ctx.squashed(prevPhase) ctx.println(s"checking ${ctx.compilationUnit} after phase ${squahsedPhase}") val checkingCtx = ctx.fresh - .setTyperState(ctx.typerState.withReporter(new ThrowingReporter(ctx.typerState.reporter))) + .setTyperState(ctx.typerState.withReporter(new ThrowingReporter(ctx.reporter))) val checker = new Checker(previousPhases(phasesToRun.toList)(ctx)) try checker.typedExpr(ctx.compilationUnit.tpdTree)(checkingCtx) catch { diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala index 87ad0831c..0fee17bcd 100644 --- a/src/dotty/tools/dotc/typer/Applications.scala +++ b/src/dotty/tools/dotc/typer/Applications.scala @@ -153,7 +153,7 @@ trait Applications extends Compatibility { self: Typer => def ok = _ok def ok_=(x: Boolean) = { - assert(x || ctx.errorsReported || !ctx.typerState.isCommittable) // !!! DEBUG + assert(x || ctx.reporter.errorsReported || !ctx.typerState.isCommittable) // !!! DEBUG _ok = x } diff --git a/src/dotty/tools/dotc/typer/Implicits.scala b/src/dotty/tools/dotc/typer/Implicits.scala index 5444dddb0..e3626fe20 100644 --- a/src/dotty/tools/dotc/typer/Implicits.scala +++ b/src/dotty/tools/dotc/typer/Implicits.scala @@ -495,7 +495,7 @@ trait Implicits { self: Typer => case _ => false } } - if (ctx.typerState.reporter.hasErrors) + if (ctx.reporter.hasErrors) nonMatchingImplicit(ref) else if (contextual && !ctx.mode.is(Mode.ImplicitShadowing) && !shadowing.tpe.isError && !refMatches(shadowing)) { diff --git a/test/dotc/tests.scala b/test/dotc/tests.scala index 337285c04..7c62000b4 100644 --- a/test/dotc/tests.scala +++ b/test/dotc/tests.scala @@ -109,8 +109,8 @@ class tests extends CompilerTest { @Test def neg_privates() = compileFile(negDir, "privates", xerrors = 2) @Test def neg_rootImports = compileFile(negDir, "rootImplicits", xerrors = 2) @Test def neg_templateParents() = compileFile(negDir, "templateParents", xerrors = 3) - @Test def neg_autoTupling = compileFile(posDir, "autoTuplingTest", args = "-language:noAutoTupling" :: Nil, xerrors = 4) - @Test def neg_autoTupling2 = compileFile(negDir, "autoTuplingTest", xerrors = 4) + @Test def neg_autoTupling = compileFile(posDir, "autoTuplingTest", args = "-language:noAutoTupling" :: Nil, xerrors = 3) + @Test def neg_autoTupling2 = compileFile(negDir, "autoTuplingTest", xerrors = 3) @Test def neg_companions = compileFile(negDir, "companions", xerrors = 1) @Test def neg_over = compileFile(negDir, "over", xerrors = 3) @Test def neg_overrides = compileFile(negDir, "overrides", xerrors = 11) @@ -145,6 +145,7 @@ class tests extends CompilerTest { @Test def neg_i583 = compileFile(negDir, "i0583-skolemize", xerrors = 2) @Test def neg_finalSealed = compileFile(negDir, "final-sealed", xerrors = 2) @Test def neg_i705 = compileFile(negDir, "i705-inner-value-class", xerrors = 7) + @Test def neg_i866 = compileFile(negDir, "i866", xerrors = 2) @Test def neg_moduleSubtyping = compileFile(negDir, "moduleSubtyping", xerrors = 4) @Test def neg_escapingRefs = compileFile(negDir, "escapingRefs", xerrors = 2) @Test def neg_instantiateAbstract = compileFile(negDir, "instantiateAbstract", xerrors = 8) diff --git a/tests/neg/i866.scala b/tests/neg/i866.scala new file mode 100644 index 000000000..2cdc99ede --- /dev/null +++ b/tests/neg/i866.scala @@ -0,0 +1,9 @@ +object Test { + def x: Int = "" // error +} +import nonexistent._ // error; this one will swallow all errors below. +object Foo { + def bar(implicit x: NonExistent) = ??? + val baz = bar +} + |