Skip to content

Commit e6c3cd4

Browse files
committed
No warn serialization methods
1 parent 212706f commit e6c3cd4

File tree

3 files changed

+266
-107
lines changed

3 files changed

+266
-107
lines changed

compiler/src/dotty/tools/dotc/transform/CheckUnused.scala

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import dotty.tools.dotc.core.StdNames.nme
1515
import dotty.tools.dotc.core.Symbols.*
1616
import dotty.tools.dotc.core.Types.{AnnotatedType, ClassInfo, ConstantType, NamedType, NoType, TermRef, Type, TypeProxy, TypeTraverser}
1717
import dotty.tools.dotc.core.Flags
18-
import dotty.tools.dotc.core.Names.Name
18+
import dotty.tools.dotc.core.Names.{Name, TermName, termName}
1919
import dotty.tools.dotc.core.NameOps.isReplWrapperName
2020
import dotty.tools.dotc.core.Annotations
2121
import dotty.tools.dotc.core.Definitions
@@ -733,7 +733,10 @@ object CheckUnused:
733733
!sym.shouldNotReportParamOwner
734734

735735
private def shouldReportPrivateDef(using Context): Boolean =
736-
peekScopeType == ScopeType.Template && !memDef.symbol.isConstructor && memDef.symbol.is(Private, butNot = SelfName | Synthetic | CaseAccessor)
736+
peekScopeType == ScopeType.Template
737+
&& !memDef.symbol.isConstructor
738+
&& memDef.symbol.is(Private, butNot = SelfName | Synthetic | CaseAccessor)
739+
&& !ignoredNames(memDef.symbol.name.toTermName)
737740

738741
private def isUnsetVarDef(using Context): Boolean =
739742
val sym = memDef.symbol
@@ -764,6 +767,8 @@ object CheckUnused:
764767
case _: tpd.Block => Local
765768
case _ => Other
766769

770+
val ignoredNames: Set[TermName] = Set("readResolve", "readObject", "writeObject", "writeReplace").map(termName(_))
771+
767772
final class ImportSelectorData(val qualTpe: Type, val selector: ImportSelector):
768773
private var myUsed: Boolean = false
769774

tests/untried/neg/warn-unused-privates.scala

Lines changed: 0 additions & 105 deletions
This file was deleted.

tests/warn/unused-privates.scala

