@@ -90,14 +90,21 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint
9090 mySuspendedMessages.getOrElseUpdate(warning.pos.source, mutable.LinkedHashSet .empty) += warning
9191
9292 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
95101 s.markUsed()
96- if ( s.verbose) Action .Verbose
102+ if s.verbose then Action .Verbose
97103 else Action .Silent
98- case _ =>
104+ else
99105 Action .Warning
100- }
106+ case none =>
107+ Action .Warning
101108
102109 def registerNowarn (annotPos : SourcePosition , range : Span )(conf : String , pos : SrcPos )(using Context ): Unit =
103110 var verbose = false
@@ -116,12 +123,10 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint
116123 .merge
117124 addSuppression :
118125 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
121126
122127 def addSuppression (sup : Suppression ): Unit =
123128 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
125130 suppressions += sup
126131
127132 def reportSuspendedMessages (source : SourceFile )(using Context ): Unit = {
@@ -132,18 +137,25 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint
132137 mySuspendedMessages.remove(source).foreach(_.foreach(ctx.reporter.issueIfNotSuppressed))
133138 }
134139
135- def runFinished (hasErrors : Boolean ): Unit =
140+ def runFinished ()(using Context ): Unit =
141+ val hasErrors = ctx.reporter.hasErrors
136142 // report suspended messages (in case the run finished before typer)
137143 mySuspendedMessages.keysIterator.toList.foreach(reportSuspendedMessages)
138144 // report unused nowarns only if all all phases are done
139145 if ! hasErrors && ctx.settings.WunusedHas .nowarn then
140146 for
141147 source <- mySuppressions.keysIterator.toList
142148 sups <- mySuppressions.remove(source)
143- sup <- sups.reverse
144- if ! sup.used
145149 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
147159
148160 /** The compilation units currently being compiled, this may return different
149161 * results over time.
@@ -372,7 +384,7 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint
372384 runPhases(allPhases = fusedPhases)(using runCtx)
373385 if (! ctx.reporter.hasErrors)
374386 Rewrites .writeBack()
375- suppressions.runFinished(hasErrors = ctx.reporter.hasErrors )
387+ suppressions.runFinished()
376388 while (finalizeActions.nonEmpty && canProgress()) {
377389 val action = finalizeActions.remove(0 )
378390 action()
0 commit comments