@@ -567,37 +567,42 @@ 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+ 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 ) =
571577 sym.is(Mutable , butNot = Accessor ) ||
572578 ctx.owner.isPrimaryConstructor && ! sym.is(Method ) && sym.owner == ctx.owner.owner ||
579+ // allow assignments from the primary constructor to class fields
573580 ctx.owner.name.is(TraitSetterName ) || ctx.owner.isStaticConstructor
581+
574582 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+ }
600601 }
602+ case TryDynamicCallType =>
603+ typedDynamicAssign(tree, pt)
604+ case tpe =>
605+ reassignmentToVal
601606 }
602607 }
603608 }
0 commit comments