summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala33
-rw-r--r--test/files/neg/warn-unused-privates.check60
-rw-r--r--test/files/neg/warn-unused-privates.scala36
3 files changed, 101 insertions, 28 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
index 36b9a65334..3cc896f3bd 100644
--- a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
@@ -464,7 +464,9 @@ trait TypeDiagnostics {
context.warning(pos, "imported `%s' is permanently hidden by definition of %s".format(hidden, defn.fullLocationString))
object checkUnused {
- val ignoreNames: Set[TermName] = Set(TermName("readResolve"), TermName("readObject"), TermName("writeObject"), TermName("writeReplace"))
+ val ignoreNames: Set[TermName] = Set(
+ "readResolve", "readObject", "writeObject", "writeReplace"
+ ).map(TermName(_))
class UnusedPrivates extends Traverser {
val defnTrees = ListBuffer[MemberDef]()
@@ -523,8 +525,12 @@ trait TypeDiagnostics {
&& (m.isPrivate || m.isLocalToBlock)
&& !(treeTypes.exists(tp => tp exists (t => t.typeSymbolDirect == m)))
)
+ def isSyntheticWarnable(sym: Symbol) = (
+ sym.isDefaultGetter
+ )
def isUnusedTerm(m: Symbol): Boolean = (
(m.isTerm)
+ && (!m.isSynthetic || isSyntheticWarnable(m))
&& (m.isPrivate || m.isLocalToBlock)
&& !targets(m)
&& !(m.name == nme.WILDCARD) // e.g. val _ = foo
@@ -533,7 +539,13 @@ trait TypeDiagnostics {
&& !treeTypes.exists(_ contains m) // e.g. val a = new Foo ; new a.Bar
)
def unusedTypes = defnTrees.toList filter (t => isUnusedType(t.symbol))
- def unusedTerms = defnTrees.toList filter (v => isUnusedTerm(v.symbol))
+ def unusedTerms = {
+ val all = defnTrees.toList.filter(v => isUnusedTerm(v.symbol))
+ // filter out setters if already warning for getter, indicated by position
+ if (all.exists(_.symbol.isSetter))
+ all.filterNot(v => v.symbol.isSetter && all.exists(g => g.symbol.isGetter && g.symbol.pos.point == v.symbol.pos.point))
+ else all
+ }
// local vars which are never set, except those already returned in unused
def unsetVars = localVars filter (v => !setVars(v) && !isUnusedTerm(v))
}
@@ -556,11 +568,18 @@ trait TypeDiagnostics {
val what = (
if (sym.isDefaultGetter) "default argument"
else if (sym.isConstructor) "constructor"
- else if (sym.isVar || sym.isGetter && (sym.accessed.isVar || (sym.owner.isTrait && !sym.hasFlag(STABLE)))) "var"
- else if (sym.isVal || sym.isGetter && (sym.accessed.isVal || (sym.owner.isTrait && sym.hasFlag(STABLE))) || sym.isLazy) "val"
- else if (sym.isSetter) "setter"
- else if (sym.isMethod) "method"
- else if (sym.isModule) "object"
+ else if (
+ sym.isVar
+ || sym.isGetter && (sym.accessed.isVar || (sym.owner.isTrait && !sym.hasFlag(STABLE)))
+ ) s"var ${sym.name.getterName.decoded}"
+ else if (
+ sym.isVal
+ || sym.isGetter && (sym.accessed.isVal || (sym.owner.isTrait && sym.hasFlag(STABLE)))
+ || sym.isLazy
+ ) s"val ${sym.name.decoded}"
+ else if (sym.isSetter) s"setter of ${sym.name.getterName.decoded}"
+ else if (sym.isMethod) s"method ${sym.name.decoded}"
+ else if (sym.isModule) s"object ${sym.name.decoded}"
else "term"
)
reporter.warning(pos, s"$why $what in ${sym.owner} is never used")
diff --git a/test/files/neg/warn-unused-privates.check b/test/files/neg/warn-unused-privates.check
index 2e93f338bb..6e1511d0e5 100644
--- a/test/files/neg/warn-unused-privates.check
+++ b/test/files/neg/warn-unused-privates.check
@@ -1,66 +1,84 @@
warn-unused-privates.scala:2: warning: private constructor in class Bippy is never used
private def this(c: Int) = this(c, c) // warn
^
-warn-unused-privates.scala:4: warning: private method in class Bippy is never used
+warn-unused-privates.scala:4: warning: private method boop in class Bippy is never used
private def boop(x: Int) = x+a+b // warn
^
-warn-unused-privates.scala:6: warning: private val in class Bippy is never used
+warn-unused-privates.scala:6: warning: private val MILLIS2 in class Bippy is never used
final private val MILLIS2: Int = 1000 // warn
^
-warn-unused-privates.scala:13: warning: private val in object Bippy is never used
+warn-unused-privates.scala:13: warning: private val HEY_INSTANCE in object Bippy is never used
private val HEY_INSTANCE: Int = 1000 // warn
^
-warn-unused-privates.scala:14: warning: private val in object Bippy is never used
+warn-unused-privates.scala:14: warning: private val BOOL in object Bippy is never used
private lazy val BOOL: Boolean = true // warn
^
-warn-unused-privates.scala:36: warning: private val in class Boppy is never used
+warn-unused-privates.scala:36: warning: private val hummer in class Boppy is never used
private val hummer = "def" // warn
^
-warn-unused-privates.scala:43: warning: private var in trait Accessors is never used
+warn-unused-privates.scala:43: warning: private var v1 in trait Accessors is never used
private var v1: Int = 0 // warn
^
-warn-unused-privates.scala:44: warning: private var in trait Accessors is never used
+warn-unused-privates.scala:44: warning: private var v2 in trait Accessors is never used
private var v2: Int = 0 // warn, never set
^
-warn-unused-privates.scala:45: warning: private var in trait Accessors is never used
+warn-unused-privates.scala:45: warning: private var v3 in trait Accessors is never used
private var v3: Int = 0 // warn, never got
^
-warn-unused-privates.scala:57: warning: private default argument in trait DefaultArgs is never used
+warn-unused-privates.scala:56: warning: private var s1 in class StableAccessors is never used
+ private var s1: Int = 0 // warn
+ ^
+warn-unused-privates.scala:57: warning: private setter of s2 in class StableAccessors is never used
+ private var s2: Int = 0 // warn, never set
+ ^
+warn-unused-privates.scala:58: warning: private var s3 in class StableAccessors is never used
+ private var s3: Int = 0 // warn, never got
+ ^
+warn-unused-privates.scala:70: warning: private default argument in trait DefaultArgs is never used
private def bippy(x1: Int, x2: Int = 10, x3: Int = 15): Int = x1 + x2 + x3
^
-warn-unused-privates.scala:57: warning: private default argument in trait DefaultArgs is never used
+warn-unused-privates.scala:70: warning: private default argument in trait DefaultArgs is never used
private def bippy(x1: Int, x2: Int = 10, x3: Int = 15): Int = x1 + x2 + x3
^
-warn-unused-privates.scala:68: warning: local var in method f0 is never used
+warn-unused-privates.scala:86: warning: local var x in method f0 is never used
var x = 1 // warn
^
-warn-unused-privates.scala:75: warning: local val in method f1 is never used
+warn-unused-privates.scala:93: warning: local val b in method f1 is never used
val b = new Outer // warn
^
-warn-unused-privates.scala:85: warning: private object in object Types is never used
+warn-unused-privates.scala:103: warning: private object Dongo in object Types is never used
private object Dongo { def f = this } // warn
^
-warn-unused-privates.scala:95: warning: local object in method l1 is never used
+warn-unused-privates.scala:113: warning: local object HiObject in method l1 is never used
object HiObject { def f = this } // warn
^
-warn-unused-privates.scala:79: warning: local var x in method f2 is never set - it could be a val
+warn-unused-privates.scala:136: warning: private method x_= in class OtherNames is never used
+ private def x_=(i: Int): Unit = ???
+ ^
+warn-unused-privates.scala:137: warning: private method x in class OtherNames is never used
+ private def x: Int = 42
+ ^
+warn-unused-privates.scala:138: warning: private method y_= in class OtherNames is never used
+ private def y_=(i: Int): Unit = ???
+ ^
+warn-unused-privates.scala:97: warning: local var x in method f2 is never set - it could be a val
var x = 100 // warn about it being a var
^
-warn-unused-privates.scala:86: warning: private class Bar1 in object Types is never used
+warn-unused-privates.scala:104: warning: private class Bar1 in object Types is never used
private class Bar1 // warn
^
-warn-unused-privates.scala:88: warning: private type Alias1 in object Types is never used
+warn-unused-privates.scala:106: warning: private type Alias1 in object Types is never used
private type Alias1 = String // warn
^
-warn-unused-privates.scala:96: warning: local class Hi is never used
+warn-unused-privates.scala:114: warning: local class Hi is never used
class Hi { // warn
^
-warn-unused-privates.scala:100: warning: local class DingDongDoobie is never used
+warn-unused-privates.scala:118: warning: local class DingDongDoobie is never used
class DingDongDoobie // warn
^
-warn-unused-privates.scala:103: warning: local type OtherThing is never used
+warn-unused-privates.scala:121: warning: local type OtherThing is never used
type OtherThing = String // warn
^
error: No warnings can be incurred under -Xfatal-warnings.
-21 warnings found
+27 warnings found
one error found
diff --git a/test/files/neg/warn-unused-privates.scala b/test/files/neg/warn-unused-privates.scala
index 2eda280d40..2f67882632 100644
--- a/test/files/neg/warn-unused-privates.scala
+++ b/test/files/neg/warn-unused-privates.scala
@@ -52,6 +52,19 @@ trait Accessors {
}
}
+class StableAccessors {
+ private var s1: Int = 0 // warn
+ private var s2: Int = 0 // warn, never set
+ private var s3: Int = 0 // warn, never got
+ private var s4: Int = 0 // no warn
+
+ def bippy(): Int = {
+ s3 = 5
+ s4 = 6
+ s2 + s4
+ }
+}
+
trait DefaultArgs {
// warn about default getters for x2 and x3
private def bippy(x1: Int, x2: Int = 10, x3: Int = 15): Int = x1 + x2 + x3
@@ -59,6 +72,11 @@ trait DefaultArgs {
def boppy() = bippy(5, 100, 200)
}
+/* SI-7707 Both usages warn default arg because using PrivateRyan.apply, not new.
+case class PrivateRyan private (ryan: Int = 42) { def f = PrivateRyan() }
+object PrivateRyan { def f = PrivateRyan() }
+*/
+
class Outer {
class Inner
}
@@ -104,3 +122,21 @@ object Types {
(new Bippy): Something
}
}
+
+trait Underwarn {
+ def f(): Seq[Int]
+
+ def g() = {
+ val Seq(_, _) = f() // no warn
+ true
+ }
+}
+
+class OtherNames {
+ private def x_=(i: Int): Unit = ???
+ private def x: Int = 42
+ private def y_=(i: Int): Unit = ???
+ private def y: Int = 42
+
+ def f = y
+}