Skip to content

Commit b5a6963

Browse files
authored
Merge pull request #6728 from dotty-staging/refactor-union-types
Use union types in compiler
2 parents d8ac6cd + 755c242 commit b5a6963

File tree

8 files changed

+31
-29
lines changed

8 files changed

+31
-29
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/Names.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,10 +185,10 @@ object Names {
185185
def underlying: TermName = unsupported("underlying")
186186

187187
@sharable // because of synchronized block in `and`
188-
private[this] var derivedNames: AnyRef /* immutable.Map[NameInfo, DerivedName] | j.u.HashMap */ =
188+
private[this] var derivedNames: immutable.Map[NameInfo, DerivedName] | HashMap[NameInfo, DerivedName] =
189189
immutable.Map.empty[NameInfo, DerivedName]
190190

191-
private def getDerived(info: NameInfo): DerivedName /* | Null */ = derivedNames match {
191+
private def getDerived(info: NameInfo): DerivedName /* | Null */ = (derivedNames: @unchecked) match {
192192
case derivedNames: immutable.AbstractMap[NameInfo, DerivedName] @unchecked =>
193193
if (derivedNames.contains(info)) derivedNames(info) else null
194194
case derivedNames: HashMap[NameInfo, DerivedName] @unchecked =>

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -939,7 +939,7 @@ object SymDenotations {
939939
if (this.is(ModuleClass))
940940
myInfo match {
941941
case ClassInfo(_, _, _, _, selfType) =>
942-
def sourceOfSelf(tp: TypeOrSymbol): Symbol = tp match {
942+
def sourceOfSelf(tp: TypeOrSymbol): Symbol = (tp: @unchecked) match {
943943
case tp: TermRef => tp.symbol
944944
case tp: Symbol => sourceOfSelf(tp.info)
945945
case tp: RefinedType => sourceOfSelf(tp.parent)

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -704,7 +704,7 @@ object Symbols {
704704

705705
type ThisName = TypeName
706706

707-
type TreeOrProvider = AnyRef /* tpd.TreeProvider | tpd.PackageDef | tpd.TypeDef | tpd.EmptyTree | Null */
707+
type TreeOrProvider = tpd.TreeProvider | tpd.Tree
708708

709709
private[this] var myTree: TreeOrProvider = tpd.EmptyTree
710710

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3940,7 +3940,7 @@ object Types {
39403940

39413941
// ------ ClassInfo, Type Bounds --------------------------------------------------
39423942

3943-
type TypeOrSymbol = AnyRef /* should be: Type | Symbol */
3943+
type TypeOrSymbol = Type | Symbol
39443944

39453945
/** Roughly: the info of a class during a period.
39463946
* @param prefix The prefix on which parents, decls, and selfType need to be rebased.
@@ -4618,7 +4618,7 @@ object Types {
46184618
override def mapClassInfo(tp: ClassInfo): ClassInfo = {
46194619
val prefix1 = this(tp.prefix)
46204620
val parents1 = tp.parents mapConserve this
4621-
val selfInfo1 = tp.selfInfo match {
4621+
val selfInfo1: TypeOrSymbol = tp.selfInfo match {
46224622
case selfInfo: Type => this(selfInfo)
46234623
case selfInfo => selfInfo
46244624
}

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)

compiler/src/dotty/tools/dotc/printing/Formatting.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ object Formatting {
8686
}
8787
}
8888

89-
private def wrapNonSensical(arg: Any /* Type | Symbol */, str: String)(implicit ctx: Context): String = {
89+
private def wrapNonSensical(arg: Any, str: String)(implicit ctx: Context): String = {
9090
import MessageContainer._
9191
def isSensical(arg: Any): Boolean = arg match {
9292
case tpe: Type =>

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ trait NamerContextOps { this: Context =>
102102
}
103103

104104
/** A new context for the interior of a class */
105-
def inClassContext(selfInfo: AnyRef /* Should be Type | Symbol*/): Context = {
105+
def inClassContext(selfInfo: TypeOrSymbol): Context = {
106106
val localCtx: Context = ctx.fresh.setNewScope
107107
selfInfo match {
108108
case sym: Symbol if sym.exists && sym.name != nme.WILDCARD => localCtx.scope.openForMutations.enter(sym)

0 commit comments

Comments
 (0)