@@ -1226,11 +1226,12 @@ class Objects(using Context @constructorOnly):
1226
1226
extendTrace(id) { evalType(prefix, thisV, klass) }
1227
1227
1228
1228
val value = eval(rhs, thisV, klass)
1229
+ val widened = widenEscapedValue(value, rhs)
1229
1230
1230
1231
if isLocal then
1231
- writeLocal(thisV, lhs.symbol, value )
1232
+ writeLocal(thisV, lhs.symbol, widened )
1232
1233
else
1233
- withTrace(trace2) { assign(receiver, lhs.symbol, value , rhs.tpe) }
1234
+ withTrace(trace2) { assign(receiver, lhs.symbol, widened , rhs.tpe) }
1234
1235
1235
1236
case closureDef(ddef) =>
1236
1237
Fun (ddef, thisV, klass, summon[Env .Data ])
@@ -1568,6 +1569,28 @@ class Objects(using Context @constructorOnly):
1568
1569
throw new Exception (" unexpected type: " + tp + " , Trace:\n " + Trace .show)
1569
1570
}
1570
1571
1572
+ /** Widen the escaped value (a method argument or rhs of an assignment)
1573
+ *
1574
+ * The default widening is 1 for most values, 2 for function values.
1575
+ * User-specified widening annotations are repected.
1576
+ */
1577
+ def widenEscapedValue (value : Value , expr : Tree ): Contextual [Value ] =
1578
+ expr.tpe.getAnnotation(defn.InitWidenAnnot ) match
1579
+ case Some (annot) =>
1580
+ annot.argument(0 ).get match
1581
+ case arg @ Literal (c : Constants .Constant ) =>
1582
+ val height = c.intValue
1583
+ if height < 0 then
1584
+ report.warning(" The argument should be positive" , arg)
1585
+ value.widen(1 )
1586
+ else
1587
+ value.widen(c.intValue)
1588
+ case arg =>
1589
+ report.warning(" The argument should be a constant integer value" , arg)
1590
+ value.widen(1 )
1591
+ case _ =>
1592
+ if value.isInstanceOf [Fun ] then value.widen(2 ) else value.widen(1 )
1593
+
1571
1594
/** Evaluate arguments of methods and constructors */
1572
1595
def evalArgs (args : List [Arg ], thisV : ThisValue , klass : ClassSymbol ): Contextual [List [ArgInfo ]] =
1573
1596
val argInfos = new mutable.ArrayBuffer [ArgInfo ]
@@ -1578,23 +1601,7 @@ class Objects(using Context @constructorOnly):
1578
1601
else
1579
1602
eval(arg.tree, thisV, klass)
1580
1603
1581
- val widened =
1582
- arg.tree.tpe.getAnnotation(defn.InitWidenAnnot ) match
1583
- case Some (annot) =>
1584
- annot.argument(0 ).get match
1585
- case arg @ Literal (c : Constants .Constant ) =>
1586
- val height = c.intValue
1587
- if height < 0 then
1588
- report.warning(" The argument should be positive" , arg)
1589
- res.widen(1 )
1590
- else
1591
- res.widen(c.intValue)
1592
- case arg =>
1593
- report.warning(" The argument should be a constant integer value" , arg)
1594
- res.widen(1 )
1595
- case _ =>
1596
- if res.isInstanceOf [Fun ] then res.widen(2 ) else res.widen(1 )
1597
-
1604
+ val widened = widenEscapedValue(res, arg.tree)
1598
1605
argInfos += ArgInfo (widened, trace.add(arg.tree), arg.tree)
1599
1606
}
1600
1607
argInfos.toList
0 commit comments