Skip to content

Commit c1facd5

Browse files
committed
Merge pull request #869 from dotty-staging/fix-#866
Fix #866
2 parents 51ab200 + 065a002 commit c1facd5

File tree

14 files changed

+51
-31
lines changed

14 files changed

+51
-31
lines changed

src/dotty/tools/dotc/Driver.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ abstract class Driver extends DotClass {
1212

1313
protected def newCompiler(): Compiler
1414

15-
protected def emptyReporter: Reporter = new StoreReporter
15+
protected def emptyReporter: Reporter = new StoreReporter(null)
1616

1717
protected def doCompile(compiler: Compiler, fileNames: List[String])(implicit ctx: Context): Reporter =
1818
if (fileNames.nonEmpty)
@@ -24,7 +24,7 @@ abstract class Driver extends DotClass {
2424
catch {
2525
case ex: FatalError =>
2626
ctx.error(ex.getMessage) // signals that we should fail compilation.
27-
ctx.typerState.reporter
27+
ctx.reporter
2828
}
2929
else emptyReporter
3030

src/dotty/tools/dotc/Resident.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class Resident extends Driver {
4747
nextCtx = rootCtx
4848
line = getLine()
4949
}
50-
if (line.startsWith(quit)) ctx.typerState.reporter
50+
if (line.startsWith(quit)) ctx.reporter
5151
else loop(line split "\\s+", nextCtx)
5252
}
5353
loop(args, rootCtx)

src/dotty/tools/dotc/Run.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ class Run(comp: Compiler)(implicit ctx: Context) {
8484
/** Print summary; return # of errors encountered */
8585
def printSummary(): Reporter = {
8686
ctx.runInfo.printMaxConstraint()
87-
val r = ctx.typerState.reporter
87+
val r = ctx.reporter
8888
r.printSummary
8989
r
9090
}

src/dotty/tools/dotc/ast/Trees.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ object Trees {
146146
* type. (Overridden by empty trees)
147147
*/
148148
def withType(tpe: Type)(implicit ctx: Context): ThisTree[Type] = {
149-
if (tpe == ErrorType) assert(ctx.errorsReported)
149+
if (tpe == ErrorType) assert(ctx.reporter.errorsReported)
150150
withTypeUnchecked(tpe)
151151
}
152152

src/dotty/tools/dotc/core/TyperState.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ extends TyperState(r) {
9898

9999

100100
override def fresh(isCommittable: Boolean): TyperState =
101-
new MutableTyperState(this, new StoreReporter, isCommittable)
101+
new MutableTyperState(this, new StoreReporter(reporter), isCommittable)
102102

103103
override def withReporter(reporter: Reporter) =
104104
new MutableTyperState(this, reporter, isCommittable)
@@ -169,7 +169,7 @@ extends TyperState(r) {
169169
* found a better solution.
170170
*/
171171
override def tryWithFallback[T](op: => T)(fallback: => T)(implicit ctx: Context): T = {
172-
val storeReporter = new StoreReporter
172+
val storeReporter = new StoreReporter(myReporter)
173173
val savedReporter = myReporter
174174
myReporter = storeReporter
175175
val savedConstraint = myConstraint

src/dotty/tools/dotc/reporting/ConsoleReporter.scala

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,9 @@ class ConsoleReporter(
4040
}
4141
}
4242

43-
override def doReport(d: Diagnostic)(implicit ctx: Context): Unit =
44-
if (!d.isSuppressed || !hasErrors) d match {
43+
override def doReport(d: Diagnostic)(implicit ctx: Context): Boolean = {
44+
val issue = !(d.isSuppressed && hasErrors)
45+
if (issue) d match {
4546
case d: Error =>
4647
printMessageAndPos(s"error: ${d.msg}", d.pos)
4748
if (ctx.settings.prompt.value) displayPrompt()
@@ -51,6 +52,8 @@ class ConsoleReporter(
5152
case _ =>
5253
printMessageAndPos(d.msg, d.pos)
5354
}
55+
issue
56+
}
5457

5558
def displayPrompt(): Unit = {
5659
writer.print("\na)bort, s)tack, r)esume: ")

src/dotty/tools/dotc/reporting/Reporter.scala

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -173,8 +173,6 @@ trait Reporting { this: Context =>
173173
throw ex
174174
}
175175
}
176-
177-
def errorsReported: Boolean = outersIterator exists (_.reporter.hasErrors)
178176
}
179177

180178
/**
@@ -183,8 +181,10 @@ trait Reporting { this: Context =>
183181
*/
184182
abstract class Reporter {
185183

186-
/** Report a diagnostic */
187-
def doReport(d: Diagnostic)(implicit ctx: Context): Unit
184+
/** Report a diagnostic, unless it is suppressed because it is nonsensical
185+
* @return a diagnostic was reported.
186+
*/
187+
def doReport(d: Diagnostic)(implicit ctx: Context): Boolean
188188

189189
/** Whether very long lines can be truncated. This exists so important
190190
* debugging information (like printing the classpath) is not rendered
@@ -213,20 +213,24 @@ abstract class Reporter {
213213
def hasErrors = errorCount > 0
214214
def hasWarnings = warningCount > 0
215215

216+
/** Have errors been reported by this reporter, or in the
217+
* case where this is a StoreReporter, by an outer reporter?
218+
*/
219+
def errorsReported = hasErrors
220+
216221
val unreportedWarnings = new mutable.HashMap[String, Int] {
217222
override def default(key: String) = 0
218223
}
219224

220-
def report(d: Diagnostic)(implicit ctx: Context): Unit = if (!isHidden(d)) {
221-
doReport(d)(ctx.addMode(Mode.Printing))
222-
d match {
223-
case d: ConditionalWarning if !d.enablingOption.value => unreportedWarnings(d.enablingOption.name) += 1
224-
case d: Warning => warningCount += 1
225-
case d: Error => errorCount += 1
226-
case d: Info => // nothing to do here
227-
// match error if d is something else
228-
}
229-
}
225+
def report(d: Diagnostic)(implicit ctx: Context): Unit =
226+
if (!isHidden(d) && doReport(d)(ctx.addMode(Mode.Printing)))
227+
d match {
228+
case d: ConditionalWarning if !d.enablingOption.value => unreportedWarnings(d.enablingOption.name) += 1
229+
case d: Warning => warningCount += 1
230+
case d: Error => errorCount += 1
231+
case d: Info => // nothing to do here
232+
// match error if d is something else
233+
}
230234

231235
def incomplete(d: Diagnostic)(implicit ctx: Context): Unit =
232236
incompleteHandler(d)(ctx)

src/dotty/tools/dotc/reporting/StoreReporter.scala

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,15 @@ import config.Printers._
1010
/**
1111
* This class implements a Reporter that stores all messages
1212
*/
13-
class StoreReporter extends Reporter {
13+
class StoreReporter(outer: Reporter) extends Reporter {
1414

1515
private var infos: mutable.ListBuffer[Diagnostic] = null
1616

17-
def doReport(d: Diagnostic)(implicit ctx: Context): Unit = {
17+
def doReport(d: Diagnostic)(implicit ctx: Context): Boolean = {
1818
typr.println(s">>>> StoredError: ${d.msg}") // !!! DEBUG
1919
if (infos == null) infos = new mutable.ListBuffer
2020
infos += d
21+
true
2122
}
2223

2324
override def hasPending: Boolean = infos != null && {
@@ -33,4 +34,6 @@ class StoreReporter extends Reporter {
3334
infos foreach ctx.reporter.report
3435
infos = null
3536
}
37+
38+
override def errorsReported = hasErrors || outer.errorsReported
3639
}

src/dotty/tools/dotc/reporting/ThrowingReporter.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import Reporter._
1111
* info to the underlying reporter.
1212
*/
1313
class ThrowingReporter(reportInfo: Reporter) extends Reporter {
14-
def doReport(d: Diagnostic)(implicit ctx: Context): Unit = d match {
14+
def doReport(d: Diagnostic)(implicit ctx: Context): Boolean = d match {
1515
case _: Error => throw d
1616
case _ => reportInfo.doReport(d)
1717
}

src/dotty/tools/dotc/transform/TreeChecker.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ class TreeChecker extends Phase with SymTransformer {
118118
val squahsedPhase = ctx.squashed(prevPhase)
119119
ctx.println(s"checking ${ctx.compilationUnit} after phase ${squahsedPhase}")
120120
val checkingCtx = ctx.fresh
121-
.setTyperState(ctx.typerState.withReporter(new ThrowingReporter(ctx.typerState.reporter)))
121+
.setTyperState(ctx.typerState.withReporter(new ThrowingReporter(ctx.reporter)))
122122
val checker = new Checker(previousPhases(phasesToRun.toList)(ctx))
123123
try checker.typedExpr(ctx.compilationUnit.tpdTree)(checkingCtx)
124124
catch {

src/dotty/tools/dotc/typer/Applications.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ trait Applications extends Compatibility { self: Typer =>
153153

154154
def ok = _ok
155155
def ok_=(x: Boolean) = {
156-
assert(x || ctx.errorsReported || !ctx.typerState.isCommittable) // !!! DEBUG
156+
assert(x || ctx.reporter.errorsReported || !ctx.typerState.isCommittable) // !!! DEBUG
157157
_ok = x
158158
}
159159

src/dotty/tools/dotc/typer/Implicits.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,7 @@ trait Implicits { self: Typer =>
495495
case _ => false
496496
}
497497
}
498-
if (ctx.typerState.reporter.hasErrors)
498+
if (ctx.reporter.hasErrors)
499499
nonMatchingImplicit(ref)
500500
else if (contextual && !ctx.mode.is(Mode.ImplicitShadowing) &&
501501
!shadowing.tpe.isError && !refMatches(shadowing)) {

test/dotc/tests.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,8 @@ class tests extends CompilerTest {
109109
@Test def neg_privates() = compileFile(negDir, "privates", xerrors = 2)
110110
@Test def neg_rootImports = compileFile(negDir, "rootImplicits", xerrors = 2)
111111
@Test def neg_templateParents() = compileFile(negDir, "templateParents", xerrors = 3)
112-
@Test def neg_autoTupling = compileFile(posDir, "autoTuplingTest", args = "-language:noAutoTupling" :: Nil, xerrors = 4)
113-
@Test def neg_autoTupling2 = compileFile(negDir, "autoTuplingTest", xerrors = 4)
112+
@Test def neg_autoTupling = compileFile(posDir, "autoTuplingTest", args = "-language:noAutoTupling" :: Nil, xerrors = 3)
113+
@Test def neg_autoTupling2 = compileFile(negDir, "autoTuplingTest", xerrors = 3)
114114
@Test def neg_companions = compileFile(negDir, "companions", xerrors = 1)
115115
@Test def neg_over = compileFile(negDir, "over", xerrors = 3)
116116
@Test def neg_overrides = compileFile(negDir, "overrides", xerrors = 11)
@@ -145,6 +145,7 @@ class tests extends CompilerTest {
145145
@Test def neg_i583 = compileFile(negDir, "i0583-skolemize", xerrors = 2)
146146
@Test def neg_finalSealed = compileFile(negDir, "final-sealed", xerrors = 2)
147147
@Test def neg_i705 = compileFile(negDir, "i705-inner-value-class", xerrors = 7)
148+
@Test def neg_i866 = compileFile(negDir, "i866", xerrors = 2)
148149
@Test def neg_moduleSubtyping = compileFile(negDir, "moduleSubtyping", xerrors = 4)
149150
@Test def neg_escapingRefs = compileFile(negDir, "escapingRefs", xerrors = 2)
150151
@Test def neg_instantiateAbstract = compileFile(negDir, "instantiateAbstract", xerrors = 8)

tests/neg/i866.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
object Test {
2+
def x: Int = "" // error
3+
}
4+
import nonexistent._ // error; this one will swallow all errors below.
5+
object Foo {
6+
def bar(implicit x: NonExistent) = ???
7+
val baz = bar
8+
}
9+

0 commit comments

Comments
 (0)