scalacenter / scalafix

Refactoring and linting tool for Scala
https://scalacenter.github.io/scalafix/
BSD 3-Clause "New" or "Revised" License
828 stars 186 forks source link

RemoveUnused: detect unused function parameters in Scala 3 #1937

Open bjaglin opened 7 months ago

bjaglin commented 7 months ago

Despite the presence of -Wunused:params and the explicit mention of it in https://github.com/lampepfl/dotty/pull/16157, I did not manage to get diagnostics (nor warnings) for unused parameters with scala 3.4.0-RC2, so the feature is currently documented/tested as Scala2-only.

We probably need to report this upstream.

$ metap ./scalafix-tests/input/target/jvm-3.4.0-RC2/meta/META-INF/semanticdb/scalafix-tests/input/src/main/scala/test/removeUnused/RemoveUnusedParams.scala.semanticdb 
scalafix-tests/input/src/main/scala/test/removeUnused/RemoveUnusedParams.scala
------------------------------------------------------------------------------

Summary:
Schema => SemanticDB v4
Uri => scalafix-tests/input/src/main/scala/test/removeUnused/RemoveUnusedParams.scala
Text => empty
Language => Scala
Symbols => 11 entries
Occurrences => 28 entries

Symbols:
local0 => param unused: String
local1 => param unused: String
local2 => param used: String
local3 => param unused: Long
local4 => implicit param string: String
test/removeUnused/UnusedParams. => final object UnusedParams extends Object { self: UnusedParams.type => +5 decls }
test/removeUnused/UnusedParams.f. => val method fFunction1[String, Unit]
test/removeUnused/UnusedParams.ff. => val method ffFunction1[String, Unit]
test/removeUnused/UnusedParams.fs. => val method fsFunction2[String, Long, Unit]
test/removeUnused/UnusedParams.g(). => method g(x: Function1[String, Unit]): Unit
test/removeUnused/UnusedParams.g().(x) => param x: Function1[String, Unit]

Occurrences:
[3:8..3:12) => test/
[3:13..3:25) <= test/removeUnused/
[5:7..5:19) <= test/removeUnused/UnusedParams.
[6:6..6:7) <= test/removeUnused/UnusedParams.f.
[6:9..6:15) => scala/Predef.String#
[6:19..6:23) => scala/Unit#
[6:26..6:32) <= local0
[6:36..6:43) => scala/Predef.println(+1).
[7:6..7:8) <= test/removeUnused/UnusedParams.ff.
[7:12..7:18) <= local1
[7:20..7:26) => scala/Predef.String#
[7:31..7:38) => scala/Predef.println(+1).
[8:6..8:8) <= test/removeUnused/UnusedParams.fs.
[8:12..8:16) <= local2
[8:18..8:24) => scala/Predef.String#
[8:26..8:32) <= local3
[8:34..8:38) => scala/Long#
[8:43..8:50) => scala/Predef.println(+1).
[8:51..8:55) => local2
[9:6..9:7) <= test/removeUnused/UnusedParams.g().
[9:8..9:9) <= test/removeUnused/UnusedParams.g().(x)
[9:11..9:17) => scala/Predef.String#
[9:21..9:25) => scala/Unit#
[9:28..9:32) => scala/Unit#
[9:35..9:38) => scala/Predef.`???`().
[10:2..10:3) => test/removeUnused/UnusedParams.g().
[10:13..10:19) <= local4
[10:23..10:30) => scala/Predef.println(+1).

_Originally posted by @bjaglin in https://github.com/scalacenter/scalafix/pull/1728#discussion_r1477068397_

bjaglin commented 2 months ago

FTR, not fixed as of

[error] (expect2_13Target3_5_0-RC6 / Test / test) sbt.TestsFailedException: Tests unsuccessful
[error] (expect2_13Target3_3_4-RC1 / Test / test) sbt.TestsFailedException: Tests unsuccessful

(tested via https://github.com/scalacenter/scalafix/pull/1951)

tgodzik commented 2 months ago

Does it not produce warnings or are those warnings not in semanticdb?

bjaglin commented 2 months ago

@tgodzik no warning is emitted by the compiler, I guess it's just a missing feature

// UnusedParams.scala

import java.util.List

object UnusedParams {
  val f: String => Unit = unused => println("f")
  val ff = (unused: String) => println("f")
  val fs = (used: String, unused: Long) => println(used)
  def g(x: String => Unit): Unit = ???
  g{implicit string => println("g")}
}
➜  /tmp scala-cli compile --scala 2.13.14 -Wunused UnusedParams.scala
Compiling project (Scala 2.13.14, JVM (21))
[warn] ./UnusedParams.scala:1:1
[warn] Unused import
[warn] import java.util.List
[warn] ^^^^^^^^^^^^^^^^^^^^^
[warn] ./UnusedParams.scala:4:27
[warn] parameter unused in anonymous function is never used
[warn]   val f: String => Unit = unused => println("f")
[warn]                           ^^^^^^
[warn] ./UnusedParams.scala:5:13
[warn] parameter unused in anonymous function is never used
[warn]   val ff = (unused: String) => println("f")
[warn]             ^^^^^^^^^^^^^^
[warn] ./UnusedParams.scala:6:27
[warn] parameter unused in anonymous function is never used
[warn]   val fs = (used: String, unused: Long) => println(used)
[warn]                           ^^^^^^^^^^^^
[warn] ./UnusedParams.scala:8:14
[warn] parameter string in anonymous function is never used
[warn]   g{implicit string => println("g")}
[warn]              ^^^^^^
Compiled project (Scala 2.13.14, JVM (21))
➜  /tmp scala-cli compile --scala 3.4.2 -Wunused:all UnusedParams.scala
Compiling project (Scala 3.4.2, JVM (21))
[warn] ./UnusedParams.scala:1:18
[warn] unused import
[warn] import java.util.List
[warn]                  ^^^^
Compiled project (Scala 3.4.2, JVM (21))
bjaglin commented 2 months ago

Actually, it looks like an issue for that was recently filed: https://github.com/scala/scala3/issues/20951