Skip to content

Commit 0e83a80

Browse files
authored
Merge pull request #15037 from dotty-staging/exp-i14907
Relax assertion in TyperState#commit If there's nothing to commit; clear unreported warnings in Reporter#flush
2 parents cad8db8 + 87c97e7 commit 0e83a80

File tree

3 files changed

+31
-9
lines changed

3 files changed

+31
-9
lines changed

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

+11-8
Original file line numberDiff line numberDiff line change
@@ -141,18 +141,21 @@ class TyperState() {
141141
Stats.record("typerState.commit")
142142
assert(isCommittable, s"$this is not committable")
143143
assert(!isCommitted, s"$this is already committed")
144-
reporter.flush()
145-
setCommittable(false)
146144
val targetState = ctx.typerState
147145

148-
// Committing into an already committed TyperState usually doesn't make
149-
// sense since it means the constraints we're committing won't be propagated
150-
// further, but it can happen if the targetState gets captured in a reported
151-
// Message, because forcing that Message might involve creating and
152-
// committing new TyperStates into the captured one after its been committed.
153-
assert(!targetState.isCommitted || targetState.reporter.hasErrors || targetState.reporter.hasWarnings,
146+
val nothingToCommit = (constraint eq targetState.constraint) && !reporter.hasUnreportedMessages
147+
assert(!targetState.isCommitted || nothingToCommit ||
148+
// Committing into an already committed TyperState usually doesn't make
149+
// sense since it means the constraints and messages we're committing won't be propagated
150+
// further, but it can happen if the targetState gets captured in a reported
151+
// Message, because forcing that Message might involve creating and
152+
// committing new TyperStates into the captured one after it's been committed.
153+
targetState.reporter.hasErrors || targetState.reporter.hasWarnings,
154154
s"Attempt to commit $this into already committed $targetState")
155155

156+
reporter.flush()
157+
setCommittable(false)
158+
156159
if constraint ne targetState.constraint then
157160
Stats.record("typerState.commit.new constraint")
158161
constr.println(i"committing $this to $targetState, fromConstr = $constraint, toConstr = ${targetState.constraint}")

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

+9-1
Original file line numberDiff line numberDiff line change
@@ -244,15 +244,23 @@ abstract class Reporter extends interfaces.ReporterResult {
244244
*/
245245
def hasUnreportedErrors: Boolean = false
246246

247+
/** Does this reporter contain any message that have yet to be reported by its outer reporter ?
248+
* This includes any warning stored in `unreportedWarnings` which need to be propagated to
249+
* get an accurate count of unreported warnings in the outer reporter.
250+
*/
251+
def hasUnreportedMessages(using Context): Boolean =
252+
pendingMessages.nonEmpty || unreportedWarnings.nonEmpty
253+
247254
/** If this reporter buffers messages, remove and return all buffered messages. */
248255
def removeBufferedMessages(using Context): List[Diagnostic] = Nil
249256

250-
/** Issue all error messages in this reporter to next outer one, or make sure they are written. */
257+
/** Issue all messages in this reporter to next outer one, or make sure they are written. */
251258
def flush()(using Context): Unit =
252259
val msgs = removeBufferedMessages
253260
if msgs.nonEmpty then msgs.foreach(ctx.reporter.report)
254261
for (key, count) <- unreportedWarnings do
255262
ctx.reporter.addUnreported(key, count)
263+
unreportedWarnings = Map.empty
256264

257265
/** If this reporter buffers messages, all buffered messages, otherwise Nil */
258266
def pendingMessages(using Context): List[Diagnostic] = Nil

tests/pos/i14907.scala

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
object Module {
2+
class Fun[N <: Int]()
3+
type Fill[N <: Int] = N match {
4+
case 0 => EmptyTuple
5+
case 1 => Any *: Fill[0]
6+
}
7+
extension[N <: Int] (f: Fun[N])
8+
def apply: Fill[N] => Any = ???
9+
10+
Fun[1]()(???)
11+
}

0 commit comments

Comments
 (0)