Skip to content

Commit a44cf26

Browse files
Mention extension in unused param warning (#23132)
Fixes #23125 Make the message more verbose by stating the extension method name. This could be improved by only adding words if the param pos is on a different line from the method pos.
2 parents 4ddeda5 + 2d2da2e commit a44cf26

File tree

4 files changed

+55
-12
lines changed

4 files changed

+55
-12
lines changed

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

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3312,23 +3312,29 @@ extends TypeMsg(ConstructorProxyNotValueID):
33123312
|are not values themselves, they can only be referred to in selections."""
33133313

33143314
class UnusedSymbol(errorText: String, val actions: List[CodeAction] = Nil)(using Context)
3315-
extends Message(UnusedSymbolID) {
3315+
extends Message(UnusedSymbolID):
33163316
def kind = MessageKind.UnusedSymbol
33173317

33183318
override def msg(using Context) = errorText
33193319
override def explain(using Context) = ""
33203320
override def actions(using Context) = this.actions
3321-
}
33223321

33233322
object UnusedSymbol:
33243323
def imports(actions: List[CodeAction])(using Context): UnusedSymbol = UnusedSymbol(i"unused import", actions)
33253324
def localDefs(using Context): UnusedSymbol = UnusedSymbol(i"unused local definition")
3326-
def explicitParams(using Context): UnusedSymbol = UnusedSymbol(i"unused explicit parameter")
3327-
def implicitParams(using Context): UnusedSymbol = UnusedSymbol(i"unused implicit parameter")
3325+
def explicitParams(sym: Symbol)(using Context): UnusedSymbol =
3326+
UnusedSymbol(i"unused explicit parameter${paramAddendum(sym)}")
3327+
def implicitParams(sym: Symbol)(using Context): UnusedSymbol =
3328+
UnusedSymbol(i"unused implicit parameter${paramAddendum(sym)}")
33283329
def privateMembers(using Context): UnusedSymbol = UnusedSymbol(i"unused private member")
33293330
def patVars(using Context): UnusedSymbol = UnusedSymbol(i"unused pattern variable")
3330-
def unsetLocals(using Context): UnusedSymbol = UnusedSymbol(i"unset local variable, consider using an immutable val instead")
3331-
def unsetPrivates(using Context): UnusedSymbol = UnusedSymbol(i"unset private variable, consider using an immutable val instead")
3331+
def unsetLocals(using Context): UnusedSymbol =
3332+
UnusedSymbol(i"unset local variable, consider using an immutable val instead")
3333+
def unsetPrivates(using Context): UnusedSymbol =
3334+
UnusedSymbol(i"unset private variable, consider using an immutable val instead")
3335+
private def paramAddendum(sym: Symbol)(using Context): String =
3336+
if sym.denot.owner.is(ExtensionMethod) then i" in extension ${sym.denot.owner}"
3337+
else ""
33323338

33333339
class NonNamedArgumentInJavaAnnotation(using Context) extends SyntaxMsg(NonNamedArgumentInJavaAnnotationID):
33343340

compiler/src/dotty/tools/dotc/transform/CheckUnused.scala

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,8 @@ object CheckUnused:
500500
val warnings = ArrayBuilder.make[MessageInfo]
501501
def warnAt(pos: SrcPos)(msg: UnusedSymbol, origin: String = ""): Unit = warnings.addOne((msg, pos, origin))
502502
val infos = refInfos
503+
//println(infos.defs.mkString("DEFS\n", "\n", "\n---"))
504+
//println(infos.refs.mkString("REFS\n", "\n", "\n---"))
503505

504506
def checkUnassigned(sym: Symbol, pos: SrcPos) =
505507
if sym.isLocalToBlock then
@@ -540,7 +542,7 @@ object CheckUnused:
540542
if aliasSym.isAllOf(PrivateParamAccessor, butNot = CaseAccessor) && !infos.refs(alias.symbol) then
541543
if aliasSym.is(Local) then
542544
if ctx.settings.WunusedHas.explicits then
543-
warnAt(pos)(UnusedSymbol.explicitParams)
545+
warnAt(pos)(UnusedSymbol.explicitParams(aliasSym))
544546
else
545547
if ctx.settings.WunusedHas.privates then
546548
warnAt(pos)(UnusedSymbol.privateMembers)
@@ -554,7 +556,7 @@ object CheckUnused:
554556
&& !sym.name.isInstanceOf[DerivedName]
555557
&& !ctx.platform.isMainMethod(m)
556558
then
557-
warnAt(pos)(UnusedSymbol.explicitParams)
559+
warnAt(pos)(UnusedSymbol.explicitParams(sym))
558560
end checkExplicit
559561
// begin
560562
if !infos.skip(m)
@@ -594,9 +596,9 @@ object CheckUnused:
594596
aliasSym.isAllOf(PrivateParamAccessor, butNot = CaseAccessor)
595597
|| aliasSym.isAllOf(Protected | ParamAccessor, butNot = CaseAccessor) && m.owner.is(Given)
596598
if checking && !infos.refs(alias.symbol) then
597-
warnAt(pos)(UnusedSymbol.implicitParams)
599+
warnAt(pos)(UnusedSymbol.implicitParams(aliasSym))
598600
else
599-
warnAt(pos)(UnusedSymbol.implicitParams)
601+
warnAt(pos)(UnusedSymbol.implicitParams(sym))
600602

601603
def checkLocal(sym: Symbol, pos: SrcPos) =
602604
if ctx.settings.WunusedHas.locals

tests/warn/i15503g.check

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
-- [E198] Unused Symbol Warning: tests/warn/i15503g.scala:8:17 ---------------------------------------------------------
2+
8 | private def f2(a: Int) = default_int // warn
3+
| ^
4+
| unused explicit parameter
5+
-- [E198] Unused Symbol Warning: tests/warn/i15503g.scala:9:31 ---------------------------------------------------------
6+
9 | private def f3(a: Int)(using Int) = a // warn
7+
| ^
8+
| unused implicit parameter
9+
-- [E198] Unused Symbol Warning: tests/warn/i15503g.scala:10:17 --------------------------------------------------------
10+
10 | private def f4(a: Int)(using Int) = default_int // warn // warn
11+
| ^
12+
| unused explicit parameter
13+
-- [E198] Unused Symbol Warning: tests/warn/i15503g.scala:10:31 --------------------------------------------------------
14+
10 | private def f4(a: Int)(using Int) = default_int // warn // warn
15+
| ^
16+
| unused implicit parameter
17+
-- [E198] Unused Symbol Warning: tests/warn/i15503g.scala:11:17 --------------------------------------------------------
18+
11 | private def f6(a: Int)(using Int) = summon[Int] // warn
19+
| ^
20+
| unused explicit parameter
21+
-- [E198] Unused Symbol Warning: tests/warn/i15503g.scala:23:18 --------------------------------------------------------
22+
23 | def isAnIssue(y: A): Boolean = x == x // warn
23+
| ^
24+
| unused explicit parameter in extension method isAnIssue
25+
-- [E198] Unused Symbol Warning: tests/warn/i15503g.scala:29:30 --------------------------------------------------------
26+
29 | extension (s: String)(using Show) // warn not used in repeat
27+
| ^
28+
| unused implicit parameter in extension method repeat

tests/warn/i15503g.scala

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//> using options -Wunused:params
1+
//> using options -Wunused:params
22

33
/* This goes around the "trivial method" detection */
44
object Foo {
@@ -15,10 +15,17 @@ object Foo {
1515
private def g2(x: Int) = ??? // OK
1616
}
1717

18-
package foo.test.i17101:
18+
object i17101:
1919
type Test[A] = A
2020
extension[A] (x: Test[A]) { // OK
2121
def value: A = x
2222
def causesIssue: Unit = println("oh no")
2323
def isAnIssue(y: A): Boolean = x == x // warn
2424
}
25+
26+
object i23125:
27+
trait Show:
28+
def show(s: String) = s
29+
extension (s: String)(using Show) // warn not used in repeat
30+
def echo = println(summon[Show].show(s))
31+
def repeat = s * 2

0 commit comments

Comments
 (0)