Skip to content
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

Unused warning on scala 2.13.5 #50

Open
amumurst opened this issue Feb 24, 2021 · 9 comments
Open

Unused warning on scala 2.13.5 #50

amumurst opened this issue Feb 24, 2021 · 9 comments

Comments

@amumurst
Copy link

Given build.sbt

scalaVersion := "2.13.5"
addCompilerPlugin("com.olegpy" %% "better-monadic-for" % "0.3.1")
scalacOptions += "-Ywarn-unused"

And main

object Main extends App {
  for {
    implicit0(i: Int) <- Option(1)
  } yield println(i)
}

I get warning

[warn] /dev/foo/src/main/scala/Main.scala:3:23: local val i$implicit$1 in value $anonfun is never used
[warn]     implicit0(i: Int) <- Option(1)
[warn]                       ^
[warn] one warning found

I do not get this on 2.13.4.
It still works and can be passed as an implicit, its just a bad warning produced.

@mr-git
Copy link

mr-git commented Mar 1, 2021

I tried with https://github.com/sirthias/macrolizer
I modified the code to make sure that the value is required implicitly, like:

object Main extends App {
  macrolizer.show {
    for {
      implicit0(i: Int) <- Option(1)
    } yield p("i")
  }
  def p(prefix: String)(implicit i: Int): Unit =
    println(s"$prefix: $i")
}

generated expanded code for both versions:

[info]   scala.Option
[info]     .apply[Int](1)
[info]     .map[Unit](
[info]       (
[info]         (x$1: Int) =>
[info]           x$1 match {
[info]             case (i @ _) =>
[info]               implicit val i$implicit$1: scala.Int = i;
[info]               X.this.p("i")(i$implicit$1)
[info]           },
[info]       ),
[info]     )

The i$implicit$1 gets passed explicitly, and it seems that in 2.13.5 the validation rules were changed to warn about such implicitly explicit usage.

From Scala 2.13.5 release notes:

Add linting of unused context bounds (via -Wunused:synthetics or -Wunused:params) (#9346) — thank you @som-snytt!

@oleg-py
Copy link
Owner

oleg-py commented Mar 1, 2021

Yeah I'd have to look for a new workaround for that warning. The linter has always produced bogus warnings in that scenario, but I was able to silence it using a synthetic flag previously.

Given that dotty is around the corner and it's gonna break all plugins and such anyways I'm not going to look deeply into that for now. Since plugin consistently uses that $implicit$ part in a val name, my personal workaround for now is to use Scala's warning suppression:

scalacOptions += "-Wconf:msg=\\$implicit\\$:s"

@som-snytt
Copy link

Warning for synthetic param is under -Wunused:synthetics. It's not enabled under -Xlint:unused.

The buffet menu is -Wunused:help. Also depending on how a macro expands, -Wmacros:after might help.

@mr-git
Copy link

mr-git commented Mar 1, 2021

-Wmacros:after fails in my case, but "-Wconf:msg=\\$implicit\\$:s" works like a charm.
I am using sbt-scalac-opts-plugin, with which "-Wunused:params" gets added and triggers (according to changes in Scala 2.13.5).

@som-snytt
Copy link

I see it can be selectively disabled (if your build.sbt is simple, I guess):

➜  skala -Wunused:params -Wunused:-synthetics
Welcome to Scala 2.13.5-20210301-002240-d4a711b (OpenJDK 64-Bit Server VM, Java 15).
Type in expressions for evaluation. Or try :help.

scala> def f[A: Ordered] = 42
def f[A](implicit evidence$1: Ordered[A]): Int

scala>

I'm glad -Wconf serves people well. I'm almost due for my -Wconf refresher course, I got behind during the pandemic.

@mr-git
Copy link

mr-git commented Mar 1, 2021

@som-snytt and @oleg-py, thank you!

@mr-git
Copy link

mr-git commented Mar 1, 2021

as I understood, usage of -Wunused:-synthetics could disable check for all unused context bounds too, thus "-Wconf:msg=\\$implicit\\$:s" looks to be safer fine-grained workaround.

@oleg-py
Copy link
Owner

oleg-py commented Mar 2, 2021

The i$implicit$1 gets passed explicitly, and it seems that in 2.13.5 the validation rules were changed to warn about such implicitly explicit usage.

Oh by the way, bm4 doesn't do explicit implicits itself. Macros and implicit resolution run during typer phase, and, afaik, the unused lint does as well. My speculation is that they aren't deterministically ordered between themselves, causing warnings before the implicits are fully resolved to be needed.

@som-snytt
Copy link

The lint is done at the end of typer; during typer, trees are typechecked both before and after macro expansion, and both typechecks will do implicit resolution as needed.

The lint looks at either or both of the unexpanded and expanded trees, depending on -Wmacros. The missing mode, however, is to let only the unexpanded tree (which the user wrote) introduce symbols to check, but let either tree mark them used.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants