Skip to content

Commit 3419fb7

Browse files
committed
Strengthen type of LazyTree
1 parent d8ac6cd commit 3419fb7

File tree

2 files changed

+23
-21
lines changed

2 files changed

+23
-21
lines changed

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

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,6 @@ object Trees {
3333
/** Property key for trees with documentation strings attached */
3434
val DocComment: Property.StickyKey[Comments.Comment] = new Property.StickyKey
3535

36-
type LazyTree = AnyRef /* really: Tree | Lazy[Tree] */
37-
type LazyTreeList = AnyRef /* really: List[Tree] | Lazy[List[Tree]] */
38-
3936
/** Trees take a parameter indicating what the type of their `tpe` field
4037
* is. Two choices: `Type` or `Untyped`.
4138
* Untyped trees have type `Tree[Untyped]`.
@@ -236,6 +233,9 @@ object Trees {
236233
override def getMessage: String = s"type of $tree is not assigned"
237234
}
238235

236+
type LazyTree[-T >: Untyped] = Tree[T] | Lazy[Tree[T]]
237+
type LazyTreeList[-T >: Untyped] = List[Tree[T]] | Lazy[List[Tree[T]]]
238+
239239
// ------ Categories of trees -----------------------------------
240240

241241
/** Instances of this class are trees for which isType is definitely true.
@@ -361,7 +361,7 @@ object Trees {
361361
type ThisTree[-T >: Untyped] <: ValOrDefDef[T]
362362
def name: TermName
363363
def tpt: Tree[T]
364-
def unforcedRhs: LazyTree = unforced
364+
def unforcedRhs: LazyTree[T] = unforced
365365
def rhs(implicit ctx: Context): Tree[T] = forceIfLazy
366366

367367
/** Is this a `BackquotedValDef` or `BackquotedDefDef` ? */
@@ -727,36 +727,36 @@ object Trees {
727727
}
728728

729729
/** mods val name: tpt = rhs */
730-
case class ValDef[-T >: Untyped] private[ast] (name: TermName, tpt: Tree[T], private var preRhs: LazyTree)(implicit @constructorOnly src: SourceFile)
730+
case class ValDef[-T >: Untyped] private[ast] (name: TermName, tpt: Tree[T], private var preRhs: LazyTree[T @uncheckedVariance])(implicit @constructorOnly src: SourceFile)
731731
extends ValOrDefDef[T] {
732732
type ThisTree[-T >: Untyped] = ValDef[T]
733733
assert(isEmpty || tpt != genericEmptyTree)
734-
def unforced: LazyTree = preRhs
735-
protected def force(x: AnyRef): Unit = preRhs = x
734+
def unforced: LazyTree[T] = preRhs
735+
protected def force(x: Tree[T @uncheckedVariance]): Unit = preRhs = x
736736
}
737737

738-
class BackquotedValDef[-T >: Untyped] private[ast] (name: TermName, tpt: Tree[T], preRhs: LazyTree)(implicit @constructorOnly src: SourceFile)
738+
class BackquotedValDef[-T >: Untyped] private[ast] (name: TermName, tpt: Tree[T], preRhs: LazyTree[T @uncheckedVariance])(implicit @constructorOnly src: SourceFile)
739739
extends ValDef[T](name, tpt, preRhs) {
740740
override def isBackquoted: Boolean = true
741741
override def productPrefix: String = "BackquotedValDef"
742742
}
743743

744744
/** mods def name[tparams](vparams_1)...(vparams_n): tpt = rhs */
745745
case class DefDef[-T >: Untyped] private[ast] (name: TermName, tparams: List[TypeDef[T]],
746-
vparamss: List[List[ValDef[T]]], tpt: Tree[T], private var preRhs: LazyTree)(implicit @constructorOnly src: SourceFile)
746+
vparamss: List[List[ValDef[T]]], tpt: Tree[T], private var preRhs: LazyTree[T @uncheckedVariance])(implicit @constructorOnly src: SourceFile)
747747
extends ValOrDefDef[T] {
748748
type ThisTree[-T >: Untyped] = DefDef[T]
749749
assert(tpt != genericEmptyTree)
750-
def unforced: LazyTree = preRhs
751-
protected def force(x: AnyRef): Unit = preRhs = x
750+
def unforced: LazyTree[T] = preRhs
751+
protected def force(x: Tree[T @uncheckedVariance]): Unit = preRhs = x
752752

753753
override def disableOverlapChecks = rawMods.is(Delegate)
754754
// disable order checks for implicit aliases since their given clause follows
755755
// their for clause, but the two appear swapped in the DefDef.
756756
}
757757

