summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSom Snytt <som.snytt@gmail.com>2016-10-19 12:09:40 -0700
committerSom Snytt <som.snytt@gmail.com>2017-03-11 23:48:31 -0800
commit833724b131f86b978f0831f637d386d7ca37a2aa (patch)
tree2033b6e43ab889e8fad2518b75cfce23adde4855
parenta85521efbbf65161debc460ab5cb55562db051e9 (diff)
downloadscala-833724b131f86b978f0831f637d386d7ca37a2aa.tar.gz
scala-833724b131f86b978f0831f637d386d7ca37a2aa.tar.bz2
scala-833724b131f86b978f0831f637d386d7ca37a2aa.zip
SI-7860 No warn private implicit value class
Previously, warned on unused synthetic companion. Also avoid false negative via hashcode reference to the underlying value. Avoid the synthetic conversion method for the implicit class (whose RHS always uses the class); the def itself is synthetic so is normally not warned.
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala13
-rw-r--r--test/files/neg/t7860.check9
-rw-r--r--test/files/neg/t7860.flags1
-rw-r--r--test/files/neg/t7860.scala42
-rw-r--r--test/files/neg/warn-unused-privates.check5
-rw-r--r--test/files/neg/warn-unused-privates.scala8
6 files changed, 74 insertions, 4 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
index ee2d00900a..b30972f931 100644
--- a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
@@ -355,7 +355,10 @@ trait TypeDiagnostics {
// functions to manipulate the name
def preQualify() = modifyName(trueOwner.fullName + "." + _)
- def postQualify() = if (!(postQualifiedWith contains trueOwner)) { postQualifiedWith ::= trueOwner; modifyName(_ + "(in " + trueOwner + ")") }
+ def postQualify() = if (!(postQualifiedWith contains trueOwner)) {
+ postQualifiedWith ::= trueOwner
+ modifyName(s => s"$s(in $trueOwner)")
+ }
def typeQualify() = if (sym.isTypeParameterOrSkolem) postQualify()
def nameQualify() = if (trueOwner.isPackageClass) preQualify() else postQualify()
@@ -498,11 +501,13 @@ trait TypeDiagnostics {
override def traverse(t: Tree): Unit = {
t match {
- case m: MemberDef if qualifies(t.symbol) => defnTrees += m
+ case m: MemberDef if qualifies(t.symbol) =>
+ defnTrees += m
t match {
case DefDef(mods@_, name@_, tparams@_, vparamss, tpt@_, rhs@_) if !t.symbol.isAbstract && !t.symbol.isDeprecated =>
if (t.symbol.isPrimaryConstructor)
for (cpa <- t.symbol.owner.constrParamAccessors if cpa.isPrivateLocal) params += cpa
+ else if (t.symbol.isSynthetic && t.symbol.isImplicit) return
else if (!t.symbol.isConstructor)
for (vs <- vparamss) params ++= vs.map(_.symbol)
case _ =>
@@ -525,6 +530,7 @@ trait TypeDiagnostics {
case NoType | NoPrefix =>
case NullaryMethodType(_) =>
case MethodType(_, _) =>
+ case SingleType(_, _) =>
case _ =>
log(s"$tp referenced from $currentOwner")
treeTypes += tp
@@ -547,6 +553,7 @@ trait TypeDiagnostics {
def isSyntheticWarnable(sym: Symbol) = (
sym.isDefaultGetter
)
+
def isUnusedTerm(m: Symbol): Boolean = (
(m.isTerm)
&& (!m.isSynthetic || isSyntheticWarnable(m))
@@ -562,7 +569,7 @@ trait TypeDiagnostics {
def treepos(t: Tree): Int =
if (t.pos.isDefined) t.pos.point else sympos(t.symbol)
- def unusedTypes = defnTrees.toList filter (t => isUnusedType(t.symbol)) sortBy treepos
+ def unusedTypes = defnTrees.toList.filter(t => isUnusedType(t.symbol)).sortBy(treepos)
def unusedTerms = {
val all = defnTrees.toList.filter(v => isUnusedTerm(v.symbol))
diff --git a/test/files/neg/t7860.check b/test/files/neg/t7860.check
new file mode 100644
index 0000000000..9b9d86c89d
--- /dev/null
+++ b/test/files/neg/t7860.check
@@ -0,0 +1,9 @@
+t7860.scala:5: warning: private class for your eyes only in object Test is never used
+ private implicit class `for your eyes only`(i: Int) { // warn
+ ^
+t7860.scala:31: warning: private class C in object Test3 is never used
+ private implicit class C(val i: Int) extends AnyVal { // warn
+ ^
+error: No warnings can be incurred under -Xfatal-warnings.
+two warnings found
+one error found
diff --git a/test/files/neg/t7860.flags b/test/files/neg/t7860.flags
new file mode 100644
index 0000000000..6ff0dea0b2
--- /dev/null
+++ b/test/files/neg/t7860.flags
@@ -0,0 +1 @@
+-Xfatal-warnings -Ywarn-unused:privates
diff --git a/test/files/neg/t7860.scala b/test/files/neg/t7860.scala
new file mode 100644
index 0000000000..6cc0d3e7f5
--- /dev/null
+++ b/test/files/neg/t7860.scala
@@ -0,0 +1,42 @@
+
+class Test
+
+object Test {
+ private implicit class `for your eyes only`(i: Int) { // warn
+ def f = i
+ }
+}
+
+class Test2 {
+ import Test2._
+ println(5.toStr)
+}
+
+object Test2 {
+ // was: warning: private object in object Test2 is never used
+ // i.e. synthetic object C
+ private implicit class C(val i: Int) extends AnyVal { // no warn
+ def toStr = i.toString
+ }
+}
+
+class Test3 {
+ import Test3._
+ //println(5.toStr)
+}
+
+object Test3 {
+ // was: warning: private object in object Test2 is never used
+ // i.e. synthetic object C
+ private implicit class C(val i: Int) extends AnyVal { // warn
+ def toStr = i.toString
+ }
+}
+
+object Test4 {
+ class A { class B }
+
+ private val a: A = new A
+
+ def b = (new a.B).##
+}
diff --git a/test/files/neg/warn-unused-privates.check b/test/files/neg/warn-unused-privates.check
index 490e070794..d4853847fd 100644
--- a/test/files/neg/warn-unused-privates.check
+++ b/test/files/neg/warn-unused-privates.check
@@ -97,6 +97,9 @@ warn-unused-privates.scala:118: warning: local class DingDongDoobie is never use
warn-unused-privates.scala:121: warning: local type OtherThing is never used
type OtherThing = String // warn
^
+warn-unused-privates.scala:216: warning: private class for your eyes only in object not even using companion privates is never used
+ private implicit class `for your eyes only`(i: Int) { // warn
+ ^
warn-unused-privates.scala:201: warning: pattern var z in method f is never used; `z@_' suppresses this warning
case z => "warn"
^
@@ -104,5 +107,5 @@ warn-unused-privates.scala:208: warning: pattern var z in method f is never used
case Some(z) => "warn"
^
error: No warnings can be incurred under -Xfatal-warnings.
-35 warnings found
+36 warnings found
one error found
diff --git a/test/files/neg/warn-unused-privates.scala b/test/files/neg/warn-unused-privates.scala
index 777e0f1579..6f16ab4138 100644
--- a/test/files/neg/warn-unused-privates.scala
+++ b/test/files/neg/warn-unused-privates.scala
@@ -209,3 +209,11 @@ trait CaseyAtTheBat {
case None => "no warn"
}
}
+
+class `not even using companion privates`
+
+object `not even using companion privates` {
+ private implicit class `for your eyes only`(i: Int) { // warn
+ def f = i
+ }
+}