Skip to content

Commit 4e61497

Browse files
committed
Replace EmptyTuple implementation from Unit to Tuple0
1 parent 70963ae commit 4e61497

File tree

64 files changed

+233
-157
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+233
-157
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1337,7 +1337,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
13371337

13381338
/** Creates the nested pairs type tree repesentation of the type trees in `ts` */
13391339
def nestedPairsTypeTree(ts: List[Tree])(implicit ctx: Context): Tree =
1340-
ts.foldRight[Tree](TypeTree(defn.UnitType))((x, acc) => AppliedTypeTree(TypeTree(defn.PairClass.typeRef), x :: acc :: Nil))
1340+
ts.foldRight[Tree](TypeTree(defn.EmptyTupleTypeRef))((x, acc) => AppliedTypeTree(TypeTree(defn.PairClass.typeRef), x :: acc :: Nil))
13411341

13421342
/** Replaces all positions in `tree` with zero-extent positions */
13431343
private def focusPositions(tree: Tree)(implicit ctx: Context): Tree = {

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

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -745,11 +745,14 @@ class Definitions {
745745
@tu lazy val TupleTypeRef: TypeRef = ctx.requiredClassRef("scala.Tuple")
746746
def TupleClass(implicit ctx: Context): ClassSymbol = TupleTypeRef.symbol.asClass
747747
@tu lazy val Tuple_cons: Symbol = TupleClass.requiredMethod("*:")
748+
@tu lazy val EmptyTupleTypeRef: TypeRef = ctx.requiredClassRef("scala.EmptyTuple")
749+
def EmptyTupleClass(implicit ctx: Context): ClassSymbol = EmptyTupleTypeRef.symbol.asClass
748750
@tu lazy val NonEmptyTupleTypeRef: TypeRef = ctx.requiredClassRef("scala.NonEmptyTuple")
749751
def NonEmptyTupleClass(implicit ctx: Context): ClassSymbol = NonEmptyTupleTypeRef.symbol.asClass
750752
lazy val NonEmptyTuple_tail: Symbol = NonEmptyTupleClass.requiredMethod("tail")
751-
752753
@tu lazy val PairClass: ClassSymbol = ctx.requiredClass("scala.*:")
754+
755+
@tu lazy val Tuple0Module: Symbol = ctx.requiredModule("scala.runtime.Tuple0")
753756
@tu lazy val TupleXXLClass: ClassSymbol = ctx.requiredClass("scala.runtime.TupleXXL")
754757
def TupleXXLModule(implicit ctx: Context): Symbol = TupleXXLClass.companionModule
755758

@@ -1185,7 +1188,7 @@ class Definitions {
11851188
case _ if bound < 0 => Some(acc.reverse)
11861189
case tp: AppliedType if defn.PairClass == tp.classSymbol => rec(tp.args(1), tp.args.head :: acc, bound - 1)
11871190
case tp: AppliedType if defn.isTupleClass(tp.tycon.classSymbol) => Some(acc.reverse ::: tp.args)
1188-
case tp if tp.classSymbol == defn.UnitClass => Some(acc.reverse)
1191+
case tp if tp.classSymbol == defn.EmptyTupleClass => Some(acc.reverse)
11891192
case _ => None
11901193
}
11911194
rec(tp.stripTypeVar, Nil, bound)
@@ -1296,7 +1299,7 @@ class Definitions {
12961299
def syntheticParent(tparams: List[TypeSymbol]): Type =
12971300
if (tparams.isEmpty) TupleTypeRef
12981301
else TypeOps.nestedPairs(tparams.map(_.typeRef))
1299-
if (isTupleClass(cls) || cls == UnitClass) parents :+ syntheticParent(tparams)
1302+
if (isTupleClass(cls) || cls == EmptyTupleClass) parents :+ syntheticParent(tparams)
13001303
else parents
13011304
}
13021305

@@ -1394,6 +1397,7 @@ class Definitions {
13941397
.updated(AnyValClass, ObjectClass)
13951398
.updated(SingletonClass, ObjectClass)
13961399
.updated(TupleClass, ObjectClass)
1400+
.updated(EmptyTupleClass, ObjectClass)
13971401
.updated(NonEmptyTupleClass, ProductClass)
13981402

13991403
// ----- Initialization ---------------------------------------------------

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -731,6 +731,6 @@ object TypeOps:
731731
}
732732

733733
def nestedPairs(ts: List[Type])(using Context): Type =
734-
ts.foldRight(defn.UnitType: Type)(defn.PairClass.typeRef.appliedTo(_, _))
734+
ts.foldRight(defn.EmptyTupleTypeRef: Type)(defn.PairClass.typeRef.appliedTo(_, _))
735735

736736
end TypeOps

compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2004,7 +2004,10 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend
20042004
def Definitions_NothingType: Type = defn.NothingType
20052005
def Definitions_NullType: Type = defn.NullType
20062006
def Definitions_StringType: Type = defn.StringType
2007-
2007+
def Definitions_TupleType: Type = defn.TupleTypeRef
2008+
def Definitions_EmptyTupleType: Type = defn.EmptyTupleTypeRef
2009+
def Definitions_NonEmptyTupleType: Type = defn.NonEmptyTupleClass.typeRef
2010+
def Definitions_TupleConsType: Type = defn.PairClass.typeRef
20082011

20092012
///////////////
20102013
// IMPLICITS //

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ class Erasure extends Phase with DenotTransformer {
163163
assert(isErasedType(tp) ||
164164
isAllowed(defn.ArrayClass, "Array.scala") ||
165165
isAllowed(defn.TupleClass, "Tuple.scala") ||
166+
isAllowed(defn.EmptyTupleClass, "Tuple.scala") ||
166167
isAllowed(defn.NonEmptyTupleClass, "Tuple.scala") ||
167168
isAllowed(defn.PairClass, "Tuple.scala"),
168169
i"The type $tp - ${tp.toString} of class ${tp.getClass} of tree $tree : ${tree.tpe} / ${tree.getClass} is illegal after erasure, phase = ${ctx.phase.prev}")

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ class TupleOptimizations extends MiniPhase with IdentityDenotTransformer {
6969
val size = tpes.size
7070
assert(size > 0)
7171
if (size == 1)
72-
// ()
73-
Literal(Constant(()))
72+
// scala.runtime.Tuple0
73+
ref(defn.Tuple0Module.termRef)
7474
else if (size <= 5)
7575
// val t = tup.asInstanceOf[TupleN[...]]
7676
// TupleN-1(t._2, ..., t._n)
@@ -197,8 +197,8 @@ class TupleOptimizations extends MiniPhase with IdentityDenotTransformer {
197197

198198
private def knownTupleFromIterator(size: Int, it: Tree)(implicit ctx: Context): Tree =
199199
if (size == 0)
200-
// Unit for empty tuple
201-
Literal(Constant(())) // TODO should this code be here? Or assert(size > specializedSize)
200+
// EmptyTuple for empty tuple
201+
ref(defn.EmptyTupleTypeRef) // TODO should this code be here? Or assert(size > specializedSize)
202202
else if (size <= MaxTupleArity) {
203203
// TupleN(it.next(), ..., it.next())
204204

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,25 +31,25 @@ object TypeUtils {
3131
case ps => ps.reduceLeft(AndType(_, _))
3232
}
3333

34-
/** The arity of this tuple type, which can be made up of Unit, TupleX and `*:` pairs,
34+
/** The arity of this tuple type, which can be made up of EmptyTuple, TupleX and `*:` pairs,
3535
* or -1 if this is not a tuple type.
3636
*/
3737
def tupleArity(implicit ctx: Context): Int = self match {
3838
case AppliedType(tycon, _ :: tl :: Nil) if tycon.isRef(defn.PairClass) =>
3939
val arity = tl.tupleArity
4040
if (arity < 0) arity else arity + 1
4141
case tp1 =>
42-
if (tp1.isRef(defn.UnitClass)) 0
42+
if (tp1.isRef(defn.EmptyTupleClass)) 0
4343
else if (defn.isTupleClass(tp1.classSymbol)) tp1.dealias.argInfos.length
4444
else -1
4545
}
4646

47-
/** The element types of this tuple type, which can be made up of Unit, TupleX and `*:` pairs */
47+
/** The element types of this tuple type, which can be made up of EmptyTuple, TupleX and `*:` pairs */
4848
def tupleElementTypes(implicit ctx: Context): List[Type] = self match {
4949
case AppliedType(tycon, hd :: tl :: Nil) if tycon.isRef(defn.PairClass) =>
5050
hd :: tl.tupleElementTypes
5151
case tp1 =>
52-
if (tp1.isRef(defn.UnitClass)) Nil
52+
if (tp1.isRef(defn.EmptyTupleClass)) Nil
5353
else if (defn.isTupleClass(tp1.classSymbol)) tp1.dealias.argInfos
5454
else throw new AssertionError("not a tuple")
5555
}

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,9 @@ trait QuotesAndSplices {
411411
}
412412
}
413413

414-
val splicePat = typed(untpd.Tuple(splices.map(x => untpd.TypedSplice(replaceBindingsInTree.transform(x)))).withSpan(quoted.span), patType)
414+
val splicePat =
415+
if splices.isEmpty then ref(defn.Tuple0Module.termRef)
416+
else typed(untpd.Tuple(splices.map(x => untpd.TypedSplice(replaceBindingsInTree.transform(x)))).withSpan(quoted.span), patType)
415417

416418
val unapplySym = if (tree.quoted.isTerm) defn.InternalQuotedExpr_unapply else defn.InternalQuotedType_unapply
417419
val quoteClass = if (tree.quoted.isTerm) defn.QuotedExprClass else defn.QuotedTypeClass

0 commit comments

Comments
 (0)