@@ -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
@@ -48,16 +52,32 @@ object Annotations {
4852 }
4953
5054 abstract class LazyAnnotation extends Annotation {
51- override def symbol (implicit ctx : Context ): Symbol
52- def complete (implicit ctx : Context ): Tree
53-
54- private var myTree : Tree = null
55- def tree (implicit ctx : Context ): Tree = {
56- if (myTree == null ) myTree = complete(ctx)
57- myTree
58- }
55+ protected var mySym : Symbol | (Context => Symbol )
56+ override def symbol (using ctx : Context ): Symbol =
57+ assert(mySym != null )
58+ mySym match {
59+ case symFn : (Context => Symbol ) @ unchecked =>
60+ mySym = null
61+ mySym = symFn(ctx)
62+ case sym : Symbol if sym.defRunId != ctx.runId =>
63+ mySym = sym.denot.current.symbol
64+ case _ =>
65+ }
66+ mySym.asInstanceOf [Symbol ]
67+
68+ protected var myTree : Tree | (Context => Tree )
69+ def tree (using ctx : Context ): Tree =
70+ assert(myTree != null )
71+ myTree match {
72+ case treeFn : (Context => Tree ) @ unchecked =>
73+ myTree = null
74+ myTree = treeFn(ctx)
75+ case _ =>
76+ }
77+ myTree.asInstanceOf [Tree ]
5978
60- override def isEvaluated : Boolean = myTree != null
79+ override def isEvaluating : Boolean = myTree == null
80+ override def isEvaluated : Boolean = myTree.isInstanceOf [Tree ]
6181 }
6282
6383 /** An annotation indicating the body of a right-hand side,
@@ -72,24 +92,31 @@ object Annotations {
7292 override def ensureCompleted (implicit ctx : Context ): Unit = ()
7393 }
7494
75- case class ConcreteBodyAnnotation (body : Tree ) extends BodyAnnotation {
95+ class ConcreteBodyAnnotation (body : Tree ) extends BodyAnnotation {
7696 def tree (implicit ctx : Context ): Tree = body
7797 }
7898
79- case class LazyBodyAnnotation ( private var bodyExpr : Context => Tree ) extends BodyAnnotation {
80- // TODO: Make `bodyExpr` an IFT once #6865 os in bootstrap
81- private var evaluated = false
82- private var myBody : Tree = _
83- def tree ( implicit ctx : Context ) : Tree = {
84- if (evaluated) assert(myBody != null )
85- else {
86- evaluated = true
87- myBody = bodyExpr (ctx)
88- 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 _ =>
89109 }
90- myBody
91- }
92- 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)
93120 }
94121
95122 object Annotation {
@@ -120,23 +147,15 @@ object Annotations {
120147 /** Create an annotation where the tree is computed lazily. */
121148 def deferred (sym : Symbol )(treeFn : Context ?=> Tree )(implicit ctx : Context ): Annotation =
122149 new LazyAnnotation {
123- override def symbol ( implicit ctx : Context ) : Symbol = sym
124- def complete ( implicit ctx : Context ) = treeFn( using ctx)
150+ protected var myTree : Tree | ( Context => Tree ) = ctx => treeFn( using ctx)
151+ protected var mySym : Symbol | ( Context => Symbol ) = sym
125152 }
126153
127154 /** Create an annotation where the symbol and the tree are computed lazily. */
128- def deferredSymAndTree (symf : Context ?=> Symbol )(treeFn : Context ?=> Tree )(implicit ctx : Context ): Annotation =
155+ def deferredSymAndTree (symFn : Context ?=> Symbol )(treeFn : Context ?=> Tree )(implicit ctx : Context ): Annotation =
129156 new LazyAnnotation {
130- private var mySym : Symbol = _
131-
132- override def symbol (implicit ctx : Context ): Symbol = {
133- if (mySym == null || mySym.defRunId != ctx.runId) {
134- mySym = symf(using ctx)
135- assert(mySym != null )
136- }
137- mySym
138- }
139- def complete (implicit ctx : Context ) = treeFn(using ctx)
157+ protected var mySym : Symbol | (Context => Symbol ) = ctx => symFn(using ctx)
158+ protected var myTree : Tree | (Context => Tree ) = ctx => treeFn(using ctx)
140159 }
141160
142161 def deferred (atp : Type , args : List [Tree ])(implicit ctx : Context ): Annotation =
0 commit comments