-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Don't ignore params of public methods
- Loading branch information
Showing
6 changed files
with
212 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
//> using options -Wunused:locals | ||
|
||
class Outer { | ||
class Inner | ||
} | ||
|
||
trait Locals { | ||
def f0 = { | ||
var x = 1 // warn | ||
var y = 2 // no warn | ||
y = 3 | ||
y + y | ||
} | ||
def f1 = { | ||
val a = new Outer // no warn | ||
val b = new Outer // warn | ||
new a.Inner | ||
} | ||
def f2 = { | ||
var x = 100 // warn about it being a var | ||
x | ||
} | ||
} | ||
|
||
object Types { | ||
def l1() = { | ||
object HiObject { def f = this } // warn | ||
class Hi { // warn | ||
def f1: Hi = new Hi | ||
def f2(x: Hi) = x | ||
} | ||
class DingDongDoobie // warn | ||
class Bippy // no warn | ||
type Something = Bippy // no warn | ||
type OtherThing = String // warn | ||
(new Bippy): Something | ||
} | ||
} | ||
|
||
// breakage: local val x$1 in method skolemize is never used | ||
case class SymbolKind(accurate: String, sanitized: String, abbreviation: String) { | ||
def skolemize: SymbolKind = copy(accurate = s"$accurate skolem", abbreviation = s"$abbreviation#SKO") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
//> using options -Wunused:params -Werror | ||
// | ||
|
||
import Answers._ | ||
|
||
trait InterFace { | ||
/** Call something. */ | ||
def call(a: Int, b: String, c: Double): Int | ||
} | ||
|
||
trait BadAPI extends InterFace { | ||
def f(a: Int, | ||
b: String, // warn | ||
c: Double): Int = { | ||
println(c) | ||
a | ||
} | ||
@deprecated("no warn in deprecated API", since="yesterday") | ||
def g(a: Int, | ||
b: String, // no warn | ||
c: Double): Int = { | ||
println(c) | ||
a | ||
} | ||
override def call(a: Int, | ||
b: String, // no warn, required by superclass | ||
c: Double): Int = { | ||
println(c) | ||
a | ||
} | ||
|
||
def meth(x: Int) = x | ||
|
||
override def equals(other: Any): Boolean = true // no warn | ||
|
||
def i(implicit s: String) = answer // yes, warn | ||
|
||
/* | ||
def future(x: Int): Int = { | ||
val y = 42 | ||
val x = y // maybe option to warn only if shadowed | ||
x | ||
} | ||
*/ | ||
} | ||
|
||
// mustn't alter warnings in super | ||
trait PoorClient extends BadAPI { | ||
override def meth(x: Int) = ??? // no warn | ||
override def f(a: Int, b: String, c: Double): Int = a + b.toInt + c.toInt | ||
} | ||
|
||
class Unusing(u: Int) { // warn | ||
def f = ??? | ||
} | ||
|
||
class Valuing(val u: Int) // no warn | ||
|
||
class Revaluing(u: Int) { def f = u } // no warn | ||
|
||
case class CaseyKasem(k: Int) // no warn | ||
|
||
case class CaseyAtTheBat(k: Int)(s: String) // warn | ||
|
||
trait Ignorance { | ||
def f(readResolve: Int) = answer // warn | ||
} | ||
|
||
class Reusing(u: Int) extends Unusing(u) // no warn | ||
|
||
class Main { | ||
def main(args: Array[String]): Unit = println("hello, args") // no warn | ||
} | ||
|
||
trait Unimplementation { | ||
def f(u: Int): Int = ??? // no warn for param in unimplementation | ||
} | ||
|
||
trait DumbStuff { | ||
def f(implicit dummy: DummyImplicit) = answer | ||
def g(dummy: DummyImplicit) = answer | ||
} | ||
trait Proofs { | ||
def f[A, B](implicit ev: A =:= B) = answer | ||
def g[A, B](implicit ev: A <:< B) = answer | ||
def f2[A, B](ev: A =:= B) = answer | ||
def g2[A, B](ev: A <:< B) = answer | ||
} | ||
|
||
trait Anonymous { | ||
def f = (i: Int) => answer // warn | ||
|
||
def f1 = (_: Int) => answer // no warn underscore parameter (a fresh name) | ||
|
||
def f2: Int => Int = _ + 1 // no warn placeholder syntax (a fresh name and synthetic parameter) | ||
|
||
def g = for (i <- List(1)) yield answer // no warn patvar elaborated as map.(i => 42) | ||
} | ||
trait Context[A] { def m(a: A): A = a } | ||
trait Implicits { | ||
def f[A](implicit ctx: Context[A]) = answer | ||
def g[A: Context] = answer | ||
} | ||
class Bound[A: Context] | ||
object Answers { | ||
def answer: Int = 42 | ||
} | ||
|
||
trait BadMix { _: InterFace => | ||
def f(a: Int, | ||
b: String, // warn | ||
c: Double): Int = { | ||
println(c) | ||
a | ||
} | ||
@deprecated("no warn in deprecated API", since="yesterday") | ||
def g(a: Int, | ||
b: String, // no warn | ||
c: Double): Int = { | ||
println(c) | ||
a | ||
} | ||
override def call(a: Int, | ||
b: String, // no warn, required by superclass | ||
c: Double): Int = { | ||
println(c) | ||
a | ||
} | ||
|
||
def meth(x: Int) = x | ||
|
||
override def equals(other: Any): Boolean = true // no warn | ||
|
||
def i(implicit s: String) = answer // yes, warn | ||
} | ||
|
||
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 | ||
} | ||
|
||
class TryStart(start: String) { | ||
def FINALLY(end: END.type) = start | ||
} | ||
|
||
object END | ||
|
||
class Nested { | ||
@annotation.unused private def actuallyNotUsed(fresh: Int, stale: Int) = fresh | ||
} |