@@ -51,7 +51,6 @@ class CheckUnused private (phaseMode: PhaseMode, suffix: String) extends MiniPha
5151 tree
5252
5353 override def transformIdent (tree : Ident )(using Context ): tree.type =
54- refInfos.isAssignment = tree.hasAttachment(AssignmentTarget )
5554 if tree.symbol.exists then
5655 // if in an inline expansion, resolve at summonInline (synthetic pos) or in an enclosing call site
5756 val resolving =
@@ -67,12 +66,10 @@ class CheckUnused private (phaseMode: PhaseMode, suffix: String) extends MiniPha
6766 resolveUsage(tree.symbol, tree.name, tree.typeOpt.importPrefix.skipPackageObject, imports = resolving)
6867 else if tree.hasType then
6968 resolveUsage(tree.tpe.classSymbol, tree.name, tree.tpe.importPrefix.skipPackageObject)
70- refInfos.isAssignment = false
7169 tree
7270
7371 // import x.y; y may be rewritten x.y, also import x.z as y
7472 override def transformSelect (tree : Select )(using Context ): tree.type =
75- refInfos.isAssignment = tree.hasAttachment(AssignmentTarget )
7673 val name = tree.removeAttachment(OriginalName ).getOrElse(nme.NO_NAME )
7774 inline def isImportable = tree.qualifier.srcPos.isSynthetic
7875 && tree.qualifier.tpe.match
@@ -96,7 +93,6 @@ class CheckUnused private (phaseMode: PhaseMode, suffix: String) extends MiniPha
9693 resolveUsage(sym, name, tree.qualifier.tpe)
9794 else if ! ignoreTree(tree) then
9895 refUsage(sym)
99- refInfos.isAssignment = false
10096 tree
10197
10298 override def transformLiteral (tree : Literal )(using Context ): tree.type =
@@ -132,10 +128,11 @@ class CheckUnused private (phaseMode: PhaseMode, suffix: String) extends MiniPha
132128 tree
133129
134130 override def prepareForAssign (tree : Assign )(using Context ): Context =
135- tree.lhs.putAttachment(AssignmentTarget , ()) // don't take LHS reference as a read
131+ if tree.lhs.symbol.exists then
132+ refInfos.setAssignmentTarget(tree.lhs.symbol)
136133 ctx
137134 override def transformAssign (tree : Assign )(using Context ): tree.type =
138- tree.lhs.removeAttachment( AssignmentTarget )
135+ refInfos.resetAssignmentTarget( )
139136 tree
140137
141138 override def prepareForMatch (tree : Match )(using Context ): Context =
@@ -310,13 +307,15 @@ class CheckUnused private (phaseMode: PhaseMode, suffix: String) extends MiniPha
310307 for annot <- sym.denot.annotations do
311308 transformAllDeep(annot.tree)
312309
313- /** If sym is not an enclosing element with respect to the give context, record the reference
310+ /** If sym is not an enclosing element with respect to the given context, record the reference
314311 *
315312 * Also check that every enclosing element is not a synthetic member
316313 * of the sym's case class companion module.
314+ *
315+ * The LHS of a current Assign is never recorded as a reference (that is, a usage).
317316 */
318317 def refUsage (sym : Symbol )(using Context ): Unit =
319- if ! refInfos.hasRef(sym) then
318+ if ! refInfos.hasRef(sym) && ! refInfos.isAssignmentTarget(sym) then
320319 val isCase = sym.is(Case ) && sym.isClass
321320 if ! ctx.outersIterator.exists: outer =>
322321 val owner = outer.owner
@@ -505,9 +504,6 @@ object CheckUnused:
505504 /** Ignore reference. */
506505 val Ignore = Property .StickyKey [Unit ]
507506
508- /** Tree is LHS of Assign. */
509- val AssignmentTarget = Property .StickyKey [Unit ]
510-
511507 /** Tree is an inlined parameter. */
512508 val InlinedParameter = Property .StickyKey [Unit ]
513509
@@ -559,18 +555,18 @@ object CheckUnused:
559555
560556 var inliners = 0 // depth of inline def (not inlined yet)
561557
562- // instead of refs.addOne, use refUsage -> addRef to distinguish a read from a write to var
563- var isAssignment = false
558+ private var assignmentTarget : Symbol = NoSymbol
559+ def isAssignmentTarget (sym : Symbol ): Boolean = sym eq assignmentTarget
560+ def resetAssignmentTarget (): Unit =
561+ assignmentTarget = NoSymbol
562+ def setAssignmentTarget (sym : Symbol ): Unit =
563+ assignmentTarget = sym
564+ asss.addOne(sym)
565+ // @pre !isAssignmentTarget(sym), see refUsage
564566 def addRef (sym : Symbol ): Unit =
565- if isAssignment then
566- asss.addOne(sym)
567- else
568- refs.addOne(sym)
567+ refs.addOne(sym)
569568 def hasRef (sym : Symbol ): Boolean =
570- if isAssignment then
571- asss(sym)
572- else
573- refs(sym)
569+ refs(sym)
574570
575571 // currently compiletime.testing is completely erased, so ignore the unit
576572 var isNullified = false
0 commit comments