@@ -567,37 +567,42 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
567
567
case lhs =>
568
568
val lhsCore = typedUnadapted(lhs, AssignProto )
569
569
def lhs1 = typed(untpd.TypedSplice (lhsCore))
570
- def canAssign (sym : Symbol ) = // allow assignments from the primary constructor to class fields
570
+ lazy val lhsVal = lhsCore.asInstanceOf [TermRef ].denot.suchThat(! _.is(Method ))
571
+
572
+ def reassignmentToVal =
573
+ errorTree(cpy.Assign (tree)(lhsCore, typed(tree.rhs, lhs1.tpe.widen)),
574
+ " reassignment to val" )
575
+
576
+ def canAssign (sym : Symbol ) =
571
577
sym.is(Mutable , butNot = Accessor ) ||
572
578
ctx.owner.isPrimaryConstructor && ! sym.is(Method ) && sym.owner == ctx.owner.owner ||
579
+ // allow assignments from the primary constructor to class fields
573
580
ctx.owner.name.is(TraitSetterName ) || ctx.owner.isStaticConstructor
581
+
574
582
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
583
+ case ref : TermRef =>
584
+ val lhsVal = lhsCore.denot.suchThat(! _.is(Method ))
585
+ if (canAssign(lhsVal.symbol))
586
+ assignType(cpy.Assign (tree)(lhs1, typed(tree.rhs, lhsVal.info)))
587
+ else {
588
+ val pre = ref.prefix
589
+ val setterName = ref.name.setterName
590
+ val setter = pre.member(setterName)
591
+ lhsCore match {
592
+ case lhsCore : RefTree if setter.exists =>
593
+ val setterTypeRaw = pre.select(setterName, setter)
594
+ val setterType = ensureAccessible(setterTypeRaw, isSuperSelection(lhsCore), tree.pos)
595
+ val lhs2 = healNonvariant(
596
+ untpd.rename(lhsCore, setterName).withType(setterType), WildcardType )
597
+ typedUnadapted(cpy.Apply (tree)(untpd.TypedSplice (lhs2), tree.rhs :: Nil ))
598
+ case _ =>
599
+ reassignmentToVal
600
+ }
600
601
}
602
+ case TryDynamicCallType =>
603
+ typedDynamicAssign(tree, pt)
604
+ case tpe =>
605
+ reassignmentToVal
601
606
}
602
607
}
603
608
}
0 commit comments