diff --git a/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala b/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala index 5549e5c48d45..29af47ce844e 100644 --- a/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala +++ b/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala @@ -27,6 +27,7 @@ import dotty.tools.dotc.core.Definitions import dotty.tools.dotc.core.Types.ConstantType import dotty.tools.dotc.core.NameKinds.WildcardParamName import dotty.tools.dotc.core.Types.TermRef +import dotty.tools.dotc.core.Types.NameFilter @@ -326,9 +327,12 @@ object CheckUnused: */ def registerUsed(sym: Symbol, name: Option[Name])(using Context): Unit = if !isConstructorOfSynth(sym) && !doNotRegister(sym) then - usedInScope.top += ((sym, sym.isAccessibleAsIdent, name)) if sym.isConstructor && sym.exists then registerUsed(sym.owner, None) // constructor are "implicitly" imported with the class + else + usedInScope.top += ((sym, sym.isAccessibleAsIdent, name)) + usedInScope.top += ((sym.companionModule, sym.isAccessibleAsIdent, name)) + usedInScope.top += ((sym.companionClass, sym.isAccessibleAsIdent, name)) /** Register a symbol that should be ignored */ def addIgnoredUsage(sym: Symbol)(using Context): Unit = @@ -345,7 +349,7 @@ object CheckUnused: /** Register an import */ def registerImport(imp: tpd.Import)(using Context): Unit = - if !tpd.languageImport(imp.expr).nonEmpty then + if !tpd.languageImport(imp.expr).nonEmpty && !imp.isGeneratedByEnum then impInScope.top += imp unusedImport ++= imp.selectors.filter { s => !shouldSelectorBeReported(imp, s) && !isImportExclusion(s) @@ -589,6 +593,10 @@ object CheckUnused: !isSyntheticMainParam(sym) && !sym.shouldNotReportParamOwner + extension (imp: tpd.Import) + /** Enum generate an import for its cases (but outside them), which should be ignored */ + def isGeneratedByEnum(using Context): Boolean = + imp.symbol.exists && imp.symbol.owner.is(Flags.Enum, butNot = Flags.Case) extension (thisName: Name) private def isWildcard: Boolean = diff --git a/tests/neg-custom-args/fatal-warnings/i15503a.scala b/tests/neg-custom-args/fatal-warnings/i15503a.scala index 28482c7addde..c626fd88085e 100644 --- a/tests/neg-custom-args/fatal-warnings/i15503a.scala +++ b/tests/neg-custom-args/fatal-warnings/i15503a.scala @@ -250,4 +250,9 @@ package foo.testing.rename.imports: package foo.testing.imports.precedence: import scala.collection.immutable.{BitSet => _, _} // error import scala.collection.immutable.BitSet // OK - def t = BitSet.empty \ No newline at end of file + def t = BitSet.empty + +package foo.test.enums: + enum A: // OK + case B extends A // OK + case C extends A // OK \ No newline at end of file diff --git a/tests/neg-custom-args/fatal-warnings/i15503i.scala b/tests/neg-custom-args/fatal-warnings/i15503i.scala index cecb79b70a34..60a1ad4741fd 100644 --- a/tests/neg-custom-args/fatal-warnings/i15503i.scala +++ b/tests/neg-custom-args/fatal-warnings/i15503i.scala @@ -65,3 +65,12 @@ package foo.test.scala.annotation: @unused private def c = 3 // OK def other = b + +package foo.test.companionprivate: + class A: + import A.b // OK + def a = b // OK + + object A: + private def b = c // OK + def c = List(1,2,3) // OK \ No newline at end of file