758758
class BackquotedDefDef[-T >: Untyped] private[ast] (name: TermName, tparams: List[TypeDef[T]],
759-
vparamss: List[List[ValDef[T]]], tpt: Tree[T], preRhs: LazyTree)(implicit @constructorOnly src: SourceFile)
759+
vparamss: List[List[ValDef[T]]], tpt: Tree[T], preRhs: LazyTree[T])(implicit @constructorOnly src: SourceFile)
760760
extends DefDef[T](name, tparams, vparamss, tpt, preRhs) {
761761
override def isBackquoted: Boolean = true
762762
override def productPrefix: String = "BackquotedDefDef"
@@ -780,12 +780,12 @@ object Trees {
780780
* if this is of class untpd.DerivingTemplate.
781781
* Typed templates only have parents.
782782
*/
783-
case class Template[-T >: Untyped] private[ast] (constr: DefDef[T], parentsOrDerived: List[Tree[T]], self: ValDef[T], private var preBody: LazyTreeList)(implicit @constructorOnly src: SourceFile)
783+
case class Template[-T >: Untyped] private[ast] (constr: DefDef[T], parentsOrDerived: List[Tree[T]], self: ValDef[T], private var preBody: LazyTreeList[T @uncheckedVariance])(implicit @constructorOnly src: SourceFile)
784784
extends DefTree[T] with WithLazyField[List[Tree[T]]] {
785785
type ThisTree[-T >: Untyped] = Template[T]
786-
def unforcedBody: LazyTreeList = unforced
787-
def unforced: LazyTreeList = preBody
788-
protected def force(x: AnyRef): Unit = preBody = x
786+
def unforcedBody: LazyTreeList[T] = unforced
787+
def unforced: LazyTreeList[T] = preBody
788+
protected def force(x: List[Tree[T @uncheckedVariance]]): Unit = preBody = x
789789
def body(implicit ctx: Context): List[Tree[T]] = forceIfLazy
790790

791791
def parents: List[Tree[T]] = parentsOrDerived // overridden by DerivingTemplate
@@ -905,12 +905,12 @@ object Trees {
905905

906906
/** A tree that can have a lazy field
907907
* The field is represented by some private `var` which is
908-
* proxied `unforced` and `force`. Forcing the field will
908+
* accessed by `unforced` and `force`. Forcing the field will
909909
* set the `var` to the underlying value.
910910
*/
911911
trait WithLazyField[+T <: AnyRef] {
912-
def unforced: AnyRef
913-
protected def force(x: AnyRef): Unit
912+
def unforced: T | Lazy[T]
913+
protected def force(x: T @uncheckedVariance): Unit
914914
def forceIfLazy(implicit ctx: Context): T = unforced match {
915915
case lzy: Lazy[T @unchecked] =>
916916
val x = lzy.complete
@@ -924,7 +924,7 @@ object Trees {
924924
* These can be instantiated with Lazy instances which
925925
* can delay tree construction until the field is first demanded.
926926
*/
927-
trait Lazy[T <: AnyRef] {
927+
trait Lazy[+T <: AnyRef] {
928928
def complete(implicit ctx: Context): T
929929
}
930930

@@ -943,6 +943,8 @@ object Trees {
943943
type DefTree = Trees.DefTree[T]
944944
type MemberDef = Trees.MemberDef[T]
945945
type ValOrDefDef = Trees.ValOrDefDef[T]
946+
type LazyTree = Trees.LazyTree[T]
947+
type LazyTreeList = Trees.LazyTreeList[T]
946948

947949
type Ident = Trees.Ident[T]
948950
type BackquotedIdent = Trees.BackquotedIdent[T]

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -762,7 +762,7 @@ class TreeUnpickler(reader: TastyReader,
762762

763763
val localCtx = localContext(sym)
764764

765-
def readRhs(implicit ctx: Context) =
765+
def readRhs(implicit ctx: Context): LazyTree =
766766
if (nothingButMods(end))
767767
EmptyTree
768768
else if (sym.isInlineMethod)

0 commit comments

Comments
 (0)