1
1
package dotty .tools .dotc .transform
2
2
3
3
import dotty .tools .dotc .ast .tpd
4
+ import dotty .tools .dotc .core .Symbols .*
4
5
import dotty .tools .dotc .ast .tpd .{Inlined , TreeTraverser }
5
6
import dotty .tools .dotc .ast .untpd
6
7
import dotty .tools .dotc .ast .untpd .ImportSelector
@@ -423,12 +424,12 @@ object CheckUnused:
423
424
if ! tpd.languageImport(imp.expr).nonEmpty && ! imp.isGeneratedByEnum && ! isTransparentAndInline(imp) then
424
425
impInScope.top += imp
425
426
unusedImport ++= imp.selectors.filter { s =>
426
- ! shouldSelectorBeReported(imp, s) && ! isImportExclusion(s)
427
+ ! shouldSelectorBeReported(imp, s) && ! isImportExclusion(s) && ! isImportIgnored(imp, s)
427
428
}
428
429
429
430
/** Register (or not) some `val` or `def` according to the context, scope and flags */
430
431
def registerDef (memDef : tpd.MemberDef )(using Context ): Unit =
431
- if memDef.isValidMemberDef then
432
+ if memDef.isValidMemberDef && ! isDefIgnored(memDef) then
432
433
if memDef.isValidParam then
433
434
if memDef.symbol.isOneOf(GivenOrImplicit ) then
434
435
if ! paramsToSkip.contains(memDef.symbol) then
@@ -439,7 +440,7 @@ object CheckUnused:
439
440
localDefInScope += memDef
440
441
else if memDef.shouldReportPrivateDef then
441
442
privateDefInScope += memDef
442
-
443
+
443
444
/** Register pattern variable */
444
445
def registerPatVar (patvar : tpd.Bind )(using Context ): Unit =
445
446
if ! patvar.symbol.isUnusedAnnot then
@@ -507,7 +508,6 @@ object CheckUnused:
507
508
508
509
def getUnused (using Context ): UnusedResult =
509
510
popScope()
510
-
511
511
val sortedImp =
512
512
if ctx.settings.WunusedHas .imports || ctx.settings.WunusedHas .strictNoImplicitWarn then
513
513
unusedImport.map(d => UnusedSymbol (d.srcPos, d.name, WarnTypes .Imports )).toList
@@ -643,9 +643,21 @@ object CheckUnused:
643
643
sel.isWildcard ||
644
644
imp.expr.tpe.member(sel.name.toTermName).alternatives.exists(_.symbol.isOneOf(GivenOrImplicit )) ||
645
645
imp.expr.tpe.member(sel.name.toTypeName).alternatives.exists(_.symbol.isOneOf(GivenOrImplicit ))
646
- )
647
-
646
+ )
647
+
648
+ /**
649
+ * Ignore CanEqual imports
650
+ */
651
+ private def isImportIgnored (imp : tpd.Import , sel : ImportSelector )(using Context ): Boolean =
652
+ (sel.isWildcard && imp.expr.tpe.allMembers.exists(p => p.symbol.typeRef.baseClasses.exists(_.derivesFrom(defn.CanEqualClass )))) ||
653
+ (imp.expr.tpe.member(sel.name.toTermName).alternatives
654
+ .exists(p => p.symbol.isOneOf(GivenOrImplicit ) && p.symbol.typeRef.baseClasses.exists(_.derivesFrom(defn.CanEqualClass ))))
648
655
656
+ /**
657
+ * Ignore definitions of CanEqual given
658
+ */
659
+ private def isDefIgnored (memDef : tpd.MemberDef )(using Context ): Boolean =
660
+ memDef.symbol.isOneOf(GivenOrImplicit ) && memDef.symbol.typeRef.baseClasses.exists(_.derivesFrom(defn.CanEqualClass ))
649
661
650
662
extension (tree : ImportSelector )
651
663
def boundTpe : Type = tree.bound match {
0 commit comments