Skip to content

Commit

Permalink
Widen values in assignment
Browse files Browse the repository at this point in the history
  • Loading branch information
liufengyun committed Aug 29, 2024
1 parent 5e83606 commit 533ee8a
Showing 1 changed file with 26 additions and 19 deletions.
45 changes: 26 additions & 19 deletions compiler/src/dotty/tools/dotc/transform/init/Objects.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1226,11 +1226,12 @@ class Objects(using Context @constructorOnly):
extendTrace(id) { evalType(prefix, thisV, klass) }

val value = eval(rhs, thisV, klass)
val widened = widenEscapedValue(value, rhs)

if isLocal then
writeLocal(thisV, lhs.symbol, value)
writeLocal(thisV, lhs.symbol, widened)
else
withTrace(trace2) { assign(receiver, lhs.symbol, value, rhs.tpe) }
withTrace(trace2) { assign(receiver, lhs.symbol, widened, rhs.tpe) }

case closureDef(ddef) =>
Fun(ddef, thisV, klass, summon[Env.Data])
Expand Down Expand Up @@ -1568,6 +1569,28 @@ class Objects(using Context @constructorOnly):
throw new Exception("unexpected type: " + tp + ", Trace:\n" + Trace.show)
}

/** Widen the escaped value (a method argument or rhs of an assignment)
*
* The default widening is 1 for most values, 2 for function values.
* User-specified widening annotations are repected.
*/
def widenEscapedValue(value: Value, expr: Tree): Contextual[Value] =
expr.tpe.getAnnotation(defn.InitWidenAnnot) match
case Some(annot) =>
annot.argument(0).get match
case arg @ Literal(c: Constants.Constant) =>
val height = c.intValue
if height < 0 then
report.warning("The argument should be positive", arg)
value.widen(1)
else
value.widen(c.intValue)
case arg =>
report.warning("The argument should be a constant integer value", arg)
value.widen(1)
case _ =>
if value.isInstanceOf[Fun] then value.widen(2) else value.widen(1)

/** Evaluate arguments of methods and constructors */
def evalArgs(args: List[Arg], thisV: ThisValue, klass: ClassSymbol): Contextual[List[ArgInfo]] =
val argInfos = new mutable.ArrayBuffer[ArgInfo]
Expand All @@ -1578,23 +1601,7 @@ class Objects(using Context @constructorOnly):
else
eval(arg.tree, thisV, klass)

val widened =
arg.tree.tpe.getAnnotation(defn.InitWidenAnnot) match
case Some(annot) =>
annot.argument(0).get match
case arg @ Literal(c: Constants.Constant) =>
val height = c.intValue
if height < 0 then
report.warning("The argument should be positive", arg)
res.widen(1)
else
res.widen(c.intValue)
case arg =>
report.warning("The argument should be a constant integer value", arg)
res.widen(1)
case _ =>
if res.isInstanceOf[Fun] then res.widen(2) else res.widen(1)

val widened = widenEscapedValue(res, arg.tree)
argInfos += ArgInfo(widened, trace.add(arg.tree), arg.tree)
}
argInfos.toList
Expand Down

0 comments on commit 533ee8a

Please sign in to comment.