Skip to content

Commit c88e224

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#notEvaluated`, previously `LazyBodyAnnotation#isEvaluated` was also returning true when evaluation was started but not finished which was confusing.
1 parent c5fb5c4 commit c88e224

File tree

3 files changed

+32
-19
lines changed

3 files changed

+32
-19
lines changed

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

Lines changed: 27 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+
/** Evaluation has not started */
39+
def notEvaluated: Boolean = false
40+
41+
/** Evaluation has finished */
3842
def isEvaluated: Boolean = true
3943

4044
def ensureCompleted(implicit ctx: Context): Unit = tree
@@ -75,6 +79,7 @@ object Annotations {
7579
myTree.asInstanceOf[Tree]
7680

7781
override def isEvaluated: Boolean = myTree.isInstanceOf[Tree]
82+
override def notEvaluated: Boolean = !isEvaluated && myTree != null
7883
}
7984

8085
/** An annotation indicating the body of a right-hand side,
@@ -89,24 +94,32 @@ object Annotations {
8994
override def ensureCompleted(implicit ctx: Context): Unit = ()
9095
}
9196

92-
case class ConcreteBodyAnnotation(body: Tree) extends BodyAnnotation {
97+
class ConcreteBodyAnnotation(body: Tree) extends BodyAnnotation {
9398
def tree(implicit ctx: Context): Tree = body
9499
}
95100

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

112125
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.notEvaluated =>
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)