Skip to content

Commit 5514655

Browse files
authored
Merge pull request #2346 from dotty-staging/fix-#2345
Fix #2345: Handle case of overloaded local vars in assignment
2 parents 4961709 + 64cdb43 commit 5514655

File tree

2 files changed

+36
-26
lines changed

2 files changed

+36
-26
lines changed

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -567,37 +567,41 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
567567
case lhs =>
568568
val lhsCore = typedUnadapted(lhs, AssignProto)
569569
def lhs1 = typed(untpd.TypedSplice(lhsCore))
570-
def canAssign(sym: Symbol) = // allow assignments from the primary constructor to class fields
570+
571+
def reassignmentToVal =
572+
errorTree(cpy.Assign(tree)(lhsCore, typed(tree.rhs, lhs1.tpe.widen)),
573+
"reassignment to val")
574+
575+
def canAssign(sym: Symbol) =
571576
sym.is(Mutable, butNot = Accessor) ||
572577
ctx.owner.isPrimaryConstructor && !sym.is(Method) && sym.owner == ctx.owner.owner ||
578+
// allow assignments from the primary constructor to class fields
573579
ctx.owner.name.is(TraitSetterName) || ctx.owner.isStaticConstructor
580+
574581
lhsCore.tpe match {
575-
case ref: TermRef if canAssign(ref.symbol) =>
576-
assignType(cpy.Assign(tree)(lhs1, typed(tree.rhs, ref.info)))
577-
case _ =>
578-
def reassignmentToVal =
579-
errorTree(cpy.Assign(tree)(lhsCore, typed(tree.rhs, lhs1.tpe.widen)),
580-
"reassignment to val")
581-
lhsCore.tpe match {
582-
case ref: TermRef => // todo: further conditions to impose on getter?
583-
val pre = ref.prefix
584-
val setterName = ref.name.setterName
585-
val setter = pre.member(setterName)
586-
lhsCore match {
587-
case lhsCore: RefTree if setter.exists =>
588-
val setterTypeRaw = pre.select(setterName, setter)
589-
val setterType = ensureAccessible(setterTypeRaw, isSuperSelection(lhsCore), tree.pos)
590-
val lhs2 = healNonvariant(
591-
untpd.rename(lhsCore, setterName).withType(setterType), WildcardType)
592-
typedUnadapted(cpy.Apply(tree)(untpd.TypedSplice(lhs2), tree.rhs :: Nil))
593-
case _ =>
594-
reassignmentToVal
595-
}
596-
case TryDynamicCallType =>
597-
typedDynamicAssign(tree, pt)
598-
case tpe =>
599-
reassignmentToVal
582+
case ref: TermRef =>
583+
val lhsVal = lhsCore.denot.suchThat(!_.is(Method))
584+
if (canAssign(lhsVal.symbol))
585+
assignType(cpy.Assign(tree)(lhs1, typed(tree.rhs, lhsVal.info)))
586+
else {
587+
val pre = ref.prefix
588+
val setterName = ref.name.setterName
589+
val setter = pre.member(setterName)
590+
lhsCore match {
591+
case lhsCore: RefTree if setter.exists =>
592+
val setterTypeRaw = pre.select(setterName, setter)
593+
val setterType = ensureAccessible(setterTypeRaw, isSuperSelection(lhsCore), tree.pos)
594+
val lhs2 = healNonvariant(
595+
untpd.rename(lhsCore, setterName).withType(setterType), WildcardType)
596+
typedUnadapted(cpy.Apply(tree)(untpd.TypedSplice(lhs2), tree.rhs :: Nil))
597+
case _ =>
598+
reassignmentToVal
599+
}
600600
}
601+
case TryDynamicCallType =>
602+
typedDynamicAssign(tree, pt)
603+
case tpe =>
604+
reassignmentToVal
601605
}
602606
}
603607
}

tests/pos/i2345.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import scala.collection.mutable
2+
3+
abstract class Whatever[A] extends mutable.Set[A] {
4+
private[this] var count = 0
5+
count = 0
6+
}

0 commit comments

Comments
 (0)