Skip to content

Commit 41e9816

Browse files
committed
Fix bug in capture analysis of closures
1 parent 31b6523 commit 41e9816

File tree

2 files changed

+32
-3
lines changed

2 files changed

+32
-3
lines changed

compiler/src/dotty/tools/dotc/transform/init/Objects.scala

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ class Objects(using Context @constructorOnly):
255255
case vdef: ValDef =>
256256
val sym = vdef.symbol
257257
if sym.isLocal then defs += sym
258+
traverseChildren(vdef.rhs)
258259

259260
case _ =>
260261
traverseChildren(tree)
@@ -680,8 +681,10 @@ class Objects(using Context @constructorOnly):
680681
val changeSetBefore = Heap.getChangeSet()
681682
// Only perform footprint optimization for method context
682683
val footprint =
683-
if ctx == EvalContext.Method then Heap.footprint(Heap.getHeapData(), thisV, env, State.currentObjectRef)
684-
else heapBefore
684+
if ctx == EvalContext.Method then
685+
Heap.footprint(Heap.getHeapData(), thisV, env, State.currentObjectRef)
686+
else
687+
heapBefore
685688
val config = Config(thisV, env, footprint)
686689

687690
Heap.update(footprint, changeSet = Set.empty)
@@ -1267,7 +1270,7 @@ class Objects(using Context @constructorOnly):
12671270
* @param klass The enclosing class where the expression is located.
12681271
* @param ctx The context where `eval` is called.
12691272
*/
1270-
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) {
1273+
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) {
12711274
cache.cachedEval(thisV, expr, ctx) { expr => cases(expr, thisV, klass) }
12721275
}
12731276

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
class BreakControl extends Throwable
2+
3+
object Breaks:
4+
private val breakException = new BreakControl
5+
6+
def breakable(op: => Unit): Unit =
7+
try op catch { case ex: BreakControl if ex eq breakException => }
8+
9+
def break(): Nothing = throw breakException
10+
11+
object A:
12+
val n = foo("hello")
13+
def foo(s: String): Int =
14+
val len = s.length
15+
var i = 0
16+
17+
while (i < len) {
18+
Breaks.breakable {
19+
val c = s.charAt(i)
20+
21+
if c == '\n' then Breaks.break()
22+
}
23+
i += 1
24+
}
25+
26+
i

0 commit comments

Comments
 (0)