@@ -90,14 +90,21 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint
90
90
mySuspendedMessages.getOrElseUpdate(warning.pos.source, mutable.LinkedHashSet .empty) += warning
91
91
92
92
def nowarnAction (dia : Diagnostic ): Action .Warning .type | Action .Verbose .type | Action .Silent .type =
93
- mySuppressions.getOrElse(dia.pos.source, Nil ).find(_.matches(dia)) match {
94
- case Some (s) =>
93
+ mySuppressions.get(dia.pos.source) match
94
+ case Some (suppressions) =>
95
+ val matching = suppressions.iterator.filter(_.matches(dia))
96
+ if matching.hasNext then
97
+ val s = matching.next()
98
+ for other <- matching do
99
+ if ! other.used then
100
+ other.markSuperseded() // superseded unless marked used later
95
101
s.markUsed()
96
- if ( s.verbose) Action .Verbose
102
+ if s.verbose then Action .Verbose
97
103
else Action .Silent
98
- case _ =>
104
+ else
99
105
Action .Warning
100
- }
106
+ case none =>
107
+ Action .Warning
101
108
102
109
def registerNowarn (annotPos : SourcePosition , range : Span )(conf : String , pos : SrcPos )(using Context ): Unit =
103
110
var verbose = false
@@ -116,12 +123,10 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint
116
123
.merge
117
124
addSuppression :
118
125
Suppression (annotPos, filters, range.start, range.end, verbose)
119
- .tap: sup =>
120
- if filters == List (MessageFilter .None ) then sup.markUsed() // invalid suppressions, don't report as unused
121
126
122
127
def addSuppression (sup : Suppression ): Unit =
123
128
val suppressions = mySuppressions.getOrElseUpdate(sup.annotPos.source, ListBuffer .empty)
124
- if sup.start != sup.end && suppressions.forall(x => x.start != sup.start || x.end != sup.end) then
129
+ if sup.start != sup.end then
125
130
suppressions += sup
126
131
127
132
def reportSuspendedMessages (source : SourceFile )(using Context ): Unit = {
@@ -132,18 +137,25 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint
132
137
mySuspendedMessages.remove(source).foreach(_.foreach(ctx.reporter.issueIfNotSuppressed))
133
138
}
134
139
135
- def runFinished (hasErrors : Boolean ): Unit =
140
+ def runFinished ()(using Context ): Unit =
141
+ val hasErrors = ctx.reporter.hasErrors
136
142
// report suspended messages (in case the run finished before typer)
137
143
mySuspendedMessages.keysIterator.toList.foreach(reportSuspendedMessages)
138
144
// report unused nowarns only if all all phases are done
139
145
if ! hasErrors && ctx.settings.WunusedHas .nowarn then
140
146
for
141
147
source <- mySuppressions.keysIterator.toList
142
148
sups <- mySuppressions.remove(source)
143
- sup <- sups.reverse
144
- if ! sup.used
145
149
do
146
- report.warning(" @nowarn annotation does not suppress any warnings" , sup.annotPos)
150
+ val suppressions = sups.reverse.toList
151
+ for sup <- suppressions do
152
+ if ! sup.used
153
+ && ! suppressions.exists(s => s.ne(sup) && s.used && s.annotPos == sup.annotPos) // duplicate
154
+ && sup.filters != List (MessageFilter .None ) // invalid suppression, don't report as unused
155
+ then
156
+ val more = if sup.superseded then " but matches a diagnostic" else " "
157
+ report.warning(" @nowarn annotation does not suppress any warnings" + more, sup.annotPos)
158
+ end suppressions
147
159
148
160
/** The compilation units currently being compiled, this may return different
149
161
* results over time.
@@ -372,7 +384,7 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint
372
384
runPhases(allPhases = fusedPhases)(using runCtx)
373
385
if (! ctx.reporter.hasErrors)
374
386
Rewrites .writeBack()
375
- suppressions.runFinished(hasErrors = ctx.reporter.hasErrors )
387
+ suppressions.runFinished()
376
388
while (finalizeActions.nonEmpty && canProgress()) {
377
389
val action = finalizeActions.remove(0 )
378
390
action()
0 commit comments