@@ -567,37 +567,41 @@ 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
+
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 ) =
571
576
sym.is(Mutable , butNot = Accessor ) ||
572
577
ctx.owner.isPrimaryConstructor && ! sym.is(Method ) && sym.owner == ctx.owner.owner ||
578
+ // allow assignments from the primary constructor to class fields
573
579
ctx.owner.name.is(TraitSetterName ) || ctx.owner.isStaticConstructor
580
+
574
581
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
+ }
600
600
}
601
+ case TryDynamicCallType =>
602
+ typedDynamicAssign(tree, pt)
603
+ case tpe =>
604
+ reassignmentToVal
601
605
}
602
606
}
603
607
}
0 commit comments