Skip to content

False positive warning: unused import with certain combination of generics #22971

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
OndrejSpanel opened this issue Apr 11, 2025 · 1 comment · May be fixed by #22982
Open

False positive warning: unused import with certain combination of generics #22971

OndrejSpanel opened this issue Apr 11, 2025 · 1 comment · May be fixed by #22982
Assignees
Labels
area:linting Linting warnings enabled with -W or -Xlint itype:bug

Comments

@OndrejSpanel
Copy link
Member

OndrejSpanel commented Apr 11, 2025

Compiler version

3.7.0-RC1
3.7.0-RC2

Minimized code

Compile with -Wunused:imports:

trait Base
class Class extends Base

abstract class Entity[T: GetType]

class Thing extends Entity[Class]

trait GetType[T]

object GetType {
  implicit object GetTypeClass extends GetType[Class]
}
object Main {
  def main(args: Array[String]): Unit = {
    import GetType.*
    val e = GetTypeClass
  }
}

Output

[warn] 15 |    import GetType.*
[warn]    |                   ^
[warn]    |                   unused import

Expectation

The code does not compile without the import, the warning should not be printed.

Note

The warning goes away when you remove the line class Thing extends Entity[Class].

@OndrejSpanel OndrejSpanel added itype:bug stat:needs triage Every issue needs to have an "area" and "itype" label labels Apr 11, 2025
@som-snytt som-snytt self-assigned this Apr 11, 2025
@som-snytt som-snytt added area:linting Linting warnings enabled with -W or -Xlint and removed stat:needs triage Every issue needs to have an "area" and "itype" label labels Apr 11, 2025
@som-snytt
Copy link
Contributor

som-snytt commented Apr 11, 2025

This is due to caching the resolution of GetType.GetTypeClass, which appears as identical Ident trees in the parent of Thing and in the RHS of e.

From the superclass context of Thing, it incorrectly cached at an outer context, where the lookup from e found it as a definition at higher precedence than the import.

A couple of notes to self or reminders:

The trees don't distinguish whether the ident is due to implicit search or import. The comment at typedIdent is false, because the elidable prefix does not result in a Select. That is, I'd expect the RHS of e to be a typed selection.

Scala 2 certainly transforms to a select:

Select(Ident(p.GetType), TermName("GetTypeClass"))

or -Yprint-trees:format

          ValDef( // val e: p.GetType[p.Class]
            0
            "e"
            <tpt> // tree.tpe=p.GetType[p.Class]
            "GetType"."GetTypeClass" // implicit val GetTypeClass: p.GetType[p.Class] in object GetType, tree.tpe=p.GetType[p.Class]
          )

This doesn't matter for Scala 2 -Wunused:imports because the typer records the imports it used for lookups.

Removing the loopOverPrefixes doesn't break any tests. Either that progressed elsewhere or a better test is needed. (I think I restored that code at some point last year, but I don't have commit history to see why.) (Edit: https://github.com/scala/scala3/pull/22751/files)

@som-snytt som-snytt linked a pull request Apr 11, 2025 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:linting Linting warnings enabled with -W or -Xlint itype:bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants