Skip to content

Commit e5b76a3

Browse files
committed
Use type test of prefix for usages in scope
1 parent daeeb4b commit e5b76a3

File tree

1 file changed

+13
-9
lines changed

1 file changed

+13
-9
lines changed

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

+13-9
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ object CheckUnused:
340340

341341
/* IMPORTS */
342342
private val impInScope = Stack(ListBuffer.empty[ImportSelectorData])
343-
private val usedInScope = Stack(mut.Set.empty[Usage])
343+
private val usedInScope = Stack(mut.Map.empty[Symbol, ListBuffer[Usage]])
344344
private val usedInPosition = mut.Map.empty[Name, mut.Set[Symbol]]
345345
/* unused import collected during traversal */
346346
private val unusedImport = ListBuffer.empty[ImportSelectorData]
@@ -397,14 +397,19 @@ object CheckUnused:
397397
if sym.exists then
398398
usedDef += sym
399399
if includeForImport1 then
400-
usedInScope.top += Usage(sym, name, prefix, isDerived)
400+
addUsage(Usage(sym, name, prefix, isDerived))
401401
addIfExists(sym)
402402
addIfExists(sym.companionModule)
403403
addIfExists(sym.companionClass)
404404
if sym.sourcePos.exists then
405405
for n <- name do
406406
usedInPosition.getOrElseUpdate(n, mut.Set.empty) += sym
407407

408+
def addUsage(usage: Usage)(using Context): Unit =
409+
val usages = usedInScope.top.getOrElseUpdate(usage.symbol, ListBuffer.empty)
410+
if !usages.exists(x => x.name == usage.name && x.isDerived == usage.isDerived && x.prefix =:= usage.prefix)
411+
then usages += usage
412+
408413
/** Register a symbol that should be ignored */
409414
def addIgnoredUsage(sym: Symbol)(using Context): Unit =
410415
doNotRegister ++= sym.everySymbol
@@ -465,7 +470,7 @@ object CheckUnused:
465470
// unused imports :
466471
currScopeType.push(newScopeType)
467472
impInScope.push(ListBuffer.empty)
468-
usedInScope.push(mut.Set.empty)
473+
usedInScope.push(mut.Map.empty)
469474

470475
def registerSetVar(sym: Symbol): Unit =
471476
setVars += sym
@@ -477,18 +482,17 @@ object CheckUnused:
477482
*/
478483
def popScope(scopeType: ScopeType)(using Context): Unit =
479484
assert(currScopeType.pop() == scopeType)
480-
val usedInfos = usedInScope.pop()
481485
val selDatas = impInScope.pop()
482486

483-
for usedInfo <- usedInfos do
484-
val Usage(sym, optName, prefix, isDerived) = usedInfo
485-
selDatas.find(sym.isInImport(_, optName, prefix, isDerived)) match
487+
for usedInfos <- usedInScope.pop().valuesIterator; usedInfo <- usedInfos do
488+
import usedInfo.*
489+
selDatas.find(symbol.isInImport(_, name, prefix, isDerived)) match
486490
case Some(sel) =>
487491
sel.markUsed()
488492
case None =>
489493
// Propagate the symbol one level up
490494
if usedInScope.nonEmpty then
491-
usedInScope.top += usedInfo
495+
addUsage(usedInfo)
492496
end for // each in usedInfos
493497

494498
for selData <- selDatas do
@@ -802,7 +806,7 @@ object CheckUnused:
802806
/** A symbol usage includes the name under which it was observed,
803807
* the prefix from which it was selected, and whether it is in a derived element.
804808
*/
805-
case class Usage(symbol: Symbol, name: Option[Name], prefix: Type, isDerived: Boolean)
809+
class Usage(val symbol: Symbol, val name: Option[Name], val prefix: Type, val isDerived: Boolean)
806810
end UnusedData
807811
extension (sym: Symbol)
808812
/** is accessible without import in current context */

0 commit comments

Comments
 (0)