Skip to content

Commit

Permalink
Fix the non-miniphase tree traverser (#16684)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
szymon-rd authored Jan 18, 2023
2 parents b824375 + ef7e32c commit 9337bd6
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 3 deletions.
7 changes: 5 additions & 2 deletions compiler/src/dotty/tools/dotc/transform/CheckUnused.scala
Original file line number Diff line number Diff line change
Expand Up @@ -204,12 +204,15 @@ class CheckUnused extends MiniPhase:
case t:tpd.ValDef =>
prepareForValDef(t)
traverseChildren(tree)(using newCtx)
transformValDef(t)
case t:tpd.DefDef =>
prepareForDefDef(t)
traverseChildren(tree)(using newCtx)
transformDefDef(t)
case t:tpd.TypeDef =>
prepareForTypeDef(t)
traverseChildren(tree)(using newCtx)
transformTypeDef(t)
case t: tpd.Bind =>
prepareForBind(t)
traverseChildren(tree)(using newCtx)
Expand Down Expand Up @@ -332,7 +335,7 @@ object CheckUnused:
* The optional name will be used to target the right import
* as the same element can be imported with different renaming
*/
def registerUsed(sym: Symbol, name: Option[Name])(using Context): Unit =
def registerUsed(sym: Symbol, name: Option[Name])(using Context): Unit =
if !isConstructorOfSynth(sym) && !doNotRegister(sym) then
if sym.isConstructor && sym.exists then
registerUsed(sym.owner, None) // constructor are "implicitly" imported with the class
Expand Down Expand Up @@ -368,7 +371,7 @@ object CheckUnused:
implicitParamInScope += memDef
else
explicitParamInScope += memDef
else if currScopeType.top == ScopeType.Local then
else if currScopeType.top == ScopeType.Local then
localDefInScope += memDef
else if memDef.shouldReportPrivateDef then
privateDefInScope += memDef
Expand Down
12 changes: 11 additions & 1 deletion tests/neg-custom-args/fatal-warnings/i15503i.scala
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,16 @@ package foo.test.companionprivate:
private def b = c // OK
def c = List(1,2,3) // OK

package foo.test.i16678:
def foo(func: Int => String, value: Int): String = func(value) // OK

def run =
println(foo(number => number.toString, value = 5)) // OK
println(foo(number => "<number>", value = 5)) // error
println(foo(func = number => "<number>", value = 5)) // error
println(foo(func = number => number.toString, value = 5)) // OK
println(foo(func = _.toString, value = 5)) // OK

package foo.test.possibleclasses:
case class AllCaseClass(
k: Int, // OK
Expand Down Expand Up @@ -120,4 +130,4 @@ package foo.test.from.i16675:
case class PositiveNumber private (i: Int) // OK
object PositiveNumber:
def make(i: Int): Option[PositiveNumber] = //OK
Option.when(i >= 0)(PositiveNumber(i)) // OK
Option.when(i >= 0)(PositiveNumber(i)) // OK

0 comments on commit 9337bd6

Please sign in to comment.