@@ -52,6 +52,7 @@ class CheckUnused private (phaseMode: PhaseMode, suffix: String) extends MiniPha
5252    tree
5353
5454  override  def  transformIdent (tree : Ident )(using  Context ):  tree.type  = 
55+     refInfos.isAssignment =  tree.hasAttachment(AssignmentTarget )
5556    if  tree.symbol.exists then 
5657      //  if in an inline expansion, resolve at summonInline (synthetic pos) or in an enclosing call site
5758      val  resolving  = 
@@ -68,10 +69,12 @@ class CheckUnused private (phaseMode: PhaseMode, suffix: String) extends MiniPha
6869        resolveUsage(tree.symbol, tree.name, tree.typeOpt.importPrefix.skipPackageObject)
6970    else  if  tree.hasType then 
7071      resolveUsage(tree.tpe.classSymbol, tree.name, tree.tpe.importPrefix.skipPackageObject)
72+     refInfos.isAssignment =  false 
7173    tree
7274
7375  //  import x.y; y may be rewritten x.y, also import x.z as y
7476  override  def  transformSelect (tree : Select )(using  Context ):  tree.type  = 
77+     refInfos.isAssignment =  tree.hasAttachment(AssignmentTarget )
7578    val  name  =  tree.removeAttachment(OriginalName ).getOrElse(nme.NO_NAME )
7679    inline  def  isImportable  =  tree.qualifier.srcPos.isSynthetic
7780      &&  tree.qualifier.tpe.match 
@@ -92,6 +95,7 @@ class CheckUnused private (phaseMode: PhaseMode, suffix: String) extends MiniPha
9295        resolveUsage(tree.symbol, name, tree.qualifier.tpe)
9396    else  if  ! ignoreTree(tree) then 
9497      refUsage(tree.symbol)
98+     refInfos.isAssignment =  false 
9599    tree
96100
97101  override  def  transformLiteral (tree : Literal )(using  Context ):  tree.type  = 
@@ -113,13 +117,10 @@ class CheckUnused private (phaseMode: PhaseMode, suffix: String) extends MiniPha
113117    ctx
114118
115119  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
117121    ctx
118122  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 )
123124    tree
124125
125126  override  def  prepareForMatch (tree : Match )(using  Context ):  Context  = 
@@ -276,7 +277,7 @@ class CheckUnused private (phaseMode: PhaseMode, suffix: String) extends MiniPha
276277  //  if sym is not an enclosing element, record the reference
277278  def  refUsage (sym : Symbol )(using  Context ):  Unit  = 
278279    if  ! ctx.outersIterator.exists(cur =>  cur.owner eq sym) then 
279-       refInfos.refs.addOne (sym)
280+       refInfos.addRef (sym)
280281
281282  /**  Look up a reference in enclosing contexts to determine whether it was introduced by a definition or import. 
282283   *  The binding of highest precedence must then be correct. 
@@ -335,7 +336,7 @@ class CheckUnused private (phaseMode: PhaseMode, suffix: String) extends MiniPha
335336        case  none => 
336337
337338    //  Avoid spurious NoSymbol and also primary ctors which are never warned about.
338-     //  Selections C.this.toString should be already excluded, but backtopped  here for eq, etc.
339+     //  Selections C.this.toString should be already excluded, but backstopped  here for eq, etc.
339340    if  ! sym.exists ||  sym.isPrimaryConstructor ||  sym.isEffectiveRoot ||  defn.topClasses(sym.owner) then  return 
340341
341342    //  Find the innermost, highest precedence. Contexts have no nesting levels but assume correctness.
@@ -404,7 +405,7 @@ class CheckUnused private (phaseMode: PhaseMode, suffix: String) extends MiniPha
404405            candidate =  cur
405406    end while 
406407    //  record usage and possibly an import
407-     refInfos.refs.addOne (sym)
408+     refInfos.addRef (sym)
408409    if  candidate !=  NoContext  &&  candidate.isImportContext &&  importer !=  null  then 
409410      refInfos.sels.put(importer, ())
410411    //  possibly record that we have performed this look-up
@@ -443,6 +444,9 @@ object CheckUnused:
443444  /**  Ignore reference. */  
444445  val  Ignore  =  Property .StickyKey [Unit ]
445446
447+   /**  Tree is LHS of Assign. */  
448+   val  AssignmentTarget  =  Property .StickyKey [Unit ]
449+ 
446450  class  PostTyper  extends  CheckUnused (PhaseMode .Aggregate , " PostTyper" 
447451
448452  class  PostInlining  extends  CheckUnused (PhaseMode .Report , " PostInlining" 
@@ -487,6 +491,14 @@ object CheckUnused:
487491
488492    val  inlined  =  Stack .empty[SrcPos ] //  enclosing call.srcPos of inlined code (expansions)
489493    var  inliners  =  0  //  depth of inline def (not inlined yet)
494+ 
495+     //  instead of refs.addOne, use addRef to distinguish a read from a write to var
496+     var  isAssignment  =  false 
497+     def  addRef (sym : Symbol ):  Unit  = 
498+       if  isAssignment then 
499+         asss.addOne(sym)
500+       else 
501+         refs.addOne(sym)
490502  end  RefInfos 
491503
492504  //  Symbols already resolved in the given Context (with name and prefix of lookup).
0 commit comments