Skip to content

Commit

Permalink
Lint option for unused context bounds
Browse files Browse the repository at this point in the history
  • Loading branch information
som-snytt committed Nov 25, 2020
1 parent 0a4f6b4 commit 7babfd5
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 6 deletions.
6 changes: 4 additions & 2 deletions src/compiler/scala/tools/nsc/settings/Warnings.scala
Expand Up @@ -124,8 +124,9 @@ trait Warnings {
val Locals = Choice("locals", "Warn if a local definition is unused.")
val Explicits = Choice("explicits", "Warn if an explicit parameter is unused.")
val Implicits = Choice("implicits", "Warn if an implicit parameter is unused.")
val Synthetics = Choice("synthetics", "Warn if a synthetic implicit parameter (context bound) is unused.")
val Nowarn = Choice("nowarn", "Warn if a @nowarn annotation does not suppress any warnings.")
val Params = Choice("params", "Enable -Wunused:explicits,implicits.", expandsTo = List(Explicits, Implicits))
val Params = Choice("params", "Enable -Wunused:explicits,implicits,synthetics.", expandsTo = List(Explicits, Implicits, Synthetics))
val Linted = Choice("linted", "-Xlint:unused.", expandsTo = List(Imports, Privates, Locals, Implicits, Nowarn))
}

Expand All @@ -142,9 +143,10 @@ trait Warnings {
def warnUnusedPatVars = warnUnused contains UnusedWarnings.PatVars
def warnUnusedPrivates = warnUnused contains UnusedWarnings.Privates
def warnUnusedLocals = warnUnused contains UnusedWarnings.Locals
def warnUnusedParams = warnUnusedExplicits || warnUnusedImplicits
def warnUnusedParams = warnUnusedExplicits || warnUnusedImplicits || warnUnusedSynthetics
def warnUnusedExplicits = warnUnused contains UnusedWarnings.Explicits
def warnUnusedImplicits = warnUnused contains UnusedWarnings.Implicits
def warnUnusedSynthetics = warnUnused contains UnusedWarnings.Synthetics
def warnUnusedNowarn = warnUnused contains UnusedWarnings.Nowarn

val warnExtraImplicit = BooleanSetting("-Wextra-implicit", "Warn when more than one implicit parameter section is defined.") withAbbreviation "-Ywarn-extra-implicit"
Expand Down
Expand Up @@ -597,7 +597,9 @@ trait TypeDiagnostics {
case nme.CONSTRUCTOR => sym.owner.companion.isCaseClass
case nme.copy => sym.owner.typeSignature.member(nme.copy).isSynthetic
}
sym.isDefaultGetter && !privateSyntheticDefault
def defaultGetterOK = sym.isDefaultGetter && !privateSyntheticDefault
def contextBoundOK = sym.isImplicit && settings.warnUnusedSynthetics
contextBoundOK || defaultGetterOK
}
def isUnusedTerm(m: Symbol): Boolean = (
m.isTerm
Expand Down
6 changes: 6 additions & 0 deletions test/files/neg/warn-unused-explicits.check
@@ -0,0 +1,6 @@
warn-unused-explicits.scala:9: warning: parameter value x in method warn is never used
def warn(x: Int) = 42
^
error: No warnings can be incurred under -Werror.
1 warning
1 error
10 changes: 10 additions & 0 deletions test/files/neg/warn-unused-explicits.scala
@@ -0,0 +1,10 @@
// scalac: -Wunused:explicits -Werror
//
trait Context[A]
trait ExplicitsOnly {
def i(implicit s: String) = 42
def f[A](implicit ctx: Context[A]) = 42
def g[A: Context] = 42

def warn(x: Int) = 42
}
8 changes: 7 additions & 1 deletion test/files/neg/warn-unused-params.check
Expand Up @@ -28,6 +28,12 @@ warn-unused-params.scala:89: warning: parameter value i in anonymous function is
warn-unused-params.scala:95: warning: parameter value i in anonymous function is never used
def g = for (i <- List(1)) yield 42 // warn map.(i => 42)
^
warn-unused-params.scala:99: warning: parameter value ctx in method f is never used
def f[A](implicit ctx: Context[A]) = 42
^
warn-unused-params.scala:100: warning: parameter value evidence$1 in method g is never used
def g[A: Context] = 42
^
error: No warnings can be incurred under -Werror.
10 warnings
12 warnings
1 error
9 changes: 7 additions & 2 deletions test/files/neg/warn-unused-params.scala
@@ -1,4 +1,4 @@
// scalac: -Ywarn-unused:params -Xfatal-warnings
// scalac: -Wunused:params -Werror
//

trait InterFace {
Expand All @@ -13,7 +13,7 @@ trait BadAPI extends InterFace {
println(c)
a
}
@deprecated ("no warn in deprecated API", since="yesterday")
@deprecated("no warn in deprecated API", since="yesterday")
def g(a: Int,
b: String, // no warn
c: Double): Int = {
Expand Down Expand Up @@ -94,3 +94,8 @@ trait Anonymous {

def g = for (i <- List(1)) yield 42 // warn map.(i => 42)
}
trait Context[A]
trait Implicits {
def f[A](implicit ctx: Context[A]) = 42
def g[A: Context] = 42
}

0 comments on commit 7babfd5

Please sign in to comment.