@@ -23,6 +23,7 @@ import scala.util.chaining._
23
23
import mutable .ListBuffer
24
24
import symtab .Flags ._
25
25
import Mode ._
26
+ import PartialFunction .cond
26
27
27
28
/** A provider of methods to assign types to trees.
28
29
*
@@ -5083,25 +5084,17 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
5083
5084
// The enclosing context may be case c @ C(_) => or val c @ C(_) = v.
5084
5085
tree1 modifyType (_.finalResultType)
5085
5086
tree1
5086
- case tree1@ Apply (fun1, arg1:: Nil )if tree.hasAttachment[RightAssociative .type ]=>
5087
- tree.removeAttachment[RightAssociative .type ]
5087
+ case tree1@ Apply (fun1, arg1:: Nil )if ! phase.erasedTypes&& tree.hasAttachment[RightAssociative .type ]=>
5088
5088
fun1.tpematch {
5089
5089
// fix evaluation order of `x op_: y` if necessary to `{ val tmp = x ; y.op_:(tmp) }`
5090
5090
case MethodType (p:: Nil , _)if ! tree1.isErroneous&& ! p.isByNameParam&& (! treeInfo.isStableIdentifier(arg1, allowVolatile= false )|| ! treeInfo.isExprSafeToInline(arg1))=>
5091
- import symtab .Flags ._
5092
- val tmp = freshTermName(nme.RIGHT_ASSOC_OP_PREFIX )
5093
- val valSym = context.owner.newValue(tmp, arg1.pos.focus,FINAL | SYNTHETIC | ARTIFACT )
5094
- val rhs = arg1.changeOwner(context.owner-> valSym)
5095
- valSym.setInfo(rhs.tpe)
5096
- val liftedArg = atPos(arg1.pos) {ValDef (valSym, rhs) }
5097
- val blk = Block (
5098
- liftedArg:: Nil ,
5099
- treeCopy.Apply (tree1, fun1,List (Ident (valSym) setPos arg1.pos.focus)).clearType()
5100
- )
5101
- typed(blk, mode, pt)match {
5102
- case b@ Block (_, res)=> res.updateAttachment(RightAssociative ) ; b
5103
- case b=> b
5104
- }
5091
+ val vsym = context.owner.newValue(freshTermName(nme.RIGHT_ASSOC_OP_PREFIX ), arg1.pos.focus,FINAL | SYNTHETIC | ARTIFACT )
5092
+ vsym.setInfo(arg1.tpe)
5093
+ val vdef = atPos(arg1.pos) {ValDef (vsym, arg1) setTypeNoType }
5094
+ context.pendingStabilizers::= vdef
5095
+ arg1.changeOwner(context.owner-> vsym)
5096
+ val arg = Ident (vsym) setType singleType(NoPrefix , vsym) setPos arg1.pos.focus
5097
+ treeCopy.Apply (tree1, fun1, arg:: Nil )
5105
5098
case _=> tree1
5106
5099
}
5107
5100
case tree1@ Apply (_, args1)if settings.multiargInfix&& tree.hasAttachment[MultiargInfixAttachment .type ]&& args1.lengthCompare(1 )> 0 =>
@@ -6081,15 +6074,30 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
6081
6074
}
6082
6075
}
6083
6076
6077
+ // Insert stabilizing ValDefs (if any) introduced during the typing of the original expression.
6084
6078
private def addStabilizers (newStabilizers :List [Tree ],expr :Tree ): Tree = if (newStabilizers.isEmpty) exprelse {
6085
6079
devWarningIf(newStabilizers.forall(_.symbol.owner== context.owner))(s " ${context.owner} - ${(newStabilizers.map(vd=> (vd.symbol, vd.symbol.owner.fullNameString)), context.owner)}" )
6086
- // Insert stabilizing ValDefs (if any) which might have been introduced during the typing of the original expression.
6087
- exprmatch {
6088
- case Block (_, res)if res.hasAttachment[RightAssociative .type ]=>
6089
- runReporting.warning(res.pos,s " right-associative application requires evaluating right-to-left " ,WarningCategory .Other , context.owner)
6090
- case _=>
6091
- }
6092
- Block (newStabilizers.reverse, expr).setPos(expr.pos).setType(expr.tpe)
6080
+ def isStab (prefix :String )(x :Tree )= cond(x) {case ValDef (_, nm, _, _)=> nm.startsWith(prefix) }
6081
+ val hasStabs = newStabilizers.exists(isStab(nme.STABILIZER_PREFIX ))
6082
+ val hasRassocs = newStabilizers.exists(isStab(nme.RIGHT_ASSOC_OP_PREFIX ))
6083
+ // stabilizers are in reverse order, but re-ordered operands are in desired (left-to-right) order
6084
+ val res =
6085
+ if (hasStabs&& hasRassocs) {
6086
+ runReporting.warning(expr.pos.focus,s " right-associative application requires right-to-left evaluation " ,WarningCategory .Other , context.owner)
6087
+ var remaining = newStabilizers.reverse
6088
+ val ordered = ListBuffer .empty[Tree ]
6089
+ while (remaining.nonEmpty) {
6090
+ val (stabs, more)= remaining.span(isStab(nme.STABILIZER_PREFIX ))
6091
+ ordered.addAll(stabs)
6092
+ val (rassocs, rest)= more.span(isStab(nme.RIGHT_ASSOC_OP_PREFIX ))
6093
+ ordered.addAll(rassocs.reverse)
6094
+ remaining= rest
6095
+ }
6096
+ ordered.toList
6097
+ }
6098
+ else if (hasStabs) newStabilizers.reverse
6099
+ else newStabilizers
6100
+ Block (res, expr).setPos(expr.pos).setType(expr.tpe)
6093
6101
}
6094
6102
6095
6103
def atOwner (owner :Symbol ): Typer =