@@ -10,6 +10,7 @@ import dotty.tools.dotc.ast.untpd.ImportSelector
10
10
import dotty .tools .dotc .config .ScalaSettings
11
11
import dotty .tools .dotc .core .Contexts .*
12
12
import dotty .tools .dotc .core .Decorators .{em , i }
13
+ import dotty .tools .dotc .core .Denotations .SingleDenotation
13
14
import dotty .tools .dotc .core .Flags .*
14
15
import dotty .tools .dotc .core .Phases .Phase
15
16
import dotty .tools .dotc .core .StdNames
@@ -409,13 +410,18 @@ object CheckUnused:
409
410
* as the same element can be imported with different renaming
410
411
*/
411
412
def registerUsed (sym : Symbol , name : Option [Name ], isDerived : Boolean = false )(using Context ): Unit =
412
- if ! isConstructorOfSynth(sym) && ! doNotRegister(sym) then
413
- if sym.isConstructor && sym.exists then
413
+ if sym.exists && ! isConstructorOfSynth(sym) && ! doNotRegister(sym) then
414
+ if sym.isConstructor then
414
415
registerUsed(sym.owner, None ) // constructor are "implicitly" imported with the class
415
416
else
416
- usedInScope.top += ((sym, sym.isAccessibleAsIdent, name, isDerived))
417
- usedInScope.top += ((sym.companionModule, sym.isAccessibleAsIdent, name, isDerived))
418
- usedInScope.top += ((sym.companionClass, sym.isAccessibleAsIdent, name, isDerived))
417
+ val accessibleAsIdent = sym.isAccessibleAsIdent
418
+ def addIfExists (sym : Symbol ): Unit =
419
+ if sym.exists then
420
+ usedDef += sym
421
+ usedInScope.top += ((sym, accessibleAsIdent, name, isDerived))
422
+ addIfExists(sym)
423
+ addIfExists(sym.companionModule)
424
+ addIfExists(sym.companionClass)
419
425
if sym.sourcePos.exists then
420
426
for n <- name do
421
427
usedInPosition.getOrElseUpdate(n, MutSet .empty) += sym
@@ -508,8 +514,6 @@ object CheckUnused:
508
514
// we keep the symbols not referencing an import in this scope
509
515
// as it can be the only reference to an outer import
510
516
usedInScope.top ++= kept
511
- // register usage in this scope for other warnings at the end of the phase
512
- usedDef ++= used.map(_._1)
513
517
// retrieve previous scope type
514
518
currScopeType.pop
515
519
end popScope
@@ -685,42 +689,54 @@ object CheckUnused:
685
689
extension (sym : Symbol )
686
690
/** is accessible without import in current context */
687
691
private def isAccessibleAsIdent (using Context ): Boolean =
688
- sym.exists &&
689
- ctx.outersIterator.exists{ c =>
690
- c.owner == sym.owner
691
- || sym.owner.isClass && c.owner.isClass
692
- && c.owner.thisType.baseClasses.contains(sym.owner)
693
- && c.owner.thisType.member(sym.name).alternatives.contains(sym)
694
- }
692
+ ctx.outersIterator.exists{ c =>
693
+ c.owner == sym.owner
694
+ || sym.owner.isClass && c.owner.isClass
695
+ && c.owner.thisType.baseClasses.contains(sym.owner)
696
+ && c.owner.thisType.member(sym.name).alternatives.contains(sym)
697
+ }
695
698
696
699
/** Given an import and accessibility, return selector that matches import<->symbol */
697
700
private def isInImport (imp : tpd.Import , isAccessible : Boolean , altName : Option [Name ], isDerived : Boolean )(using Context ): Option [ImportSelector ] =
701
+ assert(sym.exists)
702
+
698
703
val tpd .Import (qual, sels) = imp
699
704
val qualTpe = qual.tpe
700
705
val dealiasedSym = sym.dealias
701
- val simpleSelections = qualTpe.member(sym.name).alternatives
702
- val selectionsToDealias = sels.flatMap(sel =>
703
- qualTpe.member(sel.name.toTypeName).alternatives
704
- ::: qualTpe.member(sel.name.toTermName).alternatives)
705
- def qualHasSymbol = simpleSelections.map(_.symbol).contains(sym) || (simpleSelections ::: selectionsToDealias).map(_.symbol).map(_.dealias).contains(dealiasedSym)
706
- def selector = sels.find(sel => (sel.name.toTermName == sym.name || sel.name.toTypeName == sym.name) && altName.map(n => n.toTermName == sel.rename).getOrElse(true ))
707
- def dealiasedSelector =
706
+
707
+ val selectionsToDealias : List [SingleDenotation ] =
708
+ val typeSelections = sels.flatMap(n => qualTpe.member(n.name.toTypeName).alternatives)
709
+ val termSelections = sels.flatMap(n => qualTpe.member(n.name.toTermName).alternatives)
710
+ typeSelections ::: termSelections
711
+
712
+ val qualHasSymbol : Boolean =
713
+ val simpleSelections = qualTpe.member(sym.name).alternatives
714
+ simpleSelections.exists(d => d.symbol == sym || d.symbol.dealias == dealiasedSym)
715
+ || selectionsToDealias.exists(d => d.symbol.dealias == dealiasedSym)
716
+
717
+ def selector : Option [ImportSelector ] =
718
+ sels.find(sel => sym.name.toTermName == sel.name && altName.forall(n => n.toTermName == sel.rename))
719
+
720
+ def dealiasedSelector : Option [ImportSelector ] =
708
721
if isDerived then
709
- sels.flatMap(sel => selectionsToDealias.map(m => (sel, m.symbol))).collect {
722
+ sels.flatMap(sel => selectionsToDealias.map(m => (sel, m.symbol))).collectFirst {
710
723
case (sel, sym) if sym.dealias == dealiasedSym => sel
711
- }.headOption
724
+ }
712
725
else None
713
- def givenSelector = if sym.is(Given ) || sym.is(Implicit )
714
- then sels.filter(sel => sel.isGiven && ! sel.bound.isEmpty).find(sel => sel.boundTpe =:= sym.info)
726
+
727
+ def givenSelector : Option [ImportSelector ] =
728
+ if sym.is(Given ) || sym.is(Implicit ) then
729
+ sels.filter(sel => sel.isGiven && ! sel.bound.isEmpty).find(sel => sel.boundTpe =:= sym.info)
715
730
else None
716
- def wildcard = sels.find(sel => sel.isWildcard && ((sym.is(Given ) == sel.isGiven && sel.bound.isEmpty) || sym.is(Implicit )))
717
- if sym.exists && qualHasSymbol && (! isAccessible || sym.isRenamedSymbol(altName)) then
731
+
732
+ def wildcard : Option [ImportSelector ] =
733
+ sels.find(sel => sel.isWildcard && ((sym.is(Given ) == sel.isGiven && sel.bound.isEmpty) || sym.is(Implicit )))
734
+
735
+ if qualHasSymbol && (! isAccessible || altName.exists(_.toSimpleName != sym.name.toSimpleName)) then
718
736
selector.orElse(dealiasedSelector).orElse(givenSelector).orElse(wildcard) // selector with name or wildcard (or given)
719
737
else
720
738
None
721
-
722
- private def isRenamedSymbol (symNameInScope : Option [Name ])(using Context ) =
723
- sym.name != nme.NO_NAME && symNameInScope.exists(_.toSimpleName != sym.name.toSimpleName)
739
+ end isInImport
724
740
725
741
private def dealias (using Context ): Symbol =
726
742
if sym.isType && sym.asType.denot.isAliasType then
0 commit comments