Skip to content

Commit e23f815

Browse files
authored
Merge pull request #13911 from dwijnand/fix-leaky-tryImplicits
2 parents f836589 + e5201a0 commit e23f815

File tree

5 files changed

+46
-37
lines changed

5 files changed

+46
-37
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ class TyperState() {
103103
this
104104

105105
/** A fresh typer state with the same constraint as this one. */
106-
def fresh(reporter: Reporter = StoreReporter(this.reporter),
106+
def fresh(reporter: Reporter = StoreReporter(this.reporter, fromTyperState = true),
107107
committable: Boolean = this.isCommittable): TyperState =
108108
util.Stats.record("TyperState.fresh")
109109
TyperState().init(this, this.constraint)

compiler/src/dotty/tools/dotc/reporting/ExploringReporter.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import core.Contexts.Context
77
import Diagnostic._
88

99
/** A re-usable Reporter used in Contexts#test */
10-
class ExploringReporter extends StoreReporter(null):
10+
class ExploringReporter extends StoreReporter(null, fromTyperState = false):
1111
infos = new mutable.ListBuffer[Diagnostic]
1212

1313
override def hasUnreportedErrors: Boolean =

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

Lines changed: 35 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -137,42 +137,44 @@ abstract class Reporter extends interfaces.ReporterResult {
137137

138138
var unreportedWarnings: Map[String, Int] = Map.empty
139139

140+
/** Issue the diagnostic, ignoring `-Wconf` and `@nowarn` configurations,
141+
* but still honouring `-nowarn`, `-Werror`, and conditional warnings. */
142+
def issueUnconfigured(dia: Diagnostic)(using Context): Unit = dia match
143+
case w: Warning if ctx.settings.silentWarnings.value =>
144+
case w: ConditionalWarning if w.isSummarizedConditional =>
145+
val key = w.enablingOption.name
146+
val count = unreportedWarnings.getOrElse(key, 0)
147+
unreportedWarnings = unreportedWarnings.updated(key, count + 1)
148+
case _ =>
149+
// conditional warnings that are not enabled are not fatal
150+
val d = dia match
151+
case w: Warning if ctx.settings.XfatalWarnings.value => w.toError
152+
case _ => dia
153+
if !isHidden(d) then // avoid isHidden test for summarized warnings so that message is not forced
154+
withMode(Mode.Printing)(doReport(d))
155+
d match {
156+
case _: Warning => _warningCount += 1
157+
case e: Error =>
158+
errors = e :: errors
159+
_errorCount += 1
160+
if ctx.typerState.isGlobalCommittable then
161+
ctx.base.errorsToBeReported = true
162+
case _: Info => // nothing to do here
163+
// match error if d is something else
164+
}
165+
end issueUnconfigured
166+
140167
def issueIfNotSuppressed(dia: Diagnostic)(using Context): Unit =
141168
def go() =
142169
import Action._
143-
144-
val toReport = dia match
145-
case w: Warning =>
146-
def fatal(w: Warning) = if ctx.settings.XfatalWarnings.value && !w.isSummarizedConditional then Some(w.toError) else Some(w)
147-
if ctx.settings.silentWarnings.value then None
148-
else WConf.parsed.action(dia) match
149-
case Silent => None
150-
case Info => Some(w.toInfo)
151-
case Warning => fatal(w)
152-
case Verbose => fatal(w).tap(_.foreach(_.setVerbose()))
153-
case Error => Some(w.toError)
154-
case _ => Some(dia)
155-
156-
toReport foreach {
157-
case cw: ConditionalWarning if cw.isSummarizedConditional =>
158-
val key = cw.enablingOption.name
159-
unreportedWarnings =
160-
unreportedWarnings.updated(key, unreportedWarnings.getOrElse(key, 0) + 1)
161-
case d if !isHidden(d) =>
162-
withMode(Mode.Printing)(doReport(d))
163-
d match {
164-
case _: Warning => _warningCount += 1
165-
case e: Error =>
166-
errors = e :: errors
167-
_errorCount += 1
168-
if ctx.typerState.isGlobalCommittable then
169-
ctx.base.errorsToBeReported = true
170-
case _: Info => // nothing to do here
171-
// match error if d is something else
172-
}
173-
case _ => // hidden
174-
}
175-
end go
170+
dia match
171+
case w: Warning => WConf.parsed.action(w) match
172+
case Error => issueUnconfigured(w.toError)
173+
case Warning => issueUnconfigured(w)
174+
case Verbose => issueUnconfigured(w.setVerbose())
175+
case Info => issueUnconfigured(w.toInfo)
176+
case Silent =>
177+
case _ => issueUnconfigured(dia)
176178

177179
// `ctx.run` can be null in test, also in the repl when parsing the first line. The parser runs early, the Run is
178180
// only created in ReplDriver.compile when a line is submitted. This means that `@nowarn` doesnt work on parser

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import Diagnostic._
1717
* - The reporter is not flushed and the message containers capture a
1818
* `Context` (about 4MB)
1919
*/
20-
class StoreReporter(outer: Reporter = Reporter.NoReporter) extends Reporter {
20+
class StoreReporter(outer: Reporter = Reporter.NoReporter, fromTyperState: Boolean = false) extends Reporter {
2121

2222
protected var infos: mutable.ListBuffer[Diagnostic] = null
2323

@@ -40,4 +40,11 @@ class StoreReporter(outer: Reporter = Reporter.NoReporter) extends Reporter {
4040
override def pendingMessages(using Context): List[Diagnostic] = if (infos != null) infos.toList else Nil
4141

4242
override def errorsReported: Boolean = hasErrors || (outer != null && outer.errorsReported)
43+
44+
// If this is a TyperState buffering reporter then buffer the messages,
45+
// so that then only when the messages are unbuffered (when the reporter if flushed)
46+
// do they go through -Wconf, and possibly then buffered on the Run as a suspended message
47+
override def report(dia: Diagnostic)(using Context): Unit =
48+
if fromTyperState then issueUnconfigured(dia)
49+
else super.report(dia)
4350
}

compiler/src/dotty/tools/dotc/reporting/TestReporter.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import collection.mutable
66
import Diagnostic._
77

88
/** A re-usable Reporter used in Contexts#test */
9-
class TestingReporter extends StoreReporter(null):
9+
class TestingReporter extends StoreReporter(null, fromTyperState = false):
1010
infos = new mutable.ListBuffer[Diagnostic]
1111
override def hasUnreportedErrors: Boolean = infos.exists(_.isInstanceOf[Error])
1212
def reset(): Unit = infos.clear()

0 commit comments

Comments
 (0)