Skip to content

Commit 5101901

Browse files
committed
Make LazyBodyAnnotation more like LazyAnnotation
And address the TODO comment by adding an apply method that takes a `Context ?=> Tree`. Also add `Annotation#isEvaluating`, previously `LazyBodyAnnotation#isEvaluated` was also returning true when evaluation was started but not finished which was confusing.
1 parent 776bb54 commit 5101901

File tree

3 files changed

+31
-19
lines changed

3 files changed

+31
-19
lines changed

compiler/src/dotty/tools/dotc/core/Annotations.scala

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ object Annotations {
3535
def argumentConstant(i: Int)(implicit ctx: Context): Option[Constant] =
3636
for (ConstantType(c) <- argument(i) map (_.tpe)) yield c
3737

38+
/** The tree evaluaton is in progress. */
39+
def isEvaluating: Boolean = false
40+
41+
/** The tree evaluation has finished. */
3842
def isEvaluated: Boolean = true
3943

4044
def ensureCompleted(implicit ctx: Context): Unit = tree
@@ -72,6 +76,7 @@ object Annotations {
7276
}
7377
myTree.asInstanceOf[Tree]
7478

79+
override def isEvaluating: Boolean = myTree == null
7580
override def isEvaluated: Boolean = myTree.isInstanceOf[Tree]
7681
}
7782

@@ -87,24 +92,31 @@ object Annotations {
8792
override def ensureCompleted(implicit ctx: Context): Unit = ()
8893
}
8994

90-
case class ConcreteBodyAnnotation(body: Tree) extends BodyAnnotation {
95+
class ConcreteBodyAnnotation(body: Tree) extends BodyAnnotation {
9196
def tree(implicit ctx: Context): Tree = body
9297
}
9398

94-
case class LazyBodyAnnotation(private var bodyExpr: Context => Tree) extends BodyAnnotation {
95-
// TODO: Make `bodyExpr` an IFT once #6865 os in bootstrap
96-
private var evaluated = false
97-
private var myBody: Tree = _
98-
def tree(implicit ctx: Context): Tree = {
99-
if (evaluated) assert(myBody != null)
100-
else {
101-
evaluated = true
102-
myBody = bodyExpr(ctx)
103-
bodyExpr = null
99+
abstract class LazyBodyAnnotation extends BodyAnnotation {
100+
// Copy-pasted from LazyAnnotation to avoid having to turn it into a trait
101+
protected var myTree: Tree | (Context => Tree)
102+
def tree(using ctx: Context): Tree =
103+
assert(myTree != null)
104+
myTree match {
105+
case treeFn: (Context => Tree) @unchecked =>
106+
myTree = null
107+
myTree = treeFn(ctx)
108+
case _ =>
104109
}
105-
myBody
106-
}
107-
override def isEvaluated: Boolean = evaluated
110+
myTree.asInstanceOf[Tree]
111+
112+
override def isEvaluating: Boolean = myTree == null
113+
override def isEvaluated: Boolean = myTree.isInstanceOf[Tree]
114+
}
115+
116+
object LazyBodyAnnotation {
117+
def apply(bodyFn: Context ?=> Tree): LazyBodyAnnotation =
118+
new LazyBodyAnnotation:
119+
protected var myTree: Tree | (Context => Tree) = ctx => bodyFn(using ctx)
108120
}
109121

110122
object Annotation {

compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -581,9 +581,9 @@ class TreeUnpickler(reader: TastyReader,
581581
forkAt(templateStart).indexTemplateParams()(localContext(sym))
582582
}
583583
else if (sym.isInlineMethod)
584-
sym.addAnnotation(LazyBodyAnnotation { ctx0 =>
584+
sym.addAnnotation(LazyBodyAnnotation { (using ctx0: Context) =>
585585
val ctx1 = localContext(sym)(ctx0).addMode(Mode.ReadPositions)
586-
implicit val ctx: Context = sourceChangeContext(Addr(0))(ctx1)
586+
given Context = sourceChangeContext(Addr(0))(ctx1)
587587
// avoids space leaks by not capturing the current context
588588
forkAt(rhsStart).readTerm()
589589
})

compiler/src/dotty/tools/dotc/typer/PrepareInlineable.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -216,12 +216,12 @@ object PrepareInlineable {
216216
inlined: Symbol, treeExpr: Context => Tree)(implicit ctx: Context): Unit =
217217
inlined.unforcedAnnotation(defn.BodyAnnot) match {
218218
case Some(ann: ConcreteBodyAnnotation) =>
219-
case Some(ann: LazyBodyAnnotation) if ann.isEvaluated =>
219+
case Some(ann: LazyBodyAnnotation) if ann.isEvaluated || ann.isEvaluating =>
220220
case _ =>
221221
if (!ctx.isAfterTyper) {
222222
val inlineCtx = ctx
223-
inlined.updateAnnotation(LazyBodyAnnotation { _ =>
224-
implicit val ctx = inlineCtx
223+
inlined.updateAnnotation(LazyBodyAnnotation {
224+
given ctx as Context = inlineCtx
225225
val initialErrorCount = ctx.reporter.errorCount
226226
var inlinedBody = treeExpr(ctx)
227227
if (ctx.reporter.errorCount == initialErrorCount) {

0 commit comments

Comments
 (0)