Skip to content

Commit 483b1e8

Browse files
authored
Fix -Wunused:import registering constructor ("<init>") instead of its owner (also fix false positive for enum) (#16661)
This solves the issue #16650. The issue is that `member(sym.name)` failed to resolve when a type contains multiple identical name. Here the `dotty.tools.dotc.util` package contains multiple "<init>" (constructor), so `member` fail to resolve the name The solution is to register the owner of the contructor instead of the constructor itself. :warning: I couldn't create a test where this appends, I tested it by `publishLocal` and testing the code in a different project with this code from #16650 (also didn't check on the metals build): ```scala //> using lib "org.scala-lang::scala3-compiler:3.3.0-RC1-bin-20230109-f56089b-NIGHTLY" //> using scala "3.3.0-RC1-bin-20230109-f56089b-NIGHTLY" //> using option "-Wunused:all" import dotty.tools.dotc.util.LinearSet @main def run = val a = 123 println("Hello!") ``` ```bash sbt> run [info] compiling 1 Scala source to .../target/scala-3.3.0-RC1-bin-SNAPSHOT/classes ... [warn] -- Warning: ..../src/main/scala/Main.scala:5:29 [warn] 5 |import dotty.tools.dotc.util.LinearSet [warn] | ^^^^^^^^^ [warn] | unused import [warn] -- Warning:.../src/main/scala/Main.scala:10:6 [warn] 10 | val a = 123 [warn] | ^ [warn] | unused local definition [warn] two warnings found [info] running run Hello! ``` ### EDIT Also add a related fix for import generated by enum (false positive)
2 parents afeaf6e + fa1d2bb commit 483b1e8

File tree

3 files changed

+25
-3
lines changed

3 files changed

+25
-3
lines changed

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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import dotty.tools.dotc.core.Definitions
2727
import dotty.tools.dotc.core.Types.ConstantType
2828
import dotty.tools.dotc.core.NameKinds.WildcardParamName
2929
import dotty.tools.dotc.core.Types.TermRef
30+
import dotty.tools.dotc.core.Types.NameFilter
3031

3132

3233

@@ -326,9 +327,12 @@ object CheckUnused:
326327
*/
327328
def registerUsed(sym: Symbol, name: Option[Name])(using Context): Unit =
328329
if !isConstructorOfSynth(sym) && !doNotRegister(sym) then
329-
usedInScope.top += ((sym, sym.isAccessibleAsIdent, name))
330330
if sym.isConstructor && sym.exists then
331331
registerUsed(sym.owner, None) // constructor are "implicitly" imported with the class
332+
else
333+
usedInScope.top += ((sym, sym.isAccessibleAsIdent, name))
334+
usedInScope.top += ((sym.companionModule, sym.isAccessibleAsIdent, name))
335+
usedInScope.top += ((sym.companionClass, sym.isAccessibleAsIdent, name))
332336

333337
/** Register a symbol that should be ignored */
334338
def addIgnoredUsage(sym: Symbol)(using Context): Unit =
@@ -345,7 +349,7 @@ object CheckUnused:
345349

346350
/** Register an import */
347351
def registerImport(imp: tpd.Import)(using Context): Unit =
348-
if !tpd.languageImport(imp.expr).nonEmpty then
352+
if !tpd.languageImport(imp.expr).nonEmpty && !imp.isGeneratedByEnum then
349353
impInScope.top += imp
350354
unusedImport ++= imp.selectors.filter { s =>
351355
!shouldSelectorBeReported(imp, s) && !isImportExclusion(s)
@@ -589,6 +593,10 @@ object CheckUnused:
589593
!isSyntheticMainParam(sym) &&
590594
!sym.shouldNotReportParamOwner
591595

596+
extension (imp: tpd.Import)
597+
/** Enum generate an import for its cases (but outside them), which should be ignored */
598+
def isGeneratedByEnum(using Context): Boolean =
599+
imp.symbol.exists && imp.symbol.owner.is(Flags.Enum, butNot = Flags.Case)
592600

593601
extension (thisName: Name)
594602
private def isWildcard: Boolean =

tests/neg-custom-args/fatal-warnings/i15503a.scala

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,4 +250,9 @@ package foo.testing.rename.imports:
250250
package foo.testing.imports.precedence:
251251
import scala.collection.immutable.{BitSet => _, _} // error
252252
import scala.collection.immutable.BitSet // OK
253-
def t = BitSet.empty
253+
def t = BitSet.empty
254+
255+
package foo.test.enums:
256+
enum A: // OK
257+
case B extends A // OK
258+
case C extends A // OK

tests/neg-custom-args/fatal-warnings/i15503i.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,12 @@ package foo.test.scala.annotation:
6565
@unused private def c = 3 // OK
6666

6767
def other = b
68+
69+
package foo.test.companionprivate:
70+
class A:
71+
import A.b // OK
72+
def a = b // OK
73+
74+
object A:
75+
private def b = c // OK
76+
def c = List(1,2,3) // OK

0 commit comments

Comments
 (0)