diff --git a/compiler/src/dotty/tools/dotc/reporting/messages.scala b/compiler/src/dotty/tools/dotc/reporting/messages.scala index 0db766d4e337..4a081bffbd33 100644 --- a/compiler/src/dotty/tools/dotc/reporting/messages.scala +++ b/compiler/src/dotty/tools/dotc/reporting/messages.scala @@ -3310,23 +3310,29 @@ extends TypeMsg(ConstructorProxyNotValueID): |are not values themselves, they can only be referred to in selections.""" class UnusedSymbol(errorText: String, val actions: List[CodeAction] = Nil)(using Context) -extends Message(UnusedSymbolID) { +extends Message(UnusedSymbolID): def kind = MessageKind.UnusedSymbol override def msg(using Context) = errorText override def explain(using Context) = "" override def actions(using Context) = this.actions -} object UnusedSymbol: def imports(actions: List[CodeAction])(using Context): UnusedSymbol = UnusedSymbol(i"unused import", actions) def localDefs(using Context): UnusedSymbol = UnusedSymbol(i"unused local definition") - def explicitParams(using Context): UnusedSymbol = UnusedSymbol(i"unused explicit parameter") - def implicitParams(using Context): UnusedSymbol = UnusedSymbol(i"unused implicit parameter") + def explicitParams(sym: Symbol)(using Context): UnusedSymbol = + UnusedSymbol(i"unused explicit parameter${paramAddendum(sym)}") + def implicitParams(sym: Symbol)(using Context): UnusedSymbol = + UnusedSymbol(i"unused implicit parameter${paramAddendum(sym)}") def privateMembers(using Context): UnusedSymbol = UnusedSymbol(i"unused private member") def patVars(using Context): UnusedSymbol = UnusedSymbol(i"unused pattern variable") - def unsetLocals(using Context): UnusedSymbol = UnusedSymbol(i"unset local variable, consider using an immutable val instead") - def unsetPrivates(using Context): UnusedSymbol = UnusedSymbol(i"unset private variable, consider using an immutable val instead") + def unsetLocals(using Context): UnusedSymbol = + UnusedSymbol(i"unset local variable, consider using an immutable val instead") + def unsetPrivates(using Context): UnusedSymbol = + UnusedSymbol(i"unset private variable, consider using an immutable val instead") + private def paramAddendum(sym: Symbol)(using Context): String = + if sym.denot.owner.is(ExtensionMethod) then i" in extension ${sym.denot.owner}" + else "" class NonNamedArgumentInJavaAnnotation(using Context) extends SyntaxMsg(NonNamedArgumentInJavaAnnotationID): diff --git a/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala b/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala index 008e1c6feee8..e34aad6df8a7 100644 --- a/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala +++ b/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala @@ -500,6 +500,8 @@ object CheckUnused: val warnings = ArrayBuilder.make[MessageInfo] def warnAt(pos: SrcPos)(msg: UnusedSymbol, origin: String = ""): Unit = warnings.addOne((msg, pos, origin)) val infos = refInfos + //println(infos.defs.mkString("DEFS\n", "\n", "\n---")) + //println(infos.refs.mkString("REFS\n", "\n", "\n---")) def checkUnassigned(sym: Symbol, pos: SrcPos) = if sym.isLocalToBlock then @@ -540,7 +542,7 @@ object CheckUnused: if aliasSym.isAllOf(PrivateParamAccessor, butNot = CaseAccessor) && !infos.refs(alias.symbol) then if aliasSym.is(Local) then if ctx.settings.WunusedHas.explicits then - warnAt(pos)(UnusedSymbol.explicitParams) + warnAt(pos)(UnusedSymbol.explicitParams(aliasSym)) else if ctx.settings.WunusedHas.privates then warnAt(pos)(UnusedSymbol.privateMembers) @@ -554,7 +556,7 @@ object CheckUnused: && !sym.name.isInstanceOf[DerivedName] && !ctx.platform.isMainMethod(m) then - warnAt(pos)(UnusedSymbol.explicitParams) + warnAt(pos)(UnusedSymbol.explicitParams(sym)) end checkExplicit // begin if !infos.skip(m) @@ -594,9 +596,9 @@ object CheckUnused: aliasSym.isAllOf(PrivateParamAccessor, butNot = CaseAccessor) || aliasSym.isAllOf(Protected | ParamAccessor, butNot = CaseAccessor) && m.owner.is(Given) if checking && !infos.refs(alias.symbol) then - warnAt(pos)(UnusedSymbol.implicitParams) + warnAt(pos)(UnusedSymbol.implicitParams(aliasSym)) else - warnAt(pos)(UnusedSymbol.implicitParams) + warnAt(pos)(UnusedSymbol.implicitParams(sym)) def checkLocal(sym: Symbol, pos: SrcPos) = if ctx.settings.WunusedHas.locals diff --git a/tests/warn/i15503g.check b/tests/warn/i15503g.check new file mode 100644 index 000000000000..105df82e8a1a --- /dev/null +++ b/tests/warn/i15503g.check @@ -0,0 +1,28 @@ +-- [E198] Unused Symbol Warning: tests/warn/i15503g.scala:8:17 --------------------------------------------------------- +8 | private def f2(a: Int) = default_int // warn + | ^ + | unused explicit parameter +-- [E198] Unused Symbol Warning: tests/warn/i15503g.scala:9:31 --------------------------------------------------------- +9 | private def f3(a: Int)(using Int) = a // warn + | ^ + | unused implicit parameter +-- [E198] Unused Symbol Warning: tests/warn/i15503g.scala:10:17 -------------------------------------------------------- +10 | private def f4(a: Int)(using Int) = default_int // warn // warn + | ^ + | unused explicit parameter +-- [E198] Unused Symbol Warning: tests/warn/i15503g.scala:10:31 -------------------------------------------------------- +10 | private def f4(a: Int)(using Int) = default_int // warn // warn + | ^ + | unused implicit parameter +-- [E198] Unused Symbol Warning: tests/warn/i15503g.scala:11:17 -------------------------------------------------------- +11 | private def f6(a: Int)(using Int) = summon[Int] // warn + | ^ + | unused explicit parameter +-- [E198] Unused Symbol Warning: tests/warn/i15503g.scala:23:18 -------------------------------------------------------- +23 | def isAnIssue(y: A): Boolean = x == x // warn + | ^ + | unused explicit parameter in extension method isAnIssue +-- [E198] Unused Symbol Warning: tests/warn/i15503g.scala:29:30 -------------------------------------------------------- +29 | extension (s: String)(using Show) // warn not used in repeat + | ^ + | unused implicit parameter in extension method repeat diff --git a/tests/warn/i15503g.scala b/tests/warn/i15503g.scala index cfbfcdb04d1e..f63f7ea73475 100644 --- a/tests/warn/i15503g.scala +++ b/tests/warn/i15503g.scala @@ -1,4 +1,4 @@ -//> using options -Wunused:params +//> using options -Wunused:params /* This goes around the "trivial method" detection */ object Foo { @@ -15,10 +15,17 @@ object Foo { private def g2(x: Int) = ??? // OK } -package foo.test.i17101: +object i17101: type Test[A] = A extension[A] (x: Test[A]) { // OK def value: A = x def causesIssue: Unit = println("oh no") def isAnIssue(y: A): Boolean = x == x // warn } + +object i23125: + trait Show: + def show(s: String) = s + extension (s: String)(using Show) // warn not used in repeat + def echo = println(summon[Show].show(s)) + def repeat = s * 2