summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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
+ }
+}