Skip to content

Commit 0163e4a

Browse files
committed
Take inferred or explicit refinement result for unused check
1 parent ac914d9 commit 0163e4a

File tree

3 files changed

+35
-21
lines changed

3 files changed

+35
-21
lines changed

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

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -172,9 +172,7 @@ class CheckUnused private (phaseMode: PhaseMode, suffix: String) extends MiniPha
172172
override def prepareForValDef(tree: ValDef)(using Context): Context =
173173
if !tree.symbol.is(Deferred) && tree.rhs.symbol != defn.Predef_undefined then
174174
refInfos.register(tree)
175-
tree.tpt match
176-
case RefinedTypeTree(_, refinements) => relax(tree.rhs, refinements)
177-
case _ =>
175+
relax(tree.rhs, tree.tpt.tpe)
178176
ctx
179177
override def transformValDef(tree: ValDef)(using Context): tree.type =
180178
traverseAnnotations(tree.symbol)
@@ -198,9 +196,7 @@ class CheckUnused private (phaseMode: PhaseMode, suffix: String) extends MiniPha
198196
refInfos.inliners += 1
199197
else if !tree.symbol.is(Deferred) && tree.rhs.symbol != defn.Predef_undefined then
200198
refInfos.register(tree)
201-
tree.tpt match
202-
case RefinedTypeTree(_, refinements) => relax(tree.rhs, refinements)
203-
case _ =>
199+
relax(tree.rhs, tree.tpt.tpe)
204200
ctx
205201
override def transformDefDef(tree: DefDef)(using Context): tree.type =
206202
traverseAnnotations(tree.symbol)
@@ -864,15 +860,21 @@ object CheckUnused:
864860
case tree => traverseChildren(tree)
865861

866862
// NoWarn members in tree that correspond to refinements; currently uses only names.
867-
def relax(tree: Tree, refinements: List[Tree])(using Context): Unit =
868-
val names = refinements.collect { case named: NamedDefTree => named.name }.toSet
869-
val relaxer = new TreeTraverser:
870-
def traverse(tree: Tree)(using Context) =
871-
tree match
872-
case tree: NamedDefTree if names(tree.name) => tree.withAttachment(NoWarn, ())
873-
case _ =>
874-
traverseChildren(tree)
875-
relaxer.traverse(tree)
863+
def relax(tree: Tree, tpe: Type)(using Context): Unit =
864+
def refinements(tpe: Type, names: List[Name]): List[Name] =
865+
tpe match
866+
case RefinedType(parent, refinedName, refinedInfo) => refinedName :: refinements(parent, names)
867+
case _ => names
868+
val refinedNames = refinements(tpe, Nil)
869+
if !refinedNames.isEmpty then
870+
val names = refinedNames.toSet
871+
val relaxer = new TreeTraverser:
872+
def traverse(tree: Tree)(using Context) =
873+
tree match
874+
case tree: NamedDefTree if names(tree.name) => tree.withAttachment(NoWarn, ())
875+
case _ =>
876+
traverseChildren(tree)
877+
relaxer.traverse(tree)
876878

877879
extension (nm: Name)
878880
inline def exists(p: Name => Boolean): Boolean = nm.ne(nme.NO_NAME) && p(nm)

tests/warn/i22681.scala

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,10 @@ trait T:
66

77
class C:
88
def f: Runnable { def u: Int } = new Runnable with T:
9-
private def v = 42 // avoid g judged too trivial to warn
109
def run() = ()
11-
def g = v // warn effectively private member is unused
12-
def t = v // nowarn
13-
def u = v // nowarn because leaked by refinement
10+
def g = 42 // warn effectively private member is unused
11+
def t = 42 // nowarn
12+
def u = 42 // nowarn because leaked by refinement
1413
val v: Runnable { def u: Int } = new Runnable:
15-
private def v = 42 // avoid g judged too trivial to warn
1614
def run() = ()
17-
def u = v // nowarn because leaked by refinement
15+
def u = 42 // nowarn because leaked by refinement

tests/warn/i23323.scala

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//> using options -Wunused:all
2+
3+
class C:
4+
val x = new reflect.Selectable:
5+
def f = 42
6+
def g = 27
7+
val y: Selectable = new reflect.Selectable:
8+
def f = 42 // warn
9+
def g = 27 // warn
10+
val z = new scala.Selectable:
11+
def f = 42
12+
def g = 27
13+
def selectDynamic(name: String): Any = ???
14+
def applyDynamic(name: String)(args: Any*): Any = ???

0 commit comments

Comments
 (0)