Skip to content

Incorrect unused import warnings in some cases - private definitions escaping their scope #23347

Open
@jdrphillips

Description

@jdrphillips

Compiler version

3.7.1

Minimized code

object USED {
  case class A(value: Int)
}

object UNUSED {
  // In reality UNUSED would contain several other necessary members!
  private type A = USED.A
}

object Test {
  import USED.*
  import UNUSED.*

  def foo(a: A): Int = a.value

}

Output

[warn] -- [E198] Unused Symbol Warning: File.scala:92:14 
[warn] 92 |  import USED.*
[warn]    |              ^
[warn]    |              unused import

Expectation

[warn] -- [E198] Unused Symbol Warning: File.scala:93:16 
[warn] 93 |  import UNUSED.*
[warn]    |                ^
[warn]    |                unused import

Some notes:

  • This only happens if UNUSED.A is an alias for USED.A, it doesn't seem to happen in any other case, even if they are otherwise identical case classes
  • It only seems to happen for types, not values
  • private[scope] doesn't seem to affect the bug
  • importing in the other order patches the issue as expected
  • import USED.A explicitly fixes the issue
  • import UNUSED.{everything except A} fixes the issue (as you would expect)

This is quite a common pattern in our projects where we have privately aliased code in their original packages in order to skip painful re-imports in hundreds of files when moving code around to other packages.

This is quite unfortunate as none of the patches where it works are really applicable in general. If we upgraded we'd spend so much time unpicking imports and fighting automatic linting

Bug not observed on 3.7.0

(EDIT: Fixed typo in the script Test1 => USED)

Metadata

Metadata

Assignees

Labels

area:lintingLinting warnings enabled with -W or -Xlintitype:bug

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions