@@ -568,12 +568,15 @@ object CheckUnused:
568
568
// A class param is unused if its param accessor is unused.
569
569
// (The class param is not assigned to a field until constructors.)
570
570
// 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) .
572
572
if m.isPrimaryConstructor then
573
573
val alias = m.owner.info.member(sym.name)
574
574
if alias.exists then
575
575
val aliasSym = alias.symbol
576
- if aliasSym.isAllOf(PrivateParamAccessor , butNot = CaseAccessor ) && ! infos.refs(alias.symbol) then
576
+ if aliasSym.isAllOf(PrivateParamAccessor , butNot = CaseAccessor )
577
+ && ! infos.refs(alias.symbol)
578
+ && ! usedByDefaultGetter(sym, m)
579
+ then
577
580
if aliasSym.is(Local ) then
578
581
if ctx.settings.WunusedHas .explicits then
579
582
warnAt(pos)(UnusedSymbol .explicitParams(aliasSym))
@@ -582,13 +585,14 @@ object CheckUnused:
582
585
warnAt(pos)(UnusedSymbol .privateMembers)
583
586
else if ctx.settings.WunusedHas .explicits
584
587
&& ! sym.is(Synthetic ) // param to setter is unused bc there is no field yet
585
- && ! (sym.owner.is(ExtensionMethod ) && {
586
- m.paramSymss.dropWhile(_.exists(_.isTypeParam)) match
587
- case (h :: Nil ) :: Nil => h == sym // param is the extended receiver
588
+ && ! (sym.owner.is(ExtensionMethod ) &&
589
+ m.paramSymss.dropWhile(_.exists(_.isTypeParam)). match
590
+ case (h :: Nil ) :: _ => h == sym // param is the extended receiver
588
591
case _ => false
589
- } )
592
+ )
590
593
&& ! sym.name.isInstanceOf [DerivedName ]
591
594
&& ! ctx.platform.isMainMethod(m)
595
+ && ! usedByDefaultGetter(sym, m)
592
596
then
593
597
warnAt(pos)(UnusedSymbol .explicitParams(sym))
594
598
end checkExplicit
@@ -600,6 +604,16 @@ object CheckUnused:
600
604
checkExplicit()
601
605
end checkParam
602
606
607
+ // does the param have an alias in a default arg method that is used?
608
+ def usedByDefaultGetter (param : Symbol , meth : Symbol ): Boolean =
609
+ val cls = if meth.isConstructor then meth.enclosingClass.companionModule else meth.enclosingClass
610
+ val MethName = meth.name
611
+ cls.info.decls.exists: d =>
612
+ d.name match
613
+ case DefaultGetterName (MethName , _) =>
614
+ d.paramSymss.exists(_.exists(p => p.name == param.name && infos.refs(p)))
615
+ case _ => false
616
+
603
617
def checkImplicit (sym : Symbol , pos : SrcPos ) =
604
618
val m = sym.owner
605
619
def allowed =
@@ -629,9 +643,12 @@ object CheckUnused:
629
643
val checking =
630
644
aliasSym.isAllOf(PrivateParamAccessor , butNot = CaseAccessor )
631
645
|| aliasSym.isAllOf(Protected | ParamAccessor , butNot = CaseAccessor ) && m.owner.is(Given )
632
- if checking && ! infos.refs(alias.symbol) then
646
+ if checking
647
+ && ! infos.refs(alias.symbol)
648
+ && ! usedByDefaultGetter(sym, m)
649
+ then
633
650
warnAt(pos)(UnusedSymbol .implicitParams(aliasSym))
634
- else
651
+ else if ! usedByDefaultGetter(sym, m) then
635
652
warnAt(pos)(UnusedSymbol .implicitParams(sym))
636
653
637
654
def checkLocal (sym : Symbol , pos : SrcPos ) =
0 commit comments