@@ -568,12 +568,15 @@ 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
575575 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
577580 if aliasSym.is(Local ) then
578581 if ctx.settings.WunusedHas .explicits then
579582 warnAt(pos)(UnusedSymbol .explicitParams(aliasSym))
@@ -582,13 +585,14 @@ object CheckUnused:
582585 warnAt(pos)(UnusedSymbol .privateMembers)
583586 else if ctx.settings.WunusedHas .explicits
584587 && ! 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
588591 case _ => false
589- } )
592+ )
590593 && ! sym.name.isInstanceOf [DerivedName ]
591594 && ! ctx.platform.isMainMethod(m)
595+ && ! usedByDefaultGetter(sym, m)
592596 then
593597 warnAt(pos)(UnusedSymbol .explicitParams(sym))
594598 end checkExplicit
@@ -600,6 +604,16 @@ object CheckUnused:
600604 checkExplicit()
601605 end checkParam
602606
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+
603617 def checkImplicit (sym : Symbol , pos : SrcPos ) =
604618 val m = sym.owner
605619 def allowed =
@@ -629,9 +643,12 @@ object CheckUnused:
629643 val checking =
630644 aliasSym.isAllOf(PrivateParamAccessor , butNot = CaseAccessor )
631645 || 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
633650 warnAt(pos)(UnusedSymbol .implicitParams(aliasSym))
634- else
651+ else if ! usedByDefaultGetter(sym, m) then
635652 warnAt(pos)(UnusedSymbol .implicitParams(sym))
636653
637654 def checkLocal (sym : Symbol , pos : SrcPos ) =
0 commit comments