Lines changed: 259 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
1+
//
2+
//> using options -deprecation -Wunused:privates,locals
3+
//
4+
class Bippy(a: Int, b: Int) {
5+
private def this(c: Int) = this(c, c) // NO warn
6+
private def bippy(x: Int): Int = bippy(x) // warn
7+
private def boop(x: Int) = x+a+b // warn
8+
final private val MILLIS1 = 2000 // warn, scala2: no warn, might have been inlined
9+
final private val MILLIS2: Int = 1000 // warn
10+
final private val HI_COMPANION: Int = 500 // no warn, accessed from companion
11+
def hi() = Bippy.HI_INSTANCE
12+
}
13+
object Bippy {
14+
def hi(x: Bippy) = x.HI_COMPANION
15+
private val HI_INSTANCE: Int = 500 // no warn, accessed from instance
16+
private val HEY_INSTANCE: Int = 1000 // warn
17+
private lazy val BOOL: Boolean = true // warn
18+
}
19+
20+
class A(val msg: String)
21+
class B1(msg: String) extends A(msg)
22+
class B2(msg0: String) extends A(msg0)
23+
class B3(msg0: String) extends A("msg")
24+
25+
trait Accessors {
26+
private var v1: Int = 0 // warn
27+
private var v2: Int = 0 // warn, never set
28+
private var v3: Int = 0 // NO warn, never got
29+
private var v4: Int = 0 // no warn
30+
31+
private var v5 = 0 // warn, never set
32+
private var v6 = 0 // NO warn, never got
33+
private var v7 = 0 // no warn
34+
35+
def bippy(): Int = {
36+
v3 = 3
37+
v4 = 4
38+
v6 = 6
39+
v7 = 7
40+
v2 + v4 + v5 + v7
41+
}
42+
}
43+
44+
class StableAccessors {
45+
private var s1: Int = 0 // warn
46+
private var s2: Int = 0 // warn, never set
47+
private var s3: Int = 0 // NO warn, never got
48+
private var s4: Int = 0 // no warn
49+
50+
private var s5 = 0 // warn, never set
51+
private var s6 = 0 // no warn, limitation
52+
private var s7 = 0 // no warn
53+
54+
def bippy(): Int = {
55+
s3 = 3
56+
s4 = 4
57+
s6 = 6
58+
s7 = 7
59+
s2 + s4 + s5 + s7
60+
}
61+
}
62+
63+
trait DefaultArgs {
64+
// NO warn about default getters for x2 and x3
65+
private def bippy(x1: Int, x2: Int = 10, x3: Int = 15): Int = x1 + x2 + x3
66+
67+
def boppy() = bippy(5, 100, 200)
68+
}
69+
70+
/* scala/bug#7707 Both usages warn default arg because using PrivateRyan.apply, not new.
71+
case class PrivateRyan private (ryan: Int = 42) { def f = PrivateRyan() }
72+
object PrivateRyan { def f = PrivateRyan() }
73+
*/
74+
75+
class Outer {
76+
class Inner
77+
}
78+
79+
trait Locals {
80+
def f0 = {
81+
var x = 1 // warn
82+
var y = 2
83+
y = 3
84+
y + y
85+
}
86+
def f1 = {
87+
val a = new Outer // no warn
88+
val b = new Outer // warn
89+
new a.Inner
90+
}
91+
def f2 = {
92+
var x = 100 // warn about it being a var
93+
x
94+
}
95+
}
96+
97+
object Types {
98+
private object Dongo { def f = this } // NO warn
99+
private class Bar1 // warn
100+
private class Bar2 // no warn
101+
private type Alias1 = String // warn
102+
private type Alias2 = String // no warn
103+
def bippo = (new Bar2).toString
104+
105+
def f(x: Alias2) = x.length
106+
107+
def l1() = {
108+
object HiObject { def f = this } // NO warn
109+
class Hi { // warn
110+
def f1: Hi = new Hi
111+
def f2(x: Hi) = x
112+
}
113+
class DingDongDoobie // warn
114+
class Bippy // no warn
115+
type Something = Bippy // no warn
116+
type OtherThing = String // warn
117+
(new Bippy): Something
118+
}
119+
}
120+
121+
trait Underwarn {
122+
def f(): Seq[Int]
123+
124+
def g() = {
125+
val Seq(_, _) = f() // no warn
126+
true
127+
}
128+
}
129+
130+
class OtherNames {
131+
private def x_=(i: Int): Unit = ()
132+
private def x: Int = 42 // warn
133+
private def y_=(i: Int): Unit = ()
134+
private def y: Int = 42
135+
136+
def f = y
137+
}
138+
139+
case class C(a: Int, b: String, c: Option[String])
140+
case class D(a: Int)
141+
142+
// patvars which used to warn as vals in older scala 2
143+
trait Boundings {
144+
145+
def c = C(42, "hello", Some("world"))
146+
def d = D(42)
147+
148+
def f() = {
149+
val C(x, y, Some(z)) = c: @unchecked // no warn
150+
17
151+
}
152+
def g() = {
153+
val C(x @ _, y @ _, Some(z @ _)) = c: @unchecked // no warn
154+
17
155+
}
156+
def h() = {
157+
val C(x @ _, y @ _, z @ Some(_)) = c: @unchecked // no warn for z?
158+
17
159+
}
160+
161+
def v() = {
162+
val D(x) = d // no warn
163+
17
164+
}
165+
def w() = {
166+
val D(x @ _) = d // no warn
167+
17
168+
}
169+
170+
}
171+
172+
trait Forever {
173+
def f = {
174+
val t = Option((17, 42))
175+
for {
176+
ns <- t
177+
(i, j) = ns // no warn
178+
} yield (i + j)
179+
}
180+
def g = {
181+
val t = Option((17, 42))
182+
for {
183+
ns <- t
184+
(i, j) = ns // no warn
185+
} yield 42 // val emitted only if needed, hence nothing unused
186+
}
187+
}
188+
189+
trait Ignorance {
190+
private val readResolve = 42 // no warn special members
191+
}
192+
193+
trait CaseyKasem {
194+
def f = 42 match {
195+
case x if x < 25 => "no warn"
196+
case y if toString.nonEmpty => "no warn" + y
197+
case z => "warn"
198+
}
199+
}
200+
trait CaseyAtTheBat {
201+
def f = Option(42) match {
202+
case Some(x) if x < 25 => "no warn"
203+
case Some(y @ _) if toString.nonEmpty => "no warn"
204+
case Some(z) => "warn"
205+
case None => "no warn"
206+
}
207+
}
208+
209+
class `not even using companion privates`
210+
211+
object `not even using companion privates` {
212+
private implicit class `for your eyes only`(i: Int) { // no warn deprecated feature
213+
def f = i
214+
}
215+
}
216+
217+
class `no warn in patmat anonfun isDefinedAt` {
218+
def f(pf: PartialFunction[String, Int]) = pf("42")
219+
def g = f {
220+
case s => s.length // no warn (used to warn case s => true in isDefinedAt)
221+
}
222+
}
223+
224+
// this is the ordinary case, as AnyRef is an alias of Object
225+
class `nonprivate alias is enclosing` {
226+
class C
227+
type C2 = C
228+
private class D extends C2 // warn
229+
}
230+
231+
object `classof something` {
232+
private class intrinsically
233+
def f = classOf[intrinsically].toString()
234+
}
235+
236+
trait `scala 2 short comings` {
237+
def f: Int = {
238+
val x = 42 // warn
239+
17
240+
}
241+
}
242+
243+
class `issue 12600 ignore abstract types` {
244+
type Abs
245+
}
246+
247+
class `t12992 enclosing def is unused` {
248+
private val n = 42
249+
@annotation.unused def f() = n + 2 // unused code uses n
250+
}
251+
252+
class `recursive reference is not a usage` {
253+
private def f(i: Int): Int = // warn
254+
if (i <= 0) i
255+
else f(i-1)
256+
private class P { // warn
257+
def f() = new P()
258+
}
259+
}

0 commit comments

Comments
 (0)