Skip to content

Commit 1ea615f

Browse files
som-snytttgodzik
authored andcommitted
Check if param was used in default arg getter
[Cherry-picked 0cbe43b]
1 parent b27e4d5 commit 1ea615f

File tree

3 files changed

+21
-5
lines changed

3 files changed

+21
-5
lines changed

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

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -568,7 +568,7 @@ object CheckUnused:
568568
// A class param is unused if its param accessor is unused.
569569
// (The class param is not assigned to a field until constructors.)
570570
// A local param accessor warns as a param; a private accessor as a private member.
571-
// Avoid warning for case class elements because they are aliased via unapply.
571+
// Avoid warning for case class elements because they are aliased via unapply (i.e. may be extracted).
572572
if m.isPrimaryConstructor then
573573
val alias = m.owner.info.member(sym.name)
574574
if alias.exists then
@@ -589,6 +589,7 @@ object CheckUnused:
589589
)
590590
&& !sym.name.isInstanceOf[DerivedName]
591591
&& !ctx.platform.isMainMethod(m)
592+
&& !usedByDefaultGetter(sym, m)
592593
then
593594
warnAt(pos)(UnusedSymbol.explicitParams(sym))
594595
end checkExplicit
@@ -600,6 +601,16 @@ object CheckUnused:
600601
checkExplicit()
601602
end checkParam
602603

604+
// does the param have an alias in a default arg method that is used?
605+
def usedByDefaultGetter(param: Symbol, meth: Symbol): Boolean =
606+
val cls = meth.enclosingClass
607+
val MethName = meth.name
608+
cls.info.decls.exists: d =>
609+
d.name match
610+
case DefaultGetterName(MethName, _) =>
611+
d.paramSymss.exists(_.exists(p => p.name == param.name && infos.refs(p)))
612+
case _ => false
613+
603614
def checkImplicit(sym: Symbol, pos: SrcPos) =
604615
val m = sym.owner
605616
def allowed =
@@ -631,7 +642,7 @@ object CheckUnused:
631642
|| aliasSym.isAllOf(Protected | ParamAccessor, butNot = CaseAccessor) && m.owner.is(Given)
632643
if checking && !infos.refs(alias.symbol) then
633644
warnAt(pos)(UnusedSymbol.implicitParams(aliasSym))
634-
else
645+
else if !usedByDefaultGetter(sym, m) then
635646
warnAt(pos)(UnusedSymbol.implicitParams(sym))
636647

637648
def checkLocal(sym: Symbol, pos: SrcPos) =

tests/warn/i15503e.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,4 +92,4 @@ object UnwrapTyped:
9292
error("Compiler bug: `codeOf` was not evaluated by the compiler")
9393

9494
object `default usage`:
95-
def f(i: Int)(j: Int = i * 2) = j // warn I guess
95+
def f(i: Int)(j: Int = i * 2) = j // ~warn~ I guess (see tests/warn/i23349.scala)

tests/warn/i23349.scala

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

33
// An external class that doesn't get its own `copy` method.
44
class Foo(val a: String, val b: Int)
@@ -12,4 +12,9 @@ extension (self: Foo)
1212
//
1313
// Example 2: implement `copyFoo` with parameter groups.
1414
//
15-
def copyFoo(foo: Foo)(a: String = foo.a, b: Int = foo.b): Foo = Foo(a, b) // warn
15+
def copyFoo(foo: Foo)(a: String = foo.a, b: Int = foo.b): Foo = Foo(a, b)
16+
17+
class C:
18+
def copyFoo(foo: Foo, bar: String)(a: String = foo.a, b: Int = foo.b)(c: String = bar): Foo = Foo(a, b) // warn c
19+
def copyUsing(using foo: Foo, bar: String)(a: String = foo.a, b: Int = foo.b)(c: String = bar): Foo = // warn c
20+
Foo(a, b)

0 commit comments

Comments
 (0)