@@ -52,6 +52,7 @@ class CheckUnused private (phaseMode: PhaseMode, suffix: String) extends MiniPha
52
52
tree
53
53
54
54
override def transformIdent (tree : Ident )(using Context ): tree.type =
55
+ refInfos.isAssignment = tree.hasAttachment(AssignmentTarget )
55
56
if tree.symbol.exists then
56
57
// if in an inline expansion, resolve at summonInline (synthetic pos) or in an enclosing call site
57
58
val resolving =
@@ -68,10 +69,12 @@ class CheckUnused private (phaseMode: PhaseMode, suffix: String) extends MiniPha
68
69
resolveUsage(tree.symbol, tree.name, tree.typeOpt.importPrefix.skipPackageObject)
69
70
else if tree.hasType then
70
71
resolveUsage(tree.tpe.classSymbol, tree.name, tree.tpe.importPrefix.skipPackageObject)
72
+ refInfos.isAssignment = false
71
73
tree
72
74
73
75
// import x.y; y may be rewritten x.y, also import x.z as y
74
76
override def transformSelect (tree : Select )(using Context ): tree.type =
77
+ refInfos.isAssignment = tree.hasAttachment(AssignmentTarget )
75
78
val name = tree.removeAttachment(OriginalName ).getOrElse(nme.NO_NAME )
76
79
inline def isImportable = tree.qualifier.srcPos.isSynthetic
77
80
&& tree.qualifier.tpe.match
@@ -92,6 +95,7 @@ class CheckUnused private (phaseMode: PhaseMode, suffix: String) extends MiniPha
92
95
resolveUsage(tree.symbol, name, tree.qualifier.tpe)
93
96
else if ! ignoreTree(tree) then
94
97
refUsage(tree.symbol)
98
+ refInfos.isAssignment = false
95
99
tree
96
100
97
101
override def transformLiteral (tree : Literal )(using Context ): tree.type =
@@ -113,13 +117,10 @@ class CheckUnused private (phaseMode: PhaseMode, suffix: String) extends MiniPha
113
117
ctx
114
118
115
119
override def prepareForAssign (tree : Assign )(using Context ): Context =
116
- tree.lhs.putAttachment(Ignore , ()) // don't take LHS reference as a read
120
+ tree.lhs.putAttachment(AssignmentTarget , ()) // don't take LHS reference as a read
117
121
ctx
118
122
override def transformAssign (tree : Assign )(using Context ): tree.type =
119
- tree.lhs.removeAttachment(Ignore )
120
- val sym = tree.lhs.symbol
121
- if sym.exists then
122
- refInfos.asss.addOne(sym)
123
+ tree.lhs.removeAttachment(AssignmentTarget )
123
124
tree
124
125
125
126
override def prepareForMatch (tree : Match )(using Context ): Context =
@@ -269,7 +270,7 @@ class CheckUnused private (phaseMode: PhaseMode, suffix: String) extends MiniPha
269
270
// if sym is not an enclosing element, record the reference
270
271
def refUsage (sym : Symbol )(using Context ): Unit =
271
272
if ! ctx.outersIterator.exists(cur => cur.owner eq sym) then
272
- refInfos.refs.addOne (sym)
273
+ refInfos.addRef (sym)
273
274
274
275
/** Look up a reference in enclosing contexts to determine whether it was introduced by a definition or import.
275
276
* The binding of highest precedence must then be correct.
@@ -328,7 +329,7 @@ class CheckUnused private (phaseMode: PhaseMode, suffix: String) extends MiniPha
328
329
case none =>
329
330
330
331
// Avoid spurious NoSymbol and also primary ctors which are never warned about.
331
- // Selections C.this.toString should be already excluded, but backtopped here for eq, etc.
332
+ // Selections C.this.toString should be already excluded, but backstopped here for eq, etc.
332
333
if ! sym.exists || sym.isPrimaryConstructor || sym.isEffectiveRoot || defn.topClasses(sym.owner) then return
333
334
334
335
// Find the innermost, highest precedence. Contexts have no nesting levels but assume correctness.
@@ -398,7 +399,7 @@ class CheckUnused private (phaseMode: PhaseMode, suffix: String) extends MiniPha
398
399
end while
399
400
// record usage and possibly an import
400
401
if ! enclosed then
401
- refInfos.refs.addOne (sym)
402
+ refInfos.addRef (sym)
402
403
if candidate != NoContext && candidate.isImportContext && importer != null then
403
404
refInfos.sels.put(importer, ())
404
405
// possibly record that we have performed this look-up
@@ -437,6 +438,9 @@ object CheckUnused:
437
438
/** Ignore reference. */
438
439
val Ignore = Property .StickyKey [Unit ]
439
440
441
+ /** Tree is LHS of Assign. */
442
+ val AssignmentTarget = Property .StickyKey [Unit ]
443
+
440
444
class PostTyper extends CheckUnused (PhaseMode .Aggregate , " PostTyper" )
441
445
442
446
class PostInlining extends CheckUnused (PhaseMode .Report , " PostInlining" )
@@ -481,6 +485,14 @@ object CheckUnused:
481
485
482
486
val inlined = Stack .empty[SrcPos ] // enclosing call.srcPos of inlined code (expansions)
483
487
var inliners = 0 // depth of inline def (not inlined yet)
488
+
489
+ // instead of refs.addOne, use addRef to distinguish a read from a write to var
490
+ var isAssignment = false
491
+ def addRef (sym : Symbol ): Unit =
492
+ if isAssignment then
493
+ asss.addOne(sym)
494
+ else
495
+ refs.addOne(sym)
484
496
end RefInfos
485
497
486
498
// Symbols already resolved in the given Context (with name and prefix of lookup).
0 commit comments