Skip to content

Commit acf78ad

Browse files
committed
Clean up forcing logic for lazy tree fields
1 parent f3db79a commit acf78ad

File tree

5 files changed

+35
-48
lines changed

5 files changed

+35
-48
lines changed

compiler/src/dotty/tools/dotc/ast/NavigateAST.scala

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ package ast
44
import core.Contexts._
55
import core.Decorators._
66
import util.Spans._
7-
import Trees.{MemberDef, DefTree, WithLazyField}
7+
import Trees.{MemberDef, DefTree, WithLazyFields}
88
import dotty.tools.dotc.core.Types.AnnotatedType
99
import dotty.tools.dotc.core.Types.ImportType
1010
import dotty.tools.dotc.core.Types.Type
@@ -106,16 +106,14 @@ object NavigateAST {
106106
// FIXME: We shouldn't be manually forcing trees here, we should replace
107107
// our usage of `productIterator` by something in `Positioned` that takes
108108
// care of low-level details like this for us.
109-
p match {
110-
case p: WithLazyField[?] =>
111-
p.forceIfLazy
109+
p match
110+
case p: WithLazyFields => p.forceFields()
112111
case _ =>
113-
}
114112
val iterator = p match
115113
case defdef: DefTree[?] =>
116114
p.productIterator ++ defdef.mods.productIterator
117115
case _ =>
118-
p.productIterator
116+
p.productIterator
119117
childPath(iterator, p :: path)
120118
}
121119
else {

compiler/src/dotty/tools/dotc/ast/Trees.scala

Lines changed: 24 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -407,12 +407,12 @@ object Trees {
407407
}
408408

409409
/** A ValDef or DefDef tree */
410-
abstract class ValOrDefDef[+T <: Untyped](implicit @constructorOnly src: SourceFile) extends MemberDef[T] with WithLazyField[Tree[T]] {
410+
abstract class ValOrDefDef[+T <: Untyped](implicit @constructorOnly src: SourceFile) extends MemberDef[T], WithLazyFields {
411411
type ThisTree[+T <: Untyped] <: ValOrDefDef[T]
412412
def name: TermName
413413
def tpt: Tree[T]
414-
def unforcedRhs: LazyTree[T] = unforced
415-
def rhs(using Context): Tree[T] = forceIfLazy
414+
def unforcedRhs: LazyTree[T]
415+
def rhs(using Context): Tree[T]
416416
}
417417

418418
trait ValOrTypeDef[+T <: Untyped] extends MemberDef[T]:
@@ -808,8 +808,10 @@ object Trees {
808808
extends ValOrDefDef[T], ValOrTypeDef[T] {
809809
type ThisTree[+T <: Untyped] = ValDef[T]
810810
assert(isEmpty || (tpt ne genericEmptyTree))
811-
def unforced: LazyTree[T] = preRhs
812-
protected def force(x: Tree[T @uncheckedVariance]): Unit = preRhs = x
811+
812+
def unforcedRhs: LazyTree[T] = preRhs
813+
def forceFields()(using Context): Unit = preRhs = force(preRhs)
814+
def rhs(using Context): Tree[T] = { forceFields(); preRhs.asInstanceOf[Tree[T]] }
813815
}
814816

815817
/** mods def name[tparams](vparams_1)...(vparams_n): tpt = rhs */
@@ -818,8 +820,10 @@ object Trees {
818820
extends ValOrDefDef[T] {
819821
type ThisTree[+T <: Untyped] = DefDef[T]
820822
assert(tpt ne genericEmptyTree)
821-
def unforced: LazyTree[T] = preRhs
822-
protected def force(x: Tree[T @uncheckedVariance]): Unit = preRhs = x
823+
824+
def unforcedRhs: LazyTree[T] = preRhs
825+
def forceFields()(using Context): Unit = preRhs = force(preRhs)
826+
def rhs(using Context): Tree[T] = { forceFields(); preRhs.asInstanceOf[Tree[T]] }
823827

824828
def leadingTypeParams(using Context): List[TypeDef[T]] = paramss match
825829
case (tparams @ (tparam: TypeDef[_]) :: _) :: _ => tparams.asInstanceOf[List[TypeDef[T]]]
@@ -855,27 +859,17 @@ object Trees {
855859
* if this is of class untpd.DerivingTemplate.
856860
* Typed templates only have parents.
857861
*/
858-
case class Template[+T <: Untyped] private[ast] (constr: DefDef[T], private var myParentsOrDerived: LazyTreeList[T], self: ValDef[T], private var preBody: LazyTreeList[T])(implicit @constructorOnly src: SourceFile)
859-
extends DefTree[T] with WithLazyField[List[Tree[T]]] {
862+
case class Template[+T <: Untyped] private[ast] (constr: DefDef[T], private var preParentsOrDerived: LazyTreeList[T], self: ValDef[T], private var preBody: LazyTreeList[T])(implicit @constructorOnly src: SourceFile)
863+
extends DefTree[T] with WithLazyFields {
860864
type ThisTree[+T <: Untyped] = Template[T]
861-
def unforcedBody: LazyTreeList[T] = unforced
862-
def unforced: LazyTreeList[T] = preBody
863-
864-
protected def force(x: List[Tree[T @uncheckedVariance]]): Unit = preBody = x
865-
866-
// The post-condition of forceIfLazy is that all lazy fields are trees, so
867-
// we need to force parentsAndDerived as well as body.
868-
override def forceIfLazy(using Context) =
869-
parentsOrDerived
870-
super.forceIfLazy
871865

872-
def body(using Context): List[Tree[T]] = forceIfLazy
866+
def forceFields()(using Context): Unit =
867+
preParentsOrDerived = force(preParentsOrDerived)
868+
preBody = force(preBody)
873869

874-
def parentsOrDerived(using Context): List[Tree[T]] = myParentsOrDerived match
875-
case latePs: Lazy[List[Tree[T]]] @unchecked =>
876-
myParentsOrDerived = latePs.complete
877-
parentsOrDerived
878-
case ps: List[Tree[T]] @unchecked => ps
870+
def unforcedBody: LazyTreeList[T] = preBody
871+
def body(using Context): List[Tree[T]] = { forceFields(); preBody.asInstanceOf[List[Tree[T]]] }
872+
def parentsOrDerived(using Context): List[Tree[T]] = { forceFields(); preParentsOrDerived.asInstanceOf[List[Tree[T]]] }
879873

880874
def parents(using Context): List[Tree[T]] = parentsOrDerived // overridden by DerivingTemplate
881875
def derived: List[untpd.Tree] = Nil // overridden by DerivingTemplate
@@ -1027,17 +1021,11 @@ object Trees {
10271021
* accessed by `unforced` and `force`. Forcing the field will
10281022
* set the `var` to the underlying value.
10291023
*/
1030-
trait WithLazyField[+T <: AnyRef] {
1031-
def unforced: T | Lazy[T]
1032-
protected def force(x: T @uncheckedVariance): Unit
1033-
def forceIfLazy(using Context): T = unforced match {
1034-
case lzy: Lazy[T @unchecked] =>
1035-
val x = lzy.complete
1036-
force(x)
1037-
x
1038-
case x: T @ unchecked => x
1039-
}
1040-
}
1024+
trait WithLazyFields:
1025+
protected def force[T <: AnyRef](x: T | Lazy[T])(using Context): T = x match
1026+
case x: Lazy[T] @unchecked => x.complete
1027+
case x: T @unchecked => x
1028+
def forceFields()(using Context): Unit
10411029

10421030
/** A base trait for lazy tree fields.
10431031
* These can be instantiated with Lazy instances which

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import dotty.tools.tasty.TastyBuffer
88
import TastyBuffer._
99

1010
import ast._
11-
import Trees.WithLazyField
11+
import Trees.WithLazyFields
1212
import util.{SourceFile, NoSource}
1313
import core._
1414
import Annotations._, Decorators._
@@ -80,7 +80,7 @@ class PositionPickler(
8080
def alwaysNeedsPos(x: Positioned) = x match {
8181
case
8282
// initialSpan is inaccurate for trees with lazy field
83-
_: WithLazyField[?]
83+
_: WithLazyFields
8484

8585
// A symbol is created before the corresponding tree is unpickled,
8686
// and its position cannot be changed afterwards.

compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -737,8 +737,7 @@ private class ExtractAPICollector(using Context) extends ThunkHolder {
737737
var h = initHash
738738

739739
p match
740-
case p: WithLazyField[?] =>
741-
p.forceIfLazy
740+
case p: WithLazyFields => p.forceFields()
742741
case _ =>
743742

744743
if inlineOrigin.exists then

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -249,9 +249,11 @@ class TreeChecker extends Phase with SymTransformer {
249249
// case tree: untpd.Select =>
250250
// case tree: untpd.Bind =>
251251
case vd : ValDef =>
252-
assertIdentNotJavaClass(vd.forceIfLazy)
252+
vd.forceFields()
253+
assertIdentNotJavaClass(vd)
253254
case dd : DefDef =>
254-
assertIdentNotJavaClass(dd.forceIfLazy)
255+
dd.forceFields()
256+
assertIdentNotJavaClass(dd)
255257
// case tree: untpd.TypeDef =>
256258
case Apply(fun, args) =>
257259
assertIdentNotJavaClass(fun)

0 commit comments

Comments
 (0)