scala3 icon indicating copy to clipboard operation
scala3 copied to clipboard

false-positive "unused import" warning when importing givens defined in common trait for several objects

Open danielleontiev opened this issue 1 year ago • 5 comments

Compiler version

Scala 3.3.1, JVM 17

Minimized code

bug.sc
//> using scala 3.3.1
//> using options "-Wunused:imports"

trait Schema[A]

case class Foo()
case class Bar()

trait SchemaGenerator[A] {
  given Schema[A] = new Schema[A]{}
}

object FooCodec extends SchemaGenerator[Foo]
object BarCodec extends SchemaGenerator[Bar]

def summonSchemas(using Schema[Foo], Schema[Bar]) = ()

import FooCodec.given
import BarCodec.given

summonSchemas

Run code with

scala-cli run bug.sc

Output

[warn] ./bug.sc:18:17
[warn] unused import
[warn] import FooCodec.given
[warn]                 ^^^^^

Expectation

Warning should not be reported

Comment

It seems that some sort of names collision occurs due to the common SchemaGenerator trait because defining givens explicitly works as expected

//> using scala 3.3.1
//> using options "-Wunused:imports"

trait Schema[A]

case class Foo()
case class Bar()

object FooCodec {
  given Schema[Foo] = new Schema[Foo] {}
}
object BarCodec {
  given Schema[Bar] = new Schema[Bar] {}
}

def summonSchemas(using Schema[Foo], Schema[Bar]) = ()

import FooCodec.given
import BarCodec.given

summonSchemas

compiles without warning message

danielleontiev avatar Feb 09 '24 12:02 danielleontiev

Reproduced on the main branch, as well as with 3.4.0-RC4

Minimised code in non-script format (to be passed straight to the compiler)

trait Schema[A]

case class Foo()
case class Bar()

trait SchemaGenerator[A] {
  given Schema[A] = new Schema[A]{}
}

object FooCodec extends SchemaGenerator[Foo]
object BarCodec extends SchemaGenerator[Bar]

def summonSchemas(using Schema[Foo], Schema[Bar]) = ()

@main def main = {
  import FooCodec.given
  import BarCodec.given
  summonSchemas
}

output:

scalac -d . -Wunused:imports repro.scala
-- Warning: repro.scala:17:18 --------------------------------------------------
17 |  import BarCodec.given
   |                  ^^^^^
   |                  unused import
1 warning found

Gedochao avatar Feb 09 '24 14:02 Gedochao

This error is very annoying. It basically prevents us from using given imports with -Wunused:imports so we have to rely on mixing in traits.

grzegorz-bielski avatar Apr 18 '24 09:04 grzegorz-bielski

@grzegorz-bielski -Wunused:strict-no-implicit-warn weakens the check to avoid false positives, as a workaround.

➜  snips ~/projects/dotty/bin/scalac -Wunused:all -d /tmp/sandbox i19657.scala
-- Warning: i19657.scala:17:18 -----------------------------------------------------------------------------------------
17 |  import BarCodec.given
   |                  ^^^^^
   |                  unused import
-- Warning: i19657.scala:18:34 -----------------------------------------------------------------------------------------
18 |  import scala.collection.mutable.*
   |                                  ^
   |                                  unused import
2 warnings found
➜  snips ~/projects/dotty/bin/scalac -Wunused:all -Wunused:strict-no-implicit-warn -d /tmp/sandbox i19657.scala
➜  snips

It seems to avoid warning about wildcard import selectors which may reference any implicit.

so we have to rely on mixing in traits

I don't think optional warnings (especially this one) are intended to invite architectural rewrites.

som-snytt avatar Apr 18 '24 16:04 som-snytt

@som-snytt I didn't know about -Wunused:strict-no-implicit-warn. It helped, thx!

I don't think optional warnings (especially this one) are intended to invite architectural rewrites.

My thoughts exactly! However, this was the only workaround I could think of at the time that did not involve the removal of -Wunused:imports.

grzegorz-bielski avatar Apr 18 '24 18:04 grzegorz-bielski

Waiting on https://github.com/scala/scala3/pull/20321 which obviates my working branch.

som-snytt avatar May 03 '24 15:05 som-snytt