Skip to content

Commit b4d9b78

Browse files
committed
Simplify CapturedVars phase
No need for a separate entry in the context's store; we can keep everything in the phase itself, which is more efficient and modular. # Conflicts: # compiler/src/dotty/tools/dotc/transform/CapturedVars.scala
1 parent 0eaef1b commit b4d9b78

File tree

1 file changed

+20
-33
lines changed

1 file changed

+20
-33
lines changed

compiler/src/dotty/tools/dotc/transform/CapturedVars.scala

Lines changed: 20 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -13,23 +13,20 @@ import core.NameKinds.TempResultName
1313
import core.Constants._
1414
import util.Store
1515
import dotty.tools.uncheckedNN
16+
import ast.tpd.*
17+
import compiletime.uninitialized
1618

1719
/** This phase translates variables that are captured in closures to
1820
* heap-allocated refs.
1921
*/
2022
class CapturedVars extends MiniPhase with IdentityDenotTransformer:
2123
thisPhase =>
22-
import ast.tpd._
2324

2425
override def phaseName: String = CapturedVars.name
2526

2627
override def description: String = CapturedVars.description
2728

28-
private[this] var Captured: Store.Location[util.ReadOnlySet[Symbol]] = _
29-
private def captured(using Context) = ctx.store(Captured)
30-
31-
override def initContext(ctx: FreshContext): Unit =
32-
Captured = ctx.addLocation(util.ReadOnlySet.empty)
29+
private val captured = util.HashSet[Symbol]()
3330

3431
private class RefInfo(using Context) {
3532
/** The classes for which a Ref type exists. */
@@ -55,33 +52,10 @@ class CapturedVars extends MiniPhase with IdentityDenotTransformer:
5552
myRefInfo.uncheckedNN
5653
}
5754

58-
private class CollectCaptured extends TreeTraverser {
59-
private val captured = util.HashSet[Symbol]()
60-
def traverse(tree: Tree)(using Context) = tree match {
61-
case id: Ident =>
62-
val sym = id.symbol
63-
if (sym.is(Mutable, butNot = Method) && sym.owner.isTerm) {
64-
val enclMeth = ctx.owner.enclosingMethod
65-
if (sym.enclosingMethod != enclMeth) {
66-
report.log(i"capturing $sym in ${sym.enclosingMethod}, referenced from $enclMeth")
67-
captured += sym
68-
}
69-
}
70-
case _ =>
71-
traverseChildren(tree)
72-
}
73-
def runOver(tree: Tree)(using Context): util.ReadOnlySet[Symbol] = {
74-
traverse(tree)
75-
captured
76-
}
77-
}
78-
79-
override def prepareForUnit(tree: Tree)(using Context): Context = {
80-
val captured = atPhase(thisPhase) {
81-
CollectCaptured().runOver(ctx.compilationUnit.tpdTree)
82-
}
83-
ctx.fresh.updateStore(Captured, captured)
84-
}
55+
override def prepareForUnit(tree: Tree)(using Context): Context =
56+
captured.clear()
57+
atPhase(thisPhase)(CapturedVars.collect(captured)).traverse(tree)
58+
ctx
8559

8660
/** The {Volatile|}{Int|Double|...|Object}Ref class corresponding to the class `cls`,
8761
* depending on whether the reference should be @volatile
@@ -141,3 +115,16 @@ class CapturedVars extends MiniPhase with IdentityDenotTransformer:
141115
object CapturedVars:
142116
val name: String = "capturedVars"
143117
val description: String = "represent vars captured by closures as heap objects"
118+
119+
def collect(captured: util.HashSet[Symbol]): TreeTraverser = new:
120+
def traverse(tree: Tree)(using Context) = tree match
121+
case id: Ident =>
122+
val sym = id.symbol
123+
if sym.is(Mutable, butNot = Method) && sym.owner.isTerm then
124+
val enclMeth = ctx.owner.enclosingMethod
125+
if sym.enclosingMethod != enclMeth then
126+
report.log(i"capturing $sym in ${sym.enclosingMethod}, referenced from $enclMeth")
127+
captured += sym
128+
case _ =>
129+
traverseChildren(tree)
130+
end CapturedVars

0 commit comments

Comments
 (0)