@@ -21,6 +21,7 @@ import dotty.tools.dotc.core.Types.Type
21
21
import dotty .tools .dotc .core .Types .AnnotatedType
22
22
import dotty .tools .dotc .core .Flags .flagsString
23
23
import dotty .tools .dotc .core .Flags
24
+ import dotty .tools .dotc .core .Names .Name
24
25
25
26
26
27
@@ -71,10 +72,10 @@ class CheckUnused extends Phase:
71
72
unusedDataApply(_.registerImport(imp))
72
73
traverseChildren(tree)(using newCtx)
73
74
case ident : Ident =>
74
- unusedDataApply(_.registerUsed(ident.symbol))
75
+ unusedDataApply(_.registerUsed(ident.symbol, Some (ident.name) ))
75
76
traverseChildren(tree)(using newCtx)
76
77
case sel : Select =>
77
- unusedDataApply(_.registerUsed(sel.symbol))
78
+ unusedDataApply(_.registerUsed(sel.symbol, Some (sel.name) ))
78
79
traverseChildren(tree)(using newCtx)
79
80
case _ : (tpd.Block | tpd.Template | tpd.PackageDef ) =>
80
81
unusedDataApply { ud =>
@@ -99,7 +100,7 @@ class CheckUnused extends Phase:
99
100
100
101
private def typeTraverser (dt : (UnusedData => Any ) => Unit )(using Context ) = new TypeTraverser :
101
102
override def traverse (tp : Type ): Unit = tp match
102
- case AnnotatedType (_, annot) => dt(_.registerUsed(annot.symbol))
103
+ case AnnotatedType (_, annot) => dt(_.registerUsed(annot.symbol, None ))
103
104
case _ => traverseChildren(tp)
104
105
105
106
private def reportUnused (res : UnusedData .UnusedResult )(using Context ): Unit =
@@ -156,7 +157,7 @@ object CheckUnused:
156
157
*
157
158
* See the `isAccessibleAsIdent` extension method below in the file
158
159
*/
159
- private val usedInScope = MutStack (MutSet [(Symbol ,Boolean )]())
160
+ private val usedInScope = MutStack (MutSet [(Symbol ,Boolean , Option [ Name ] )]())
160
161
/* unused import collected during traversal */
161
162
private val unusedImport = MutSet [ImportSelector ]()
162
163
@@ -195,17 +196,15 @@ object CheckUnused:
195
196
registerUsed(annotSym)
196
197
197
198
/** Register a found (used) symbol */
198
- def registerUsed (sym : Symbol )(using Context ): Unit =
199
+ def registerUsed (sym : Symbol , name : Option [ Name ] )(using Context ): Unit =
199
200
if ! isConstructorOfSynth(sym) then
200
- usedInScope.top += sym -> sym.isAccessibleAsIdent
201
- usedDef += sym
201
+ usedInScope.top += ((sym, sym.isAccessibleAsIdent, name))
202
202
if sym.isConstructor && sym.exists then
203
- registerUsed(sym.owner) // constructor are "implicitly" imported with the class
203
+ registerUsed(sym.owner, None ) // constructor are "implicitly" imported with the class
204
204
205
205
/** Register a list of found (used) symbols */
206
206
def registerUsed (syms : Seq [Symbol ])(using Context ): Unit =
207
- usedInScope.top ++= syms.filterNot(isConstructorOfSynth).map(s => s -> s.isAccessibleAsIdent)
208
- usedDef ++= syms
207
+ usedInScope.top ++= syms.filterNot(isConstructorOfSynth).map(s => (s, s.isAccessibleAsIdent, None ))
209
208
210
209
/** Register an import */
211
210
def registerImport (imp : tpd.Import )(using Context ): Unit =
@@ -248,10 +247,10 @@ object CheckUnused:
248
247
// used imports in this scope
249
248
val imports = impInScope.pop().toSet
250
249
val kept = used.filter { t =>
251
- val (sym, isAccessible) = t
250
+ val (sym, isAccessible, optName ) = t
252
251
// keep the symbol for outer scope, if it matches **no** import
253
252
! imports.exists { imp =>
254
- sym.isInImport(imp, isAccessible) match
253
+ sym.isInImport(imp, isAccessible, optName ) match
255
254
case None => false
256
255
case Some (sel) =>
257
256
unusedImport -= sel
@@ -368,10 +367,10 @@ object CheckUnused:
368
367
}
369
368
370
369
/** Given an import and accessibility, return an option of selector that match import<->symbol */
371
- def isInImport (imp : tpd.Import , isAccessible : Boolean )(using Context ): Option [ImportSelector ] =
370
+ def isInImport (imp : tpd.Import , isAccessible : Boolean , symName : Option [ Name ] )(using Context ): Option [ImportSelector ] =
372
371
val tpd .Import (qual, sels) = imp
373
372
val qualHasSymbol = qual.tpe.member(sym.name).alternatives.map(_.symbol).contains(sym)
374
- def selector = sels.find(sel => sel.name.toTermName == sym.name || sel.name.toTypeName == sym.name)
373
+ def selector = sels.find(sel => ( sel.name.toTermName == sym.name || sel.name.toTypeName == sym.name) && symName.map(n => n.toTermName == sel.rename).getOrElse( true ) )
375
374
def wildcard = sels.find(sel => sel.isWildcard && ((sym.is(Given ) == sel.isGiven) || sym.is(Implicit )))
376
375
if qualHasSymbol && ! isAccessible && sym.exists then
377
376
selector.orElse(wildcard) // selector with name or wildcard (or given)
0 commit comments