Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bin/test-release.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ version=$1
scala212=2.12.20
scala213=2.13.16
scala3LTS=3.3.5
scala3Next=3.6.4
scala3Next=3.7.0

cs resolve \
ch.epfl.scala:scalafix-interfaces:$version \
Expand Down
1 change: 1 addition & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ lazy val properties = project
props.put("scala33", scala33)
props.put("scala35", scala35)
props.put("scala36", scala36)
props.put("scala37", scala37)
props.put("scala3LTS", scala3LTS)
props.put("scala3Next", scala3Next)
val out =
Expand Down
30 changes: 17 additions & 13 deletions docs/rules/RemoveUnused.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,10 @@ case class AB(a: Int, b: String)
object Main {
val example = AB(42, "lol")
example match {
case AB(a, b) => println("Not used")
case AB(foo, bar) => println("Not used")
}
example match {
case AB(a, b) => println("Not used, but canonical names")
}
}
// after
Expand All @@ -81,16 +84,16 @@ object Main {
example match {
case AB(_, _) => println("Not used")
}
example match {
case AB(a, b) => println("Not used, but canonical names")
}
}
```

On Scala 3, `-Wunused:unsafe-warn-patvars` is required.

On Scala 2.13.15+, canonical patterns (vars with the same names as the
attributes) do not trigger unused warnings, so the input above will not
be rewritten. See https://github.com/scala/bug/issues/13035.
Comment on lines -89 to -91
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since this is now the default behavior on latest 2.13.x and 3.x, I am removing the "exception" note and documenting it via an example, as it can be surprising

On Scala 3, an additional `-Wunused:unsafe-warn-patvars` option is required
until Scala 3.7.0.

### Remove unused function parameters (Scala 2 only)
### Remove unused function parameters

```scala
// before
Expand All @@ -103,6 +106,8 @@ object Main {
}
```

On Scala 3, this is only supported for 3.7.0+.

## Formatting

> This rule does a best-effort at preserving original formatting. In some cases,
Expand Down Expand Up @@ -176,8 +181,7 @@ $ scala3 -W
- nowarn,
- all,
- imports :
Warn if an import selector is not referenced.
NOTE : overrided by -Wunused:strict-no-implicit-warn,
Warn if an import selector is not referenced.,
- privates :
Warn if a private member is unused,
- locals :
Expand All @@ -188,13 +192,13 @@ $ scala3 -W
Warn if an implicit parameter is unused,
- params :
Enable -Wunused:explicits,implicits,
- patvars :
Warn if a variable bound in a pattern is unused,
- linted :
Enable -Wunused:imports,privates,locals,implicits,
- strict-no-implicit-warn :
Same as -Wunused:import, only for imports of explicit named members.
NOTE : This overrides -Wunused:imports and NOT set by -Wunused:all,
NOTE : This overrides -Wunused:imports and NOT set by -Wunused:all,
- unsafe-warn-patvars :
(UNSAFE) Warn if a variable bound in a pattern is unused.
This warning can generate false positive, as warning cannot be
suppressed yet.
Deprecated alias for `patvars`
```
5 changes: 3 additions & 2 deletions project/Dependencies.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ import sbt._

