From d4f30d1a268a51ee74c98f6ae0f45136274536af Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Mon, 26 Oct 2015 09:41:25 +0100 Subject: Keep separate chain of outer reporters for StoreReporters Used in rewritten `errorsReported` method. This fixes #866. The problem before was that `TyperState#trywithFallBack` temporarily updates the reporter, so crawling up the context chain to check for reporters with errors missed some reported errors, which triggered the assertion in `Tree#withType`. --- src/dotty/tools/dotc/Driver.scala | 2 +- src/dotty/tools/dotc/ast/Trees.scala | 2 +- src/dotty/tools/dotc/core/TyperState.scala | 4 ++-- src/dotty/tools/dotc/reporting/Reporter.scala | 7 +++++-- src/dotty/tools/dotc/reporting/StoreReporter.scala | 4 +++- 5 files changed, 12 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/dotty/tools/dotc/Driver.scala b/src/dotty/tools/dotc/Driver.scala index 92a2ed1a2..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) 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/Reporter.scala b/src/dotty/tools/dotc/reporting/Reporter.scala index 086575fb4..7c9d1fa79 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) } /** @@ -213,6 +211,11 @@ 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 } diff --git a/src/dotty/tools/dotc/reporting/StoreReporter.scala b/src/dotty/tools/dotc/reporting/StoreReporter.scala index 51d3df110..1991790b5 100644 --- a/src/dotty/tools/dotc/reporting/StoreReporter.scala +++ b/src/dotty/tools/dotc/reporting/StoreReporter.scala @@ -10,7 +10,7 @@ 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 @@ -33,4 +33,6 @@ class StoreReporter extends Reporter { infos foreach ctx.reporter.report infos = null } + + override def errorsReported = hasErrors || outer.errorsReported } -- cgit v1.2.3