Skip to content

Commit 9337bd6

Browse files
authored
Fix the non-miniphase tree traverser (#16684)
Fixes #16678. The issue is related to the second tree traverser (needed as miniphase traverser do not cover every cases). Symbols are added to a set during the traversal of their own definition to avoid recording recursive. In the second tree traverser this symbol is never removed, so the following usage are never cached, resulting in false positive. @szymon-rd
2 parents b824375 + ef7e32c commit 9337bd6

File tree

2 files changed

+16
-3
lines changed

2 files changed

+16
-3
lines changed

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,12 +204,15 @@ class CheckUnused extends MiniPhase:
204204
case t:tpd.ValDef =>
205205
prepareForValDef(t)
206206
traverseChildren(tree)(using newCtx)
207+
transformValDef(t)
207208
case t:tpd.DefDef =>
208209
prepareForDefDef(t)
209210
traverseChildren(tree)(using newCtx)
211+
transformDefDef(t)
210212
case t:tpd.TypeDef =>
211213
prepareForTypeDef(t)
212214
traverseChildren(tree)(using newCtx)
215+
transformTypeDef(t)
213216
case t: tpd.Bind =>
214217
prepareForBind(t)
215218
traverseChildren(tree)(using newCtx)
@@ -332,7 +335,7 @@ object CheckUnused:
332335
* The optional name will be used to target the right import
333336
* as the same element can be imported with different renaming
334337
*/
335-
def registerUsed(sym: Symbol, name: Option[Name])(using Context): Unit =
338+
def registerUsed(sym: Symbol, name: Option[Name])(using Context): Unit =
336339
if !isConstructorOfSynth(sym) && !doNotRegister(sym) then
337340
if sym.isConstructor && sym.exists then
338341
registerUsed(sym.owner, None) // constructor are "implicitly" imported with the class
@@ -368,7 +371,7 @@ object CheckUnused:
368371
implicitParamInScope += memDef
369372
else
370373
explicitParamInScope += memDef
371-
else if currScopeType.top == ScopeType.Local then
374+
else if currScopeType.top == ScopeType.Local then
372375
localDefInScope += memDef
373376
else if memDef.shouldReportPrivateDef then
374377
privateDefInScope += memDef

tests/neg-custom-args/fatal-warnings/i15503i.scala

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,16 @@ package foo.test.companionprivate:
7575
private def b = c // OK
7676
def c = List(1,2,3) // OK
7777

78+
package foo.test.i16678:
79+
def foo(func: Int => String, value: Int): String = func(value) // OK
80+
81+
def run =
82+
println(foo(number => number.toString, value = 5)) // OK
83+
println(foo(number => "<number>", value = 5)) // error
84+
println(foo(func = number => "<number>", value = 5)) // error
85+
println(foo(func = number => number.toString, value = 5)) // OK
86+
println(foo(func = _.toString, value = 5)) // OK
87+
7888
package foo.test.possibleclasses:
7989
case class AllCaseClass(
8090
k: Int, // OK
@@ -120,4 +130,4 @@ package foo.test.from.i16675:
120130
case class PositiveNumber private (i: Int) // OK
121131
object PositiveNumber:
122132
def make(i: Int): Option[PositiveNumber] = //OK
123-
Option.when(i >= 0)(PositiveNumber(i)) // OK
133+
Option.when(i >= 0)(PositiveNumber(i)) // OK

0 commit comments

Comments
 (0)