Skip to content

Commit

Permalink
Merge pull request #10692 from som-snytt/issue/12935-no-warn-empty-ev…
Browse files Browse the repository at this point in the history
…idence

Don't warn unused evidence of empty interface
  • Loading branch information
lrytz committed Mar 5, 2024
2 parents 06a7509 + 17102c3 commit 13cbc00
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 6 deletions.
Expand Up @@ -762,15 +762,18 @@ trait TypeDiagnostics extends splain.SplainDiagnostics {
opc.iterator.exists(_.low == m)
}
}
def isEmptyMarker(p: Symbol): Boolean = p.info.members.reverseIterator.forall(isUniversalMember(_)) // nonTrivialMembers(p).isEmpty
def isConvention(p: Symbol): Boolean = (
p.name.decoded == "args" && p.owner.isMethod && p.owner.name.decoded == "main"
||
p.isImplicit && cond(p.tpe.typeSymbol) { case SameTypeClass | SubTypeClass | DummyImplicitClass => true }
)
def warningIsOnFor(s: Symbol) =
if (!s.isImplicit) settings.warnUnusedExplicits
else if (!s.isSynthetic) settings.warnUnusedImplicits
else settings.warnUnusedSynthetics
else {
if (!s.isSynthetic) settings.warnUnusedImplicits
else settings.warnUnusedSynthetics
} && !isEmptyMarker(s)
def warnable(s: Symbol) = (
warningIsOnFor(s)
&& !isImplementation(s.owner)
Expand Down
2 changes: 1 addition & 1 deletion test/files/neg/t12591.scala
@@ -1,5 +1,5 @@
// scalac: -Werror -Wunused:synthetics
trait Context[A]
trait Context[A] { def m(a: A): A = a } // Context has a member, so warn if unused

object Example {
def g[A: Context] = f
Expand Down
8 changes: 7 additions & 1 deletion test/files/neg/warn-unused-implicits.check
Expand Up @@ -4,6 +4,12 @@ warn-unused-implicits.scala:13: warning: parameter s in method f is never used
warn-unused-implicits.scala:33: warning: parameter s in method i is never used
def i(implicit s: String, t: Int) = t // yes, warn
^
warn-unused-implicits.scala:52: warning: parameter ev in method ==> is never used
def ==>[B](b: B)(implicit ev: BadCanEqual[A, B]): Boolean = a == b // warn, ev.run
^
warn-unused-implicits.scala:60: warning: parameter m in method f is never used
def f[A](implicit m: MembersOnly[A]) = toString.nonEmpty // warn implicit trait with private member
^
error: No warnings can be incurred under -Werror.
2 warnings
4 warnings
1 error
19 changes: 19 additions & 0 deletions test/files/neg/warn-unused-implicits.scala
Expand Up @@ -40,3 +40,22 @@ trait U { _: T =>
override def f()(implicit i: Int): Int = g() // no warn, required by baseclass, scala/bug#12876
def g(): Int
}

trait CanEqual[A, B]
trait BadCanEqual[A, B] extends Runnable

class EqTest {
implicit class ArrowAssert[A](a: A) {
def ==>[B](b: B)(implicit ev: CanEqual[A, B]): Boolean = a == b // no warn, no non-trivial members
}
implicit class BadArrowAssert[A](a: A) {
def ==>[B](b: B)(implicit ev: BadCanEqual[A, B]): Boolean = a == b // warn, ev.run
}
}

trait MembersOnly[A] {
private def member() = 42 // don't care whether member is accessible; maybe they must pass it elsewhere
}
class Privately {
def f[A](implicit m: MembersOnly[A]) = toString.nonEmpty // warn implicit trait with private member
}
5 changes: 4 additions & 1 deletion test/files/neg/warn-unused-params.check
Expand Up @@ -43,6 +43,9 @@ warn-unused-params.scala:111: warning: parameter b in method f is never used
warn-unused-params.scala:134: warning: parameter s in method i is never used
def i(implicit s: String) = answer // yes, warn
^
warn-unused-params.scala:142: warning: parameter s in method f is never used
def f(s: Serializable) = toString.nonEmpty // warn explicit param of marker trait
^
error: No warnings can be incurred under -Werror.
15 warnings
16 warnings
1 error
6 changes: 5 additions & 1 deletion test/files/neg/warn-unused-params.scala
Expand Up @@ -96,7 +96,7 @@ trait Anonymous {

def g = for (i <- List(1)) yield answer // warn map.(i => 42)
}
trait Context[A]
trait Context[A] { def m(a: A): A = a }
trait Implicits {
def f[A](implicit ctx: Context[A]) = answer
def g[A: Context] = answer
Expand Down Expand Up @@ -137,3 +137,7 @@ trait BadMix { _: InterFace =>
class Unequal {
override def equals(other: Any) = toString.nonEmpty // no warn non-trivial RHS, required by universal method
}

class Seriously {
def f(s: Serializable) = toString.nonEmpty // warn explicit param of marker trait
}

0 comments on commit 13cbc00

Please sign in to comment.