scalafix icon indicating copy to clipboard operation
scalafix copied to clipboard

RemoveUnused skips some unused locals

Open bjaglin opened this issue 5 years ago • 0 comments
trafficstars

Scala 2.13.2 / 2.12.11 / 2.11.12 SemanticDB 4.3.13 Scalafix 0.9.16

It looks like scalac is running dead code elimination early-on, so -Wunused / -Ywarn-unused does not raise warnings for some unused locals. https://github.com/scalacenter/scalafix/blob/v0.9.16/scalafix-tests/input/src/main/scala/test/RemoveUnusedTerms.scala does not cover this at the moment.

I thought I could disable this via -opt:l:none on 2.12+ (and maybe recommend/enforce it as a mandatory scalacOptions in RemoveUnused, for the rule to be exhaustive), but it does not seem to change anything. There might be another scalac flag to control that, or maybe this could be reported against the compiler project? Given that the behavior is consistent accross 2.11, 2.12 and 2.13, I doubt this can change though

bjaglin@x1:/tmp$ cat RemoveUnused.scala 
object RemoveUnused {
  def foo: Int = {
    val dce = 1 // should be picked up by -Wunused/RemoveUnused but is stripped early-on by the compiler
    12
  }
  def bar: Int = {
    val unused = 1
    println("bar")
    12
  }
}
bjaglin@x1:/tmp$ cs launch -J -Dscala.usejavacp=true org.scalameta:metac_2.13.2:4.3.13 -- -Wunused -opt:l:none -Xprint:typer RemoveUnused.scala
RemoveUnused.scala:7: warning: local val unused in method bar is never used
    val unused = 1
        ^
[[syntax trees at end of                     typer]] // RemoveUnused.scala
package <empty> {
  object RemoveUnused extends scala.AnyRef {
    def <init>(): RemoveUnused.type = {
      RemoveUnused.super.<init>();
      ()
    };
    def foo: Int = 12;
    def bar: Int = {
      val unused: Int = 1;
      scala.Predef.println("bar");
      12
    }
  }
}

1 warning
bjaglin@x1:/tmp$ metap META-INF/semanticdb/RemoveUnused.scala.semanticdb | tail
[1:6..1:9) <= _empty_/RemoveUnused.foo().
[1:11..1:14) => scala/Int#
[2:8..2:11) <= local0
[5:6..5:9) <= _empty_/RemoveUnused.bar().
[5:11..5:14) => scala/Int#
[6:8..6:14) <= local1
[7:4..7:11) => scala/Predef.println(+1).

Diagnostics:
[6:4..6:18) [warning] local val unused in method bar is never used

bjaglin avatar Jun 01 '20 13:06 bjaglin