Skip to content

Commit dc13b7d

Browse files
som-snytttgodzik
authored andcommitted
Check for synthetic case methods in unused lint (scala#24239)
Fixes scala#24235 References to a case class from synthetic methods in its companion are not usages for `-Wunused`. [Cherry-picked da0a934]
1 parent a02ca5a commit dc13b7d

File tree

2 files changed

+32
-7
lines changed

2 files changed

+32
-7
lines changed

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

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -275,10 +275,23 @@ class CheckUnused private (phaseMode: PhaseMode, suffix: String) extends MiniPha
275275
for annot <- sym.denot.annotations do
276276
transformAllDeep(annot.tree)
277277

278-
// if sym is not an enclosing element, record the reference
278+
/** If sym is not an enclosing element with respect to the give context, record the reference
279+
*
280+
* Also check that every enclosing element is not a synthetic member
281+
* of the sym's case class companion module.
282+
*/
279283
def refUsage(sym: Symbol)(using Context): Unit =
280-
if !ctx.outersIterator.exists(cur => cur.owner eq sym) then
281-
refInfos.addRef(sym)
284+
if !refInfos.hasRef(sym) then
285+
val isCase = sym.is(Case) && sym.isClass
286+
if !ctx.outersIterator.exists: outer =>
287+
val owner = outer.owner
288+
owner.eq(sym)
289+
|| isCase
290+
&& owner.exists
291+
&& owner.is(Synthetic)
292+
&& owner.owner.eq(sym.companionModule.moduleClass)
293+
then
294+
refInfos.addRef(sym)
282295

283296
/** Look up a reference in enclosing contexts to determine whether it was introduced by a definition or import.
284297
* The binding of highest precedence must then be correct.
@@ -394,7 +407,7 @@ class CheckUnused private (phaseMode: PhaseMode, suffix: String) extends MiniPha
394407
end while
395408
// record usage and possibly an import
396409
if !enclosed then
397-
refInfos.addRef(sym)
410+
refUsage(sym)
398411
if imports && candidate != NoContext && candidate.isImportContext && importer != null then
399412
refInfos.sels.put(importer, ())
400413
end resolveUsage
@@ -414,15 +427,15 @@ class CheckUnused private (phaseMode: PhaseMode, suffix: String) extends MiniPha
414427
else Nil
415428
implicitRefs.find(ref => ref.underlyingRef.widen <:< tp) match
416429
case Some(found: TermRef) =>
417-
refInfos.addRef(found.denot.symbol)
430+
refUsage(found.denot.symbol)
418431
if cur.isImportContext then
419432
cur.importInfo.nn.selectors.find(sel => sel.isGiven || sel.rename == found.name) match
420433
case Some(sel) =>
421434
refInfos.sels.put(sel, ())
422435
case _ =>
423436
return
424437
case Some(found: RenamedImplicitRef) if cur.isImportContext =>
425-
refInfos.addRef(found.underlyingRef.denot.symbol)
438+
refUsage(found.underlyingRef.denot.symbol)
426439
cur.importInfo.nn.selectors.find(sel => sel.rename == found.implicitName) match
427440
case Some(sel) =>
428441
refInfos.sels.put(sel, ())
@@ -501,13 +514,18 @@ object CheckUnused:
501514

502515
var inliners = 0 // depth of inline def (not inlined yet)
503516

504-
// instead of refs.addOne, use addRef to distinguish a read from a write to var
517+
// instead of refs.addOne, use refUsage -> addRef to distinguish a read from a write to var
505518
var isAssignment = false
506519
def addRef(sym: Symbol): Unit =
507520
if isAssignment then
508521
asss.addOne(sym)
509522
else
510523
refs.addOne(sym)
524+
def hasRef(sym: Symbol): Boolean =
525+
if isAssignment then
526+
asss(sym)
527+
else
528+
refs(sym)
511529

512530
// currently compiletime.testing is completely erased, so ignore the unit
513531
var isNullified = false

tests/warn/i15503c.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,10 @@ object LazyVals:
7070

7171
final class Waiting extends CountDownLatch(1), LazyValControlState:
7272
private def writeReplace(): Any = null
73+
74+
package i24235:
75+
object Test:
76+
private case class Unused() // warn
77+
private class Regular // nowarn
78+
private object Regular: // warn
79+
def r = Regular() // usage

0 commit comments

Comments
 (0)