Skip to content

Commit fcdcfdb

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

File tree

76 files changed

+256
-176
lines changed

Some content is hidden

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

76 files changed

+256
-176
lines changed

bench-run/src/main/scala/dotty/tools/benchmarks/tuples/Apply.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class Apply {
1313
def setup(): Unit = {
1414
val size = sizeAndIndex.split(' ')(0).toInt
1515
index = sizeAndIndex.split(' ')(1).toInt
16-
tuple = "elem" *: ()
16+
tuple = "elem" *: Tuple()
1717

1818
for (i <- 1 until size)
1919
tuple = "elem" *: tuple

bench-run/src/main/scala/dotty/tools/benchmarks/tuples/Concat.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class Concat {
1111
var tuple2: Tuple = _
1212

1313
def tupleOfSize(n: Int): Tuple = {
14-
var t: Tuple = ()
14+
var t: Tuple = Tuple()
1515
for (i <- 1 to n)
1616
t = "elem" *: t
1717
t

bench-run/src/main/scala/dotty/tools/benchmarks/tuples/Cons.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class Cons {
1212

1313
@Setup
1414
def setup(): Unit = {
15-
tuple = ()
15+
tuple = Tuple()
1616

1717
for (i <- 1 to size)
1818
tuple = "elem" *: tuple

bench-run/src/main/scala/dotty/tools/benchmarks/tuples/Conversions.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class Conversions {
1212

1313
@Setup
1414
def setup(): Unit = {
15-
tuple = ()
15+
tuple = Tuple()
1616

1717
for (i <- 1 to size)
1818
tuple = "elem" *: tuple

bench-run/src/main/scala/dotty/tools/benchmarks/tuples/Map.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class Map {
1111

1212
@Setup
1313
def setup(): Unit = {
14-
tuple = ()
14+
tuple = Tuple()
1515

1616
for (i <- 1 to size)
1717
tuple = "elem" *: tuple

bench-run/src/main/scala/dotty/tools/benchmarks/tuples/Tail.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class Tail {
1111

1212
@Setup
1313
def setup(): Unit = {
14-
tuple = "elem" *: ()
14+
tuple = "elem" *: Tuple()
1515

1616
for (i <- 1 until size)
1717
tuple = "elem" *: tuple

bench-run/src/main/scala/dotty/tools/benchmarks/tuples/TupleOps.scala

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ class TupleOps {
1111

1212
@Setup
1313
def setup(): Unit = {
14-
tuple1 = ()
14+
tuple1 = Tuple()
1515
for (i <- 1 until 15)
1616
tuple1 = s"elem$i" *: tuple1
1717

18-
tuple2 = ()
18+
tuple2 = Tuple()
1919
for (i <- 1 until 10)
2020
tuple2 = s"elem$i" *: tuple2
2121

@@ -25,23 +25,23 @@ class TupleOps {
2525

2626
def tupleFlatMap(tuple: Tuple, f: [A] => A => Tuple): Tuple = {
2727
def tailRecFlatMap(t: Tuple, acc: Tuple): Tuple = t match {
28-
case () => acc
28+
case Tuple() => acc
2929
case x *: rest => tailRecFlatMap(rest, acc ++ f(x))
3030
}
31-
tailRecFlatMap(tuple, ())
31+
tailRecFlatMap(tuple, Tuple())
3232
}
3333

3434
def tupleReverse(tuple: Tuple): Tuple = {
3535
def tailRecReverse(t: Tuple, acc: Tuple): Tuple = t match {
36-
case () => acc
36+
case Tuple() => acc
3737
case x *: rest => tailRecReverse(rest, x *: acc)
3838
}
39-
tailRecReverse(tuple, ())
39+
tailRecReverse(tuple, Tuple())
4040
}
4141

4242
def tupleMerge(tuple1: Tuple, tuple2: Tuple): Tuple = (tuple1, tuple2) match {
43-
case (_, ()) => tuple1
44-
case ((), _) => tuple2
43+
case (_, Tuple()) => tuple1
44+
case (Tuple(), _) => tuple2
4545
case (x *: xs, y *: ys) =>
4646
if (x.asInstanceOf[Int] <= y.asInstanceOf[Int]) x *: tupleMerge(xs, tuple2)
4747
else y *: tupleMerge(tuple1, ys)

bench-run/src/main/scala/dotty/tools/benchmarks/tuples/Zip.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ class Zip {
1313

1414
@Setup
1515
def setup(): Unit = {
16-
tuple1 = ()
17-
tuple2 = ()
16+
tuple1 = Tuple()
17+
tuple2 = Tuple()
1818

1919
for (i <- 1 to size) {
2020
tuple1 = "el" *: tuple1

bench-run/src/main/scala/tuples/Drop.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class Drop {
1212

1313
@Setup
1414
def setup(): Unit = {
15-
tuple = ()
15+
tuple = Tuple()
1616
half = size / 2
1717

1818
for (i <- 1 to size)

bench-run/src/main/scala/tuples/Split.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class Split {
1212

1313
@Setup
1414
def setup(): Unit = {
15-
tuple = ()
15+
tuple = Tuple()
1616
half = size / 2
1717

1818
for (i <- 1 to size)

bench-run/src/main/scala/tuples/Take.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class Take {
1212

1313
@Setup
1414
def setup(): Unit = {
15-
tuple = ()
15+
tuple = Tuple()
1616
half = size / 2
1717

1818
for (i <- 1 to size)

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

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2274,7 +2274,7 @@ class Typer extends Namer
22742274
else List.fill(arity)(defn.AnyType)
22752275
val elems = tree.trees.lazyZip(pts).map(typed(_, _))
22762276
if (ctx.mode.is(Mode.Type))
2277-
elems.foldRight(TypeTree(defn.UnitType): Tree)((elemTpt, elemTpts) =>
2277+
elems.foldRight(TypeTree(defn.EmptyTupleTypeRef): Tree)((elemTpt, elemTpts) =>
22782278
AppliedTypeTree(TypeTree(defn.PairClass.typeRef), List(elemTpt, elemTpts)))
22792279
.withSpan(tree.span)
22802280
else {

library/src-bootstrapped/scala/Tuple.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -158,10 +158,10 @@ object Tuple {
158158
type Split[T <: Tuple, N <: Int] = (Take[T, N], Drop[T, N])
159159

160160
/** Empty tuple */
161-
def apply(): EmptyTuple = ()
161+
def apply(): EmptyTuple = scala.runtime.Tuple0.asInstanceOf[EmptyTuple]
162162

163163
/** Matches an empty tuple. */
164-
def unapply(x: Any): Boolean = x.isInstanceOf[EmptyTuple]
164+
def unapply(x: EmptyTuple): Boolean = x == scala.runtime.Tuple0
165165

166166
/** Convert an array into a tuple of unknown arity and types */
167167
def fromArray[T](xs: Array[T]): Tuple = {
@@ -191,8 +191,8 @@ object Tuple {
191191
Tuple.fromArray(p.productIterator.toArray).asInstanceOf[m.MirroredElemTypes] // TODO use toIArray of Object to avoid double/triple array copy
192192
}
193193

194-
/** Tuple of arity 0 */
195-
type EmptyTuple = Unit
194+
/** Tuple of arity zero */
195+
sealed trait EmptyTuple extends Tuple
196196

197197
/** Tuple of arbitrary non-zero arity */
198198
sealed trait NonEmptyTuple extends Tuple with Product {

library/src-bootstrapped/scala/deriving.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,17 @@ object deriving {
3434
trait Singleton extends Product {
3535
type MirroredMonoType = this.type
3636
type MirroredType = this.type
37-
type MirroredElemTypes = Unit
38-
type MirroredElemLabels = Unit
37+
type MirroredElemTypes = EmptyTuple
38+
type MirroredElemLabels = EmptyTuple
3939
def fromProduct(p: scala.Product) = this
4040
}
4141

4242
/** A proxy for Scala 2 singletons, which do not inherit `Singleton` directly */
4343
class SingletonProxy(val value: AnyRef) extends Product {
4444
type MirroredMonoType = value.type
4545
type MirroredType = value.type
46-
type MirroredElemTypes = Unit
47-
type MirroredElemLabels = Unit
46+
type MirroredElemTypes = EmptyTuple
47+
type MirroredElemLabels = EmptyTuple
4848
def fromProduct(p: scala.Product) = value
4949
}
5050

library/src/scala/internal/TupledFunction.scala renamed to library/src-bootstrapped/scala/internal/TupledFunction.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ import scala.runtime.TupleXXL
66
object TupledFunction {
77

88
def tupledFunction0[F, G]: TupledFunction[F, G] = scala.TupledFunction[F, G](
9-
tupledImpl = (f: F) => ((args: Unit) => f.asInstanceOf[() => Any].apply()).asInstanceOf[G],
10-
untupledImpl = (g: G) => (() => g.asInstanceOf[Unit => Any].apply(())).asInstanceOf[F]
9+
tupledImpl = (f: F) => ((args: EmptyTuple) => f.asInstanceOf[() => Any].apply()).asInstanceOf[G],
10+
untupledImpl = (g: G) => (() => g.asInstanceOf[EmptyTuple => Any].apply(Tuple())).asInstanceOf[F]
1111
)
1212

1313
def tupledFunction1[F, G]: TupledFunction[F, G] = scala.TupledFunction[F, G](

library/src-bootstrapped/scala/quoted/Expr.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class Expr[+T] private[scala] {
3838
* ```
3939
*/
4040
final def matches(that: Expr[Any])(using qctx: QuoteContext): Boolean =
41-
!scala.internal.quoted.Expr.unapply[Unit, Unit](this)(using that, false, qctx).isEmpty
41+
!scala.internal.quoted.Expr.unapply[EmptyTuple, EmptyTuple](this)(using that, false, qctx).isEmpty
4242

4343
/** Checked cast to a `quoted.Expr[U]` */
4444
def cast[U](using tp: scala.quoted.Type[U])(using qctx: QuoteContext): scala.quoted.Expr[U] =
@@ -131,7 +131,7 @@ object Expr {
131131
def ofTuple(seq: Seq[Expr[Any]])(using qctx: QuoteContext): Expr[Tuple] = {
132132
seq match {
133133
case Seq() =>
134-
unitExpr
134+
'{ Tuple() }
135135
case Seq('{ $x1: $t1 }) =>
136136
'{ Tuple1($x1) }
137137
case Seq('{ $x1: $t1 }, '{ $x2: $t2 }) =>

0 commit comments

Comments
 (0)