@@ -10,6 +10,7 @@ import dotty.tools.dotc.ast.untpd.ImportSelector
1010import dotty .tools .dotc .config .ScalaSettings
1111import dotty .tools .dotc .core .Contexts .*
1212import dotty .tools .dotc .core .Decorators .{em , i }
13+ import dotty .tools .dotc .core .Denotations .SingleDenotation
1314import dotty .tools .dotc .core .Flags .*
1415import dotty .tools .dotc .core .Phases .Phase
1516import dotty .tools .dotc .core .StdNames
@@ -409,13 +410,18 @@ object CheckUnused:
409410 * as the same element can be imported with different renaming
410411 */
411412 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
414415 registerUsed(sym.owner, None ) // constructor are "implicitly" imported with the class
415416 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)
419425 if sym.sourcePos.exists then
420426 for n <- name do
421427 usedInPosition.getOrElseUpdate(n, MutSet .empty) += sym
@@ -508,8 +514,6 @@ object CheckUnused:
508514 // we keep the symbols not referencing an import in this scope
509515 // as it can be the only reference to an outer import
510516 usedInScope.top ++= kept
511- // register usage in this scope for other warnings at the end of the phase
512- usedDef ++= used.map(_._1)
513517 // retrieve previous scope type
514518 currScopeType.pop
515519 end popScope
@@ -685,42 +689,54 @@ object CheckUnused:
685689 extension (sym : Symbol )
686690 /** is accessible without import in current context */
687691 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+ }
695698
696699 /** Given an import and accessibility, return selector that matches import<->symbol */
697700 private def isInImport (imp : tpd.Import , isAccessible : Boolean , altName : Option [Name ], isDerived : Boolean )(using Context ): Option [ImportSelector ] =
701+ assert(sym.exists)
702+
698703 val tpd .Import (qual, sels) = imp
699704 val qualTpe = qual.tpe
700705 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 ] =
708721 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 {
710723 case (sel, sym) if sym.dealias == dealiasedSym => sel
711- }.headOption
724+ }
712725 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)
715730 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
718736 selector.orElse(dealiasedSelector).orElse(givenSelector).orElse(wildcard) // selector with name or wildcard (or given)
719737 else
720738 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
724740
725741 private def dealias (using Context ): Symbol =
726742 if sym.isType && sym.asType.denot.isAliasType then
0 commit comments