@@ -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 }
0 commit comments