Skip to content

Commit 9ad7463

Browse files
committed
Move the isAccessible test up to registerSym, instead of isInImport.
That test does not rely on any information dependent on the import selectors. It only relies on information at the use site. Eagerly checking it means we do not put as many symbols into the `usedInScope` set, which is good because it is one of the complexity factors of the unused-imports analysis.
1 parent a096b43 commit 9ad7463

File tree

1 file changed

+12
-11
lines changed

1 file changed

+12
-11
lines changed

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

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ object CheckUnused:
364364
*
365365
* See the `isAccessibleAsIdent` extension method below in the file
366366
*/
367-
private val usedInScope = MutStack(MutSet[(Symbol,Boolean, Option[Name], Boolean)]())
367+
private val usedInScope = MutStack(MutSet[(Symbol, Option[Name], Boolean)]())
368368
private val usedInPosition = MutMap.empty[Name, MutSet[Symbol]]
369369
/* unused import collected during traversal */
370370
private val unusedImport = MutList.empty[ImportSelectorData]
@@ -412,12 +412,16 @@ object CheckUnused:
412412
if sym.isConstructor then
413413
registerUsed(sym.owner, None, notForImport) // constructor are "implicitly" imported with the class
414414
else
415-
val accessibleAsIdent = sym.isAccessibleAsIdent
415+
// If the symbol is accessible in this scope without an import, do not register it for unused import analysis
416+
val notForImport1 =
417+
notForImport
418+
|| (!name.exists(_.toTermName != sym.name.toTermName) && sym.isAccessibleAsIdent)
419+
416420
def addIfExists(sym: Symbol): Unit =
417421
if sym.exists then
418422
usedDef += sym
419-
if !notForImport then
420-
usedInScope.top += ((sym, accessibleAsIdent, name, isDerived))
423+
if !notForImport1 then
424+
usedInScope.top += ((sym, name, isDerived))
421425
addIfExists(sym)
422426
addIfExists(sym.companionModule)
423427
addIfExists(sym.companionClass)
@@ -501,9 +505,9 @@ object CheckUnused:
501505
val selDatas = impInScope.pop()
502506

503507
for usedInfo <- usedInfos do
504-
val (sym, isAccessible, optName, isDerived) = usedInfo
508+
val (sym, optName, isDerived) = usedInfo
505509
val usedData = selDatas.find { selData =>
506-
sym.isInImport(selData, isAccessible, optName, isDerived)
510+
sym.isInImport(selData, optName, isDerived)
507511
}
508512
usedData match
509513
case Some(data) =>
@@ -697,15 +701,12 @@ object CheckUnused:
697701
}
698702

699703
/** Given an import and accessibility, return selector that matches import<->symbol */
700-
private def isInImport(selData: ImportSelectorData, isAccessible: Boolean, symName: Option[Name], isDerived: Boolean)(using Context): Boolean =
704+
private def isInImport(selData: ImportSelectorData, symName: Option[Name], isDerived: Boolean)(using Context): Boolean =
701705
assert(sym.exists)
702706

703707
val selector = selData.selector
704708

705-
if isAccessible && !symName.exists(_.toTermName != sym.name.toTermName) then
706-
// Even if this import matches, it is pointless because the symbol would be accessible anyway
707-
false
708-
else if !selector.isWildcard then
709+
if !selector.isWildcard then
709710
if !symName.forall(explicitName => selector.rename == explicitName.toTermName) then
710711
// if there is an explicit name, it must match
711712
false

0 commit comments

Comments
 (0)