Unused implicit?

I don’t understand this warning"

[warn] -- [E198] Unused Symbol Warning: /Users/.../polynomial/utils.scala:21:30 
[warn] 21 |def isCanonical[P: Polynomials](poly: P): Boolean = poly.asMatchable match ...
[warn]    |                              ^
[warn]    |                              unused implicit parameter

The implicit is indeed unused, but it is still useful to prevent calls to isCanonical on types that are not of the Polynomials typeclass. Isn’t that a valid use of an (unused) implicit?

Yes, this is what is called an evidence.

IIRC, in Scala 2 if you named it ev then it doesn’t warn, not sure if Scala 3 has that same trick.
Otherwise, you can just use @nowarn.

Same warning if named ev:

[warn] -- [E198] Unused Symbol Warning: /Users/charpov/GIT/Assignments-761_861/4/Polynomials/src-instructor/test/scala/polynomial/utils.scala:21:34 
[warn] 21 |def isCanonical[P](poly: P)(using ev: Polynomials[P]): Boolean = poly.asMatchable match
[warn]    |                                  ^^
[warn]    |                                  unused implicit parameter
1 Like

A few well-known types are excluded from the warning and also types without members (“marker interfaces”).

For example, it warns for Comparable. Not actually comparing anything suggests that the constraint is stale, or you actually forgot to compare them.

scala> def f[A: Comparable] = "42".toInt
1 warning found
-- [E198] Unused Symbol Warning: -----------------------------------------------
1 |def f[A: Comparable] = "42".toInt
  |                   ^
  |                   unused implicit parameter
def f[A](using evidence$1: Comparable[A]): Int

I think it’s necessary to unuse it this way, on the desugared form:

scala> def f[A](a: A)(using @unused c: Comparable[A]) = a.toString
def f[A](a: A)(using c: Comparable[A]): String

That is a bit nicer than @nowarn, which would work for context bound syntax.

(I think heuristics like the name test were before you could choose
-Wunused:explicits,implicits,synthetics
Actually Scala 3 doesn’t have synthetics yet, that is Scala 2 only:

  -Wunused:synthetics               Warn if a synthetic implicit parameter (context bound) is unused.
  -Wunused:nowarn                   Warn if a @nowarn annotation does not suppress any warnings.
  -Wunused:params                   Enable -Wunused:explicits,implicits,synthetics.

It was added in early pandemic, no doubt to pass the time.)

2 Likes