object Dependencies {
val scala212 = sys.props.getOrElse("scala212.nightly", "2.12.20")
val scala213 = sys.props.getOrElse("scala213.nightly", "2.13.16")
val scala213 = sys.props.getOrElse("scala213.nightly", "2.13.16") // remove 2.13.14 hack in RuleSuite when bumping
val scala33 = "3.3.5"
val scala35 = "3.5.2"
val scala36 = "3.6.4"
val scala37 = "3.7.0"
val scala3LTS = scala33
val scala3Next = sys.props.getOrElse("scala3.nightly", scala36)
val scala3Next = sys.props.getOrElse("scala3.nightly", scala37)

val bijectionCoreV = "0.9.8"
val collectionCompatV = "2.13.0"
Expand Down
3 changes: 2 additions & 1 deletion project/Mima.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ object Mima {
ProblemFilters.exclude[DirectMissingMethodProblem]("scalafix.v0.Signature#Self.syntax"),
ProblemFilters.exclude[ReversedMissingMethodProblem]("scalafix.interfaces.Scalafix.scala33"),
ProblemFilters.exclude[ReversedMissingMethodProblem]("scalafix.interfaces.Scalafix.scala35"),
ProblemFilters.exclude[ReversedMissingMethodProblem]("scalafix.interfaces.Scalafix.scala36")
ProblemFilters.exclude[ReversedMissingMethodProblem]("scalafix.interfaces.Scalafix.scala36"),
ProblemFilters.exclude[ReversedMissingMethodProblem]("scalafix.interfaces.Scalafix.scala37")
)
}
}
14 changes: 10 additions & 4 deletions project/ScalafixBuild.scala
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ object ScalafixBuild extends AutoPlugin with GhpagesKeys {
val jdk = System.getProperty("java.specification.version").toDouble
val scala3Versions =
// Scala 3.5 will never support JDK 23
if (jdk >= 23) Seq(scala33, scala36)
else Seq(scala33, scala35, scala36)
if (jdk >= 23) Seq(scala33, scala36, scala37)
else Seq(scala33, scala35, scala36, scala37)
(coreScalaVersions ++ scala3Versions :+ scala3Next).distinct
}
lazy val cliScalaVersionsWithTargets: Seq[(String, TargetAxis)] =
Expand Down Expand Up @@ -84,7 +84,11 @@ object ScalafixBuild extends AutoPlugin with GhpagesKeys {
scalaVersion.value.startsWith("2.12")
}
lazy val warnUnused = Def.setting {
if (isScala3.value) Seq("-Wunused:all", "-Wunused:unsafe-warn-patvars")
if (isScala3.value)
Seq(
"-Wunused:all",
"-Wunused:unsafe-warn-patvars" // only needed for <3.7.0
)
else if (isScala213.value) Seq("-Wunused")
else Seq("-Ywarn-unused")
}
Expand Down Expand Up @@ -144,6 +148,7 @@ object ScalafixBuild extends AutoPlugin with GhpagesKeys {
"scala33" -> scala33,
"scala35" -> scala35,
"scala36" -> scala36,
"scala37" -> scala37,
"scala3LTS" -> scala3LTS,
"scala3Next" -> scala3Next,
sbtVersion
Expand Down Expand Up @@ -239,7 +244,8 @@ object ScalafixBuild extends AutoPlugin with GhpagesKeys {
)

private val PreviousScalaVersion: Map[String, Option[String]] = Map(
"3.6.4" -> Some("3.6.3")
"3.6.4" -> Some("3.6.3"),
scala37 -> None
)

override def buildSettings: Seq[Setting[_]] = List(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ final class ScalafixImpl extends Scalafix {
Versions.scala35
override def scala36(): String =
Versions.scala36
override def scala37(): String =
Versions.scala37
override def scala3LTS(): String =
Versions.scala3LTS
override def scala3Next(): String =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ public interface Scalafix {
*/
String scala36();

/**
* The Scala 3.7 version in {@link #supportedScalaVersions()}
*/
String scala37();

/**
* The Scala 3 LTS version in {@link #supportedScalaVersions()}
*/
Expand Down Expand Up @@ -155,6 +160,8 @@ static Scalafix fetchAndClassloadInstance(String requestedScalaVersion, List<Rep
scalaVersionKey = "scala35";
} else if (requestedScalaMajorMinorOrMajorVersion.equals("3.6")) {
scalaVersionKey = "scala36";
} else if (requestedScalaMajorMinorOrMajorVersion.equals("3.7")) {
scalaVersionKey = "scala37";
} else if (requestedScalaMajorMinorOrMajorVersion.startsWith("3")) {
scalaVersionKey = "scala3Next";
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,10 @@ class RemoveUnused(config: RemoveUnusedConfig)
isUnusedPattern += diagnostic.position
} else if (
config.params &&
(msg.startsWith("parameter") && msg.endsWith("is never used"))
(
msg.startsWith("parameter") && msg.endsWith("is never used") ||
msg == "unused explicit parameter"
)
) {
isUnusedParam += diagnostic.position
}
Expand Down Expand Up @@ -189,7 +192,7 @@ class RemoveUnused(config: RemoveUnusedConfig)
case Term.Function(params, _) =>
params.collect {
case param @ Term.Param(_, name, _, _)
if isUnusedParam(param.pos) =>
if isUnusedParam(param.pos) || isUnusedParam(name.pos) =>
Patch.replaceTree(name, "_")
}.asPatch
}.asPatch
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ case class RemoveUnusedConfig(
locals: Boolean = true,
@Description("Remove unused pattern match variables")
patternvars: Boolean = true,
@Description("Remove unused function parameters (Scala 2 only)")
@Description("Remove unused function parameters")
params: Boolean = true
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,23 @@ class RuleSuite extends AbstractSemanticRuleSuite with AnyFunSuiteLike {
override def runOn(diffTest: RuleTest): Unit = {
def stripPatch(v: String) = v.split('.').take(2).mkString(".")

val inputSV = props.scalaVersion
val path = diffTest.path.input.toNIO.toString

val versionMismatch =
stripPatch(RulesBuildInfo.scalaVersion) != stripPatch(props.scalaVersion)
stripPatch(RulesBuildInfo.scalaVersion) != stripPatch(inputSV)
val explicitResultTypesTest =
diffTest.path.input.toNIO.toString.contains(
path.contains(
"explicitResultTypes" + java.io.File.separator // don't skip tests with a suffix
)

// ExplicitResultTypes can only run against sources compiled with the sam
// binary version as the one used to compile the rule
if (versionMismatch && explicitResultTypesTest) return
if (
// ExplicitResultTypes can only run against sources compiled with the same
// binary version as the one used to compile the rule
(versionMismatch && explicitResultTypesTest) ||
// RemoveUnusedPatternVars has the old 2.12.x behavior for 2.13.14
(inputSV == "2.13.14" && path.endsWith("RemoveUnusedPatternVars.scala"))
) return
else super.runOn(diffTest)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,7 @@ object ExplicitResultTypesBase {
private val g = 1
private def h(a: Int) = ""
private var i = 22
private implicit var j = 1
val k = (1, "msg")
implicit val L = List(1)
implicit val M = Map(1 -> "STRING")
implicit def D = 2
implicit def tparam[T](e: T) = e
implicit def tparam2[T](e: T) = List(e)
implicit def tparam3[T](e: T) = Map(e -> e)
class implicitlytrick {
implicit val s: _root_.java.lang.String = "string"
implicit val x = implicitly[String]
}
def comment(x: Int) =
// comment
x + 2
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
rules = ExplicitResultTypes
ExplicitResultTypes.memberKind = [Val, Def, Var]
ExplicitResultTypes.memberVisibility = [Public, Protected]
*/
package test.explicitResultTypes

import scala.language.implicitConversions

object ExplicitResultTypesImplicit {
private implicit var j = 1
implicit val L = List(1)
implicit val M = Map(1 -> "STRING")
implicit def D = 2
implicit def tparam[T](e: T) = e
implicit def tparam2[T](e: T) = List(e)
implicit def tparam3[T](e: T) = Map(e -> e)
class implicitlytrick {
implicit val s: _root_.java.lang.String = "string"
implicit val x = implicitly[String]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ rule = RemoveUnused
*/
package test.removeUnused

// Not available as of Scala 3.4.1
// https://github.com/scalacenter/scalafix/issues/1937
object UnusedParams {
val f: String => Unit = unused => println("f")
val ff = (unused: String) => println("f")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ object ob {
// Add code that needs fixing here.
val example = AB(42, "lol")

example match {
case AB(aa, bb) => println("https://github.com/scala/bug/issues/13035")
}
example match {
case AB(_, _) => println("Not used, good")
}
Expand Down
Loading