Skip to content

Commit

Permalink
Fix bug in capture analysis of closures
Browse files Browse the repository at this point in the history
  • Loading branch information
liufengyun committed Aug 29, 2024
1 parent 31b6523 commit 41e9816
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 3 deletions.
9 changes: 6 additions & 3 deletions compiler/src/dotty/tools/dotc/transform/init/Objects.scala
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ class Objects(using Context @constructorOnly):
case vdef: ValDef =>
val sym = vdef.symbol
if sym.isLocal then defs += sym
traverseChildren(vdef.rhs)

case _ =>
traverseChildren(tree)
Expand Down Expand Up @@ -680,8 +681,10 @@ class Objects(using Context @constructorOnly):
val changeSetBefore = Heap.getChangeSet()
// Only perform footprint optimization for method context
val footprint =
if ctx == EvalContext.Method then Heap.footprint(Heap.getHeapData(), thisV, env, State.currentObjectRef)
else heapBefore
if ctx == EvalContext.Method then
Heap.footprint(Heap.getHeapData(), thisV, env, State.currentObjectRef)
else
heapBefore
val config = Config(thisV, env, footprint)

Heap.update(footprint, changeSet = Set.empty)
Expand Down Expand Up @@ -1267,7 +1270,7 @@ class Objects(using Context @constructorOnly):
* @param klass The enclosing class where the expression is located.
* @param ctx The context where `eval` is called.
*/
def eval(expr: Tree, thisV: ThisValue, klass: ClassSymbol, ctx: EvalContext = EvalContext.Other): Contextual[Value] = log("evaluating " + expr.show + ", this = " + thisV.show + ", regions = " + Regions.show + " in " + klass.show, printer, (_: Value).show) {
def eval(expr: Tree, thisV: ThisValue, klass: ClassSymbol, ctx: EvalContext = EvalContext.Other): Contextual[Value] = log("evaluating " + expr.show + ", this = " + thisV.show + ", heap size = " + Heap.getHeapData().size + " in " + klass.show, printer, (_: Value).show) {
cache.cachedEval(thisV, expr, ctx) { expr => cases(expr, thisV, klass) }
}

Expand Down
26 changes: 26 additions & 0 deletions tests/init-global/pos/footprint2.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
class BreakControl extends Throwable

object Breaks:
private val breakException = new BreakControl

def breakable(op: => Unit): Unit =
try op catch { case ex: BreakControl if ex eq breakException => }

def break(): Nothing = throw breakException

object A:
val n = foo("hello")
def foo(s: String): Int =
val len = s.length
var i = 0

while (i < len) {
Breaks.breakable {
val c = s.charAt(i)

if c == '\n' then Breaks.break()
}
i += 1
}

i

0 comments on commit 41e9816

Please sign in to comment.