From b9f5fc58763f734ad863aa812a65de658f0b24c1 Mon Sep 17 00:00:00 2001 From: Som Snytt Date: 2025年9月23日 10:43:07 -0700 Subject: [PATCH 1/3] Unused lint does not rewrite suppressed warnings Partially duplicates reporter logic; reporter could auto-apply actions, maybe keying off diagnostic ID. --- .../tools/dotc/transform/CheckUnused.scala | 17 +++++++++++++++-- tests/rewrites/i24009.scala | 9 +++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 tests/rewrites/i24009.scala diff --git a/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala b/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala index 1c6bae6b112a..8ecadde2b887 100644 --- a/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala +++ b/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala @@ -15,7 +15,7 @@ import dotty.tools.dotc.core.StdNames.nme import dotty.tools.dotc.core.Symbols.{ClassSymbol, NoSymbol, Symbol, defn, isDeprecated, requiredClass, requiredModule} import dotty.tools.dotc.core.Types.* import dotty.tools.dotc.report -import dotty.tools.dotc.reporting.{CodeAction, UnusedSymbol} +import dotty.tools.dotc.reporting.{Action, CodeAction, Diagnostic, UnusedSymbol, WConf} import dotty.tools.dotc.rewrites.Rewrites import dotty.tools.dotc.transform.MegaPhase.MiniPhase import dotty.tools.dotc.typer.{ImportInfo, Typer} @@ -551,7 +551,20 @@ object CheckUnused: for (msg, pos, origin) <- warnings do if origin.isEmpty then report.warning(msg, pos) else report.warning(msg, pos, origin) - msg.actions.headOption.foreach(Rewrites.applyAction) + // avoid rewrite if warning will be suppressed (would be nice if reporter knew how to apply actions) + msg.actions.headOption match + case Some(action) if ctx.run != null => + val dia = + if origin.isEmpty then Diagnostic.Warning(msg, pos.sourcePos) + else Diagnostic.LintWarning(msg, pos.sourcePos, origin) + ctx.run.nn.suppressions.nowarnAction(dia) match + case Action.Warning => + WConf.parsed.action(dia) match + case Action.Error | Action.Warning => + Rewrites.applyAction(action) + case _ => + case _ => + case _ => type MessageInfo = (UnusedSymbol, SrcPos, String) // string is origin or empty diff --git a/tests/rewrites/i24009.scala b/tests/rewrites/i24009.scala new file mode 100644 index 000000000000..73620d558e51 --- /dev/null +++ b/tests/rewrites/i24009.scala @@ -0,0 +1,9 @@ +//> using options -Wunused:imports -rewrite -Wconf:name=UnusedSymbol&origin=p.C:s + +package p: + class C + +package q: + import p.C // nowarn and no rewrite + + class D From 95e1ce217d67e9fc86643599f81c93065247c7bb Mon Sep 17 00:00:00 2001 From: Som Snytt Date: 2025年9月24日 09:48:42 -0700 Subject: [PATCH 2/3] Reporter applies lint actions Instead of testing whether to emit actions by probing suppressions, just let the reporter apply LintWarning actions when the warning is actually reported. --- .../tools/dotc/reporting/Diagnostic.scala | 4 ++- .../dotty/tools/dotc/reporting/Reporter.scala | 3 +++ .../dotty/tools/dotc/reporting/WConf.scala | 3 ++- .../tools/dotc/transform/CheckUnused.scala | 25 ++++--------------- 4 files changed, 13 insertions(+), 22 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/reporting/Diagnostic.scala b/compiler/src/dotty/tools/dotc/reporting/Diagnostic.scala index 30a9b8f60cf8..da938f761fbc 100644 --- a/compiler/src/dotty/tools/dotc/reporting/Diagnostic.scala +++ b/compiler/src/dotty/tools/dotc/reporting/Diagnostic.scala @@ -40,10 +40,12 @@ object Diagnostic: */ trait OriginWarning(val origin: String): self: Warning => + object OriginWarning: + val NoOrigin = "..." /** Lints are likely to be filtered. Provide extra axes for filtering by `-Wconf`. */ - class LintWarning(msg: Message, pos: SourcePosition, origin: String) + class LintWarning(msg: Message, pos: SourcePosition, origin: String = OriginWarning.NoOrigin) extends Warning(msg, pos), OriginWarning(origin) class Warning( diff --git a/compiler/src/dotty/tools/dotc/reporting/Reporter.scala b/compiler/src/dotty/tools/dotc/reporting/Reporter.scala index af92d0e0efdf..6eeac9832197 100644 --- a/compiler/src/dotty/tools/dotc/reporting/Reporter.scala +++ b/compiler/src/dotty/tools/dotc/reporting/Reporter.scala @@ -9,6 +9,7 @@ import dotty.tools.dotc.core.Mode import dotty.tools.dotc.core.Symbols.{NoSymbol, Symbol} import dotty.tools.dotc.reporting.Diagnostic.* import dotty.tools.dotc.reporting.Message.* +import dotty.tools.dotc.rewrites.Rewrites import dotty.tools.dotc.util.NoSourcePosition import java.io.{BufferedReader, PrintWriter} @@ -170,6 +171,8 @@ abstract class Reporter extends interfaces.ReporterResult { handleRecursive("error reporting", dia.message, ex) dia match { case w: Warning => + if w.isInstanceOf[LintWarning] then + w.msg.actions.foreach(Rewrites.applyAction) warnings = w :: warnings _warningCount += 1 case e: Error => diff --git a/compiler/src/dotty/tools/dotc/reporting/WConf.scala b/compiler/src/dotty/tools/dotc/reporting/WConf.scala index cff15aa6dc38..2cb170ec1764 100644 --- a/compiler/src/dotty/tools/dotc/reporting/WConf.scala +++ b/compiler/src/dotty/tools/dotc/reporting/WConf.scala @@ -34,7 +34,8 @@ enum MessageFilter: pattern.findFirstIn(path).nonEmpty case Origin(pattern) => message match - case message: OriginWarning => pattern.findFirstIn(message.origin).nonEmpty + case message: OriginWarning if message.origin != OriginWarning.NoOrigin => + pattern.findFirstIn(message.origin).nonEmpty case _ => false case None => false diff --git a/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala b/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala index 8ecadde2b887..06ddd817d296 100644 --- a/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala +++ b/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala @@ -15,8 +15,8 @@ import dotty.tools.dotc.core.StdNames.nme import dotty.tools.dotc.core.Symbols.{ClassSymbol, NoSymbol, Symbol, defn, isDeprecated, requiredClass, requiredModule} import dotty.tools.dotc.core.Types.* import dotty.tools.dotc.report -import dotty.tools.dotc.reporting.{Action, CodeAction, Diagnostic, UnusedSymbol, WConf} -import dotty.tools.dotc.rewrites.Rewrites +import dotty.tools.dotc.reporting.{CodeAction, Diagnostic, UnusedSymbol} +import dotty.tools.dotc.rewrites.Rewrites.ActionPatch import dotty.tools.dotc.transform.MegaPhase.MiniPhase import dotty.tools.dotc.typer.{ImportInfo, Typer} import dotty.tools.dotc.typer.Deriving.OriginalTypeClass @@ -549,29 +549,15 @@ object CheckUnused: def reportUnused()(using Context): Unit = for (msg, pos, origin) <- warnings do - if origin.isEmpty then report.warning(msg, pos) - else report.warning(msg, pos, origin) - // avoid rewrite if warning will be suppressed (would be nice if reporter knew how to apply actions) - msg.actions.headOption match - case Some(action) if ctx.run != null => - val dia = - if origin.isEmpty then Diagnostic.Warning(msg, pos.sourcePos) - else Diagnostic.LintWarning(msg, pos.sourcePos, origin) - ctx.run.nn.suppressions.nowarnAction(dia) match - case Action.Warning => - WConf.parsed.action(dia) match - case Action.Error | Action.Warning => - Rewrites.applyAction(action) - case _ => - case _ => - case _ => + report.warning(msg, pos, origin) type MessageInfo = (UnusedSymbol, SrcPos, String) // string is origin or empty def warnings(using Context): Array[MessageInfo] = val actionable = ctx.settings.rewrite.value.nonEmpty val warnings = ArrayBuilder.make[MessageInfo] - def warnAt(pos: SrcPos)(msg: UnusedSymbol, origin: String = ""): Unit = warnings.addOne((msg, pos, origin)) + def warnAt(pos: SrcPos)(msg: UnusedSymbol, origin: String = Diagnostic.OriginWarning.NoOrigin): Unit = + warnings.addOne((msg, pos, origin)) val infos = refInfos // non-local sym was target of assignment or has a sibling setter that was referenced @@ -734,7 +720,6 @@ object CheckUnused: def checkImports() = import scala.jdk.CollectionConverters.given - import Rewrites.ActionPatch type ImpSel = (Import, ImportSelector) def isUsed(sel: ImportSelector): Boolean = infos.sels.containsKey(sel) def warnImport(warnable: ImpSel, actions: List[CodeAction] = Nil): Unit = From 8c198cfc0f06dfc1689bf6a3fba4c9d303982200 Mon Sep 17 00:00:00 2001 From: Som Snytt Date: 2025年9月24日 10:05:09 -0700 Subject: [PATCH 3/3] Unused imports emits actions always --- compiler/src/dotty/tools/dotc/transform/CheckUnused.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala b/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala index 06ddd817d296..d935e1563bf0 100644 --- a/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala +++ b/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala @@ -554,7 +554,7 @@ object CheckUnused: type MessageInfo = (UnusedSymbol, SrcPos, String) // string is origin or empty def warnings(using Context): Array[MessageInfo] = - val actionable = ctx.settings.rewrite.value.nonEmpty + val actionable: true = true //ctx.settings.rewrite.value.nonEmpty val warnings = ArrayBuilder.make[MessageInfo] def warnAt(pos: SrcPos)(msg: UnusedSymbol, origin: String = Diagnostic.OriginWarning.NoOrigin): Unit = warnings.addOne((msg, pos, origin))

AltStyle によって変換されたページ (->オリジナル) /