Skip to content

Commit 50694ca

Browse files
EugeneFlesselleWojciechMazur
authored andcommitted
Move NonEmptyTuple members into Tuple
Addressing #19175 The motivation for this has already been established, among other things: - the corresponding type level operations already use `Tuple` as upper bound; - the corresponding `NamedTuple` operations also do not make a distinction; - these operations are no more unsafe than other operations already available on `Tuple`, such as `drop` Note this should _not_ be a problem for binary compatibility, as both `Tuple` and `NonEmptyTuple` are erased to `Product`s (see `defn.specialErasure`). [Cherry-picked 16becd7]
1 parent 2e5cec9 commit 50694ca

File tree

2 files changed

+29
-31
lines changed

2 files changed

+29
-31
lines changed

library/src/scala/Tuple.scala

+25-27
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,30 @@ sealed trait Tuple extends Product {
3131
inline def *: [H, This >: this.type <: Tuple] (x: H): H *: This =
3232
runtime.Tuples.cons(x, this).asInstanceOf[H *: This]
3333

34+
/** Get the i-th element of this tuple.
35+
* Equivalent to productElement but with a precise return type.
36+
*/
37+
inline def apply[This >: this.type <: Tuple](n: Int): Elem[This, n.type] =
38+
runtime.Tuples.apply(this, n).asInstanceOf[Elem[This, n.type]]
39+
40+
/** Get the head of this tuple */
41+
inline def head[This >: this.type <: Tuple]: Head[This] =
42+
runtime.Tuples.apply(this, 0).asInstanceOf[Head[This]]
43+
44+
/** Get the initial part of the tuple without its last element */
45+
inline def init[This >: this.type <: Tuple]: Init[This] =
46+
runtime.Tuples.init(this).asInstanceOf[Init[This]]
47+
48+
/** Get the last of this tuple */
49+
inline def last[This >: this.type <: Tuple]: Last[This] =
50+
runtime.Tuples.last(this).asInstanceOf[Last[This]]
51+
52+
/** Get the tail of this tuple.
53+
* This operation is O(this.size)
54+
*/
55+
inline def tail[This >: this.type <: Tuple]: Tail[This] =
56+
runtime.Tuples.tail(this).asInstanceOf[Tail[This]]
57+
3458
/** Return a new tuple by concatenating `this` tuple with `that` tuple.
3559
* This operation is O(this.size + that.size)
3660
*/
@@ -304,33 +328,7 @@ case object EmptyTuple extends Tuple {
304328
}
305329

306330
/** Tuple of arbitrary non-zero arity */
307-
sealed trait NonEmptyTuple extends Tuple {
308-
import Tuple.*
309-
310-
/** Get the i-th element of this tuple.
311-
* Equivalent to productElement but with a precise return type.
312-
*/
313-
inline def apply[This >: this.type <: NonEmptyTuple](n: Int): Elem[This, n.type] =
314-
runtime.Tuples.apply(this, n).asInstanceOf[Elem[This, n.type]]
315-
316-
/** Get the head of this tuple */
317-
inline def head[This >: this.type <: NonEmptyTuple]: Head[This] =
318-
runtime.Tuples.apply(this, 0).asInstanceOf[Head[This]]
319-
320-
/** Get the initial part of the tuple without its last element */
321-
inline def init[This >: this.type <: NonEmptyTuple]: Init[This] =
322-
runtime.Tuples.init(this).asInstanceOf[Init[This]]
323-
324-
/** Get the last of this tuple */
325-
inline def last[This >: this.type <: NonEmptyTuple]: Last[This] =
326-
runtime.Tuples.last(this).asInstanceOf[Last[This]]
327-
328-
/** Get the tail of this tuple.
329-
* This operation is O(this.size)
330-
*/
331-
inline def tail[This >: this.type <: NonEmptyTuple]: Tail[This] =
332-
runtime.Tuples.tail(this).asInstanceOf[Tail[This]]
333-
}
331+
sealed trait NonEmptyTuple extends Tuple
334332

335333
@showAsInfix
336334
sealed abstract class *:[+H, +T <: Tuple] extends NonEmptyTuple

library/src/scala/runtime/Tuples.scala

+4-4
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ object Tuples {
350350
}
351351
}
352352

353-
def tail(self: NonEmptyTuple): Tuple = (self: Any) match {
353+
def tail(self: Tuple): Tuple = (self: Any) match {
354354
case xxl: TupleXXL => xxlTail(xxl)
355355
case _ => specialCaseTail(self)
356356
}
@@ -558,16 +558,16 @@ object Tuples {
558558
}
559559
}
560560

561-
def init(self: NonEmptyTuple): Tuple = (self: Any) match {
561+
def init(self: Tuple): Tuple = (self: Any) match {
562562
case xxl: TupleXXL => xxlInit(xxl)
563563
case _ => specialCaseInit(self)
564564
}
565565

566-
def last(self: NonEmptyTuple): Any = (self: Any) match {
566+
def last(self: Tuple): Any = (self: Any) match {
567567
case self: Product => self.productElement(self.productArity - 1)
568568
}
569569

570-
def apply(self: NonEmptyTuple, n: Int): Any =
570+
def apply(self: Tuple, n: Int): Any =
571571
self.productElement(n)
572572

573573
// Benchmarks showed that this is faster than doing (it1 zip it2).copyToArray(...)

0 commit comments

Comments
 (0)