@@ -1226,11 +1226,12 @@ class Objects(using Context @constructorOnly):
12261226 extendTrace(id) { evalType(prefix, thisV, klass) }
12271227
12281228 val value = eval(rhs, thisV, klass)
1229+ val widened = widenEscapedValue(value, rhs)
12291230
12301231 if isLocal then
1231- writeLocal(thisV, lhs.symbol, value )
1232+ writeLocal(thisV, lhs.symbol, widened )
12321233 else
1233- withTrace(trace2) { assign(receiver, lhs.symbol, value , rhs.tpe) }
1234+ withTrace(trace2) { assign(receiver, lhs.symbol, widened , rhs.tpe) }
12341235
12351236 case closureDef(ddef) =>
12361237 Fun (ddef, thisV, klass, summon[Env .Data ])
@@ -1568,6 +1569,28 @@ class Objects(using Context @constructorOnly):
15681569 throw new Exception (" unexpected type: " + tp + " , Trace:\n " + Trace .show)
15691570 }
15701571
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+
15711594 /** Evaluate arguments of methods and constructors */
15721595 def evalArgs (args : List [Arg ], thisV : ThisValue , klass : ClassSymbol ): Contextual [List [ArgInfo ]] =
15731596 val argInfos = new mutable.ArrayBuffer [ArgInfo ]
@@ -1578,23 +1601,7 @@ class Objects(using Context @constructorOnly):
15781601 else
15791602 eval(arg.tree, thisV, klass)
15801603
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)
15981605 argInfos += ArgInfo (widened, trace.add(arg.tree), arg.tree)
15991606 }
16001607 argInfos.toList
0 commit comments