@@ -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