Skip to content

Commit

Permalink
Merge pull request scala#869 from dotty-staging/fix-#866
Browse files Browse the repository at this point in the history
  • Loading branch information
odersky committed Oct 27, 2015
2 parents 51ab200 + 065a002 commit c1facd5
Show file tree
Hide file tree
Showing 14 changed files with 51 additions and 31 deletions.
4 changes: 2 additions & 2 deletions src/dotty/tools/dotc/Driver.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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

Expand Down
2 changes: 1 addition & 1 deletion src/dotty/tools/dotc/Resident.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion src/dotty/tools/dotc/Run.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
2 changes: 1 addition & 1 deletion src/dotty/tools/dotc/ast/Trees.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand Down
4 changes: 2 additions & 2 deletions src/dotty/tools/dotc/core/TyperState.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down
7 changes: 5 additions & 2 deletions src/dotty/tools/dotc/reporting/ConsoleReporter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -51,6 +52,8 @@ class ConsoleReporter(
case _ =>
printMessageAndPos(d.msg, d.pos)
}
issue
}

def displayPrompt(): Unit = {
writer.print("\na)bort, s)tack, r)esume: ")
Expand Down
32 changes: 18 additions & 14 deletions src/dotty/tools/dotc/reporting/Reporter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,6 @@ trait Reporting { this: Context =>
throw ex
}
}

def errorsReported: Boolean = outersIterator exists (_.reporter.hasErrors)
}

/**
Expand All @@ -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
Expand Down Expand Up @@ -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)
Expand Down
7 changes: 5 additions & 2 deletions src/dotty/tools/dotc/reporting/StoreReporter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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 && {
Expand All @@ -33,4 +34,6 @@ class StoreReporter extends Reporter {
infos foreach ctx.reporter.report
infos = null
}

override def errorsReported = hasErrors || outer.errorsReported
}
2 changes: 1 addition & 1 deletion src/dotty/tools/dotc/reporting/ThrowingReporter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
2 changes: 1 addition & 1 deletion src/dotty/tools/dotc/transform/TreeChecker.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion src/dotty/tools/dotc/typer/Applications.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down
2 changes: 1 addition & 1 deletion src/dotty/tools/dotc/typer/Implicits.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down
5 changes: 3 additions & 2 deletions test/dotc/tests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
9 changes: 9 additions & 0 deletions tests/neg/i866.scala
Original file line number Diff line number Diff line change
@@ -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
}

0 comments on commit c1facd5

Please sign in to comment.