diff --git a/library/src/scala/Tuple.scala b/library/src/scala/Tuple.scala index c5c2115811cb..fb08a0afe2b5 100644 --- a/library/src/scala/Tuple.scala +++ b/library/src/scala/Tuple.scala @@ -1,5 +1,6 @@ package scala -import annotation.showAsInfix + +import annotation.{experimental, showAsInfix} import compiletime._ import compiletime.ops.int._ @@ -82,11 +83,26 @@ object Tuple { case x *: _ => x } + /** Type of the initial part of the tuple without its last element */ + @experimental + type Init[X <: Tuple] <: Tuple = X match { + case _ *: EmptyTuple => EmptyTuple + case x *: xs => + x *: Init[xs] + } + /** Type of the tail of a tuple */ type Tail[X <: NonEmptyTuple] <: Tuple = X match { case _ *: xs => xs } + /** Type of the last element of a tuple */ + @experimental + type Last[X <: Tuple] = X match { + case x *: EmptyTuple => x + case _ *: xs => Last[xs] + } + /** Type of the concatenation of two tuples */ type Concat[X <: Tuple, +Y <: Tuple] <: Tuple = X match { case EmptyTuple => Y @@ -269,6 +285,16 @@ sealed trait NonEmptyTuple extends Tuple { inline def head[This >: this.type <: NonEmptyTuple]: Head[This] = runtime.Tuples.apply(this, 0).asInstanceOf[Head[This]] + /** Get the initial part of the tuple without its last element */ + @experimental + inline def init[This >: this.type <: NonEmptyTuple]: Init[This] = + runtime.Tuples.init(this).asInstanceOf[Init[This]] + + /** Get the last of this tuple */ + @experimental + inline def last[This >: this.type <: NonEmptyTuple]: Last[This] = + runtime.Tuples.last(this).asInstanceOf[Last[This]] + /** Get the tail of this tuple. * This operation is O(this.size) */ diff --git a/library/src/scala/runtime/Tuples.scala b/library/src/scala/runtime/Tuples.scala index 267e04f65aed..e5018cce47a6 100644 --- a/library/src/scala/runtime/Tuples.scala +++ b/library/src/scala/runtime/Tuples.scala @@ -355,6 +355,82 @@ object Tuples { case _ => specialCaseTail(self) } + // Init for TupleXXL + private def xxlInit(xxl: TupleXXL): Tuple = { + if (xxl.productArity == 23) { + val elems = xxl.elems + Tuple22( + elems(0), elems(1), elems(2), elems(3), elems(4), elems(5), + elems(6), elems(7), elems(8), elems(9), elems(10), elems(11), + elems(12), elems(13), elems(14), elems(15), elems(16), elems(17), + elems(18), elems(19), elems(20), elems(21) + ) + } else { + val arr = new Array[Object](xxl.elems.length - 1) + System.arraycopy(xxl.elems, 0, arr, 0, xxl.elems.length - 1) + TupleXXL.fromIArray(arr.asInstanceOf[IArray[Object]]).asInstanceOf[Tuple] + } + } + + // Init for Tuple1 to Tuple22 + private def specialCaseInit(self: Tuple): Tuple = { + (self: Any) match { + case _: Tuple1[_] => + EmptyTuple + case self: Tuple2[_, _] => + Tuple1(self._1) + case self: Tuple3[_, _, _] => + Tuple2(self._1, self._2) + case self: Tuple4[_, _, _, _] => + Tuple3(self._1, self._2, self._3) + case self: Tuple5[_, _, _, _, _] => + Tuple4(self._1,self._2, self._3, self._4) + case self: Tuple6[_, _, _, _, _, _] => + Tuple5(self._1, self._2, self._3, self._4, self._5) + case self: Tuple7[_, _, _, _, _, _, _] => + Tuple6(self._1, self._2, self._3, self._4, self._5, self._6) + case self: Tuple8[_, _, _, _, _, _, _, _] => + Tuple7(self._1, self._2, self._3, self._4, self._5, self._6, self._7) + case self: Tuple9[_, _, _, _, _, _, _, _, _] => + Tuple8(self._1, self._2, self._3, self._4, self._5, self._6, self._7, self._8) + case self: Tuple10[_, _, _, _, _, _, _, _, _, _] => + Tuple9(self._1, self._2, self._3, self._4, self._5, self._6, self._7, self._8, self._9) + case self: Tuple11[_, _, _, _, _, _, _, _, _, _, _] => + Tuple10(self._1, self._2, self._3, self._4, self._5, self._6, self._7, self._8, self._9, self._10) + case self: Tuple12[_, _, _, _, _, _, _, _, _, _, _, _] => + Tuple11(self._1, self._2, self._3, self._4, self._5, self._6, self._7, self._8, self._9, self._10, self._11) + case self: Tuple13[_, _, _, _, _, _, _, _, _, _, _, _, _] => + Tuple12(self._1, self._2, self._3, self._4, self._5, self._6, self._7, self._8, self._9, self._10, self._11, self._12) + case self: Tuple14[_, _, _, _, _, _, _, _, _, _, _, _, _, _] => + Tuple13(self._1, self._2, self._3, self._4, self._5, self._6, self._7, self._8, self._9, self._10, self._11, self._12, self._13) + case self: Tuple15[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => + Tuple14(self._1, self._2, self._3, self._4, self._5, self._6, self._7, self._8, self._9, self._10, self._11, self._12, self._13, self._14) + case self: Tuple16[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => + Tuple15(self._1, self._2, self._3, self._4, self._5, self._6, self._7, self._8, self._9, self._10, self._11, self._12, self._13, self._14, self._15) + case self: Tuple17[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => + Tuple16(self._1, self._2, self._3, self._4, self._5, self._6, self._7, self._8, self._9, self._10, self._11, self._12, self._13, self._14, self._15, self._16) + case self: Tuple18[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => + Tuple17(self._1, self._2, self._3, self._4, self._5, self._6, self._7, self._8, self._9, self._10, self._11, self._12, self._13, self._14, self._15, self._16, self._17) + case self: Tuple19[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => + Tuple18(self._1, self._2, self._3, self._4, self._5, self._6, self._7, self._8, self._9, self._10, self._11, self._12, self._13, self._14, self._15, self._16, self._17, self._18) + case self: Tuple20[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => + Tuple19(self._1, self._2, self._3, self._4, self._5, self._6, self._7, self._8, self._9, self._10, self._11, self._12, self._13, self._14, self._15, self._16, self._17, self._18, self._19) + case self: Tuple21[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => + Tuple20(self._1, self._2, self._3, self._4, self._5, self._6, self._7, self._8, self._9, self._10, self._11, self._12, self._13, self._14, self._15, self._16, self._17, self._18, self._19, self._20) + case self: Tuple22[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => + Tuple21(self._1, self._2, self._3, self._4, self._5, self._6, self._7, self._8, self._9, self._10, self._11, self._12, self._13, self._14, self._15, self._16, self._17, self._18, self._19, self._20, self._21) + } + } + + def init(self: NonEmptyTuple): Tuple = (self: Any) match { + case xxl: TupleXXL => xxlInit(xxl) + case _ => specialCaseInit(self) + } + + def last(self: NonEmptyTuple): Any = (self: Any) match { + case self: Product => self.productElement(self.productArity - 1) + } + def apply(self: NonEmptyTuple, n: Int): Any = self.productElement(n) diff --git a/project/Build.scala b/project/Build.scala index c21fb71609fa..8520a5de6839 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -14,20 +14,15 @@ import sbt.ScriptedPlugin.autoImport._ import xerial.sbt.pack.PackPlugin import xerial.sbt.pack.PackPlugin.autoImport._ import xerial.sbt.Sonatype.autoImport._ - import com.typesafe.tools.mima.plugin.MimaPlugin.autoImport._ - -import dotty.tools.sbtplugin.DottyIDEPlugin.{ installCodeExtension, prepareCommand, runProcess } +import dotty.tools.sbtplugin.DottyIDEPlugin.{installCodeExtension, prepareCommand, runProcess} import dotty.tools.sbtplugin.DottyIDEPlugin.autoImport._ - import org.scalajs.sbtplugin.ScalaJSPlugin import org.scalajs.sbtplugin.ScalaJSPlugin.autoImport._ - import sbtbuildinfo.BuildInfoPlugin import sbtbuildinfo.BuildInfoPlugin.autoImport._ import scala.util.Properties.isJavaAtLeast - import org.portablescala.sbtplatformdeps.PlatformDepsPlugin.autoImport._ object DottyJSPlugin extends AutoPlugin { @@ -1781,7 +1776,7 @@ object Build { (Compile/doc/target).value }, commonMiMaSettings, - mimaBinaryIssueFilters ++= MiMaFilters.Library, + mimaBinaryIssueFilters ++= MiMaFilters.Library ) } else base } diff --git a/project/MiMaFilters.scala b/project/MiMaFilters.scala index c7a71a2dd8dc..0f8dbfa896c0 100644 --- a/project/MiMaFilters.scala +++ b/project/MiMaFilters.scala @@ -4,5 +4,7 @@ import com.typesafe.tools.mima.core.ProblemFilters._ object MiMaFilters { val Library: Seq[ProblemFilter] = Seq( + ProblemFilters.exclude[DirectMissingMethodProblem]("scala.runtime.Tuples.init"), + ProblemFilters.exclude[DirectMissingMethodProblem]("scala.runtime.Tuples.last") ) } diff --git a/tests/run-deep-subtype/Tuple-init.check b/tests/run-deep-subtype/Tuple-init.check new file mode 100644 index 000000000000..31c15bbd4e76 --- /dev/null +++ b/tests/run-deep-subtype/Tuple-init.check @@ -0,0 +1,76 @@ +() +(0) +(0,0) +(0,0,1) +(0,0,1,2) +(0,0,1,2,3) +(0,0,1,2,3,4) +(0,0,1,2,3,4,5) +(0,0,1,2,3,4,5,6) +(0,0,1,2,3,4,5,6,7) +(0,0,1,2,3,4,5,6,7,8) +(0,0,1,2,3,4,5,6,7,8,9) +(0,0,1,2,3,4,5,6,7,8,9,10) +(0,0,1,2,3,4,5,6,7,8,9,10,11) +(0,0,1,2,3,4,5,6,7,8,9,10,11,12) +(0,0,1,2,3,4,5,6,7,8,9,10,11,12,13) +(0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14) +(0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15) +(0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16) +(0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17) +(0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18) +(0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19) +(0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20) +(0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21) +(0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22) +(0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23) +() +(1) +(1,2) +(1,2,3) +(1,2,3,4) +(1,2,3,4,5) +(1,2,3,4,5,6) +(1,2,3,4,5,6,7) +(1,2,3,4,5,6,7,8) +(1,2,3,4,5,6,7,8,9) +(1,2,3,4,5,6,7,8,9,10) +(1,2,3,4,5,6,7,8,9,10,11) +(1,2,3,4,5,6,7,8,9,10,11,12) +(1,2,3,4,5,6,7,8,9,10,11,12,13) +(1,2,3,4,5,6,7,8,9,10,11,12,13,14) +(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15) +(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16) +(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17) +(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18) +(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19) +(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20) +(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21) +(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22) +(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23) +(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24) +() +(1) +(1,2) +(1,2,3) +(1,2,3,4) +(1,2,3,4,5) +(1,2,3,4,5,6) +(1,2,3,4,5,6,7) +(1,2,3,4,5,6,7,8) +(1,2,3,4,5,6,7,8,9) +(1,2,3,4,5,6,7,8,9,10) +(1,2,3,4,5,6,7,8,9,10,11) +(1,2,3,4,5,6,7,8,9,10,11,12) +(1,2,3,4,5,6,7,8,9,10,11,12,13) +(1,2,3,4,5,6,7,8,9,10,11,12,13,14) +(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15) +(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16) +(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17) +(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18) +(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19) +(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20) +(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21) +(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22) +(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23) +(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24) diff --git a/tests/run-deep-subtype/Tuple-init.scala b/tests/run-deep-subtype/Tuple-init.scala new file mode 100644 index 000000000000..286c84a17cf7 --- /dev/null +++ b/tests/run-deep-subtype/Tuple-init.scala @@ -0,0 +1,65 @@ +import scala.reflect.ClassTag + +object Test { + def main(args: Array[String]): Unit = { + def testArray[T: ClassTag](n: Int, elem: Int => T): Unit = { + val t: Int *: Tuple = 0 *: Tuple.fromArray(Array.tabulate(n)(elem)) + println(t.init) + } + + for (i <- 0 to 25) + testArray(i, j => j) + + println(Tuple1(1).init) + println((1, 2).init) + println((1, 2, 3).init) + println((1, 2, 3, 4).init) + println((1, 2, 3, 4, 5).init) + println((1, 2, 3, 4, 5, 6).init) + println((1, 2, 3, 4, 5, 6, 7).init) + println((1, 2, 3, 4, 5, 6, 7, 8).init) + println((1, 2, 3, 4, 5, 6, 7, 8, 9).init) + println((1, 2, 3, 4, 5, 6, 7, 8, 9, 10).init) + println((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11).init) + println((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12).init) + println((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13).init) + println((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14).init) + println((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15).init) + println((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16).init) + println((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17).init) + println((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18).init) + println((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19).init) + println((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20).init) + println((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21).init) + println((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22).init) + println((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23).init) + println((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24).init) + println((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25).init) + + println((1 *: Tuple()).init) + println((1 *: 2 *: Tuple()).init) + println((1 *: 2 *: 3 *: Tuple()).init) + println((1 *: 2 *: 3 *: 4 *: Tuple()).init) + println((1 *: 2 *: 3 *: 4 *: 5 *: Tuple()).init) + println((1 *: 2 *: 3 *: 4 *: 5 *: 6 *: Tuple()).init) + println((1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: Tuple()).init) + println((1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: Tuple()).init) + println((1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: Tuple()).init) + println((1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: Tuple()).init) + println((1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: Tuple()).init) + println((1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: Tuple()).init) + println((1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: Tuple()).init) + println((1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: Tuple()).init) + println((1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: Tuple()).init) + println((1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: 16 *: Tuple()).init) + println((1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: 16 *: 17 *: Tuple()).init) + println((1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: 16 *: 17 *: 18 *: Tuple()).init) + println((1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: 16 *: 17 *: 18 *: 19 *: Tuple()).init) + println((1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: 16 *: 17 *: 18 *: 19 *: 20 *: Tuple()).init) + println((1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: 16 *: 17 *: 18 *: 19 *: 20 *: 21 *: Tuple()).init) + println((1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: 16 *: 17 *: 18 *: 19 *: 20 *: 21 *: 22 *: Tuple()).init) + println((1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: 16 *: 17 *: 18 *: 19 *: 20 *: 21 *: 22 *: 23 *: Tuple()).init) + println((1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: 16 *: 17 *: 18 *: 19 *: 20 *: 21 *: 22 *: 23 *: 24 *: Tuple()).init) + println((1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: 16 *: 17 *: 18 *: 19 *: 20 *: 21 *: 22 *: 23 *: 24 *: 25 *: Tuple()).init) + } +} diff --git a/tests/run-deep-subtype/Tuple-last.check b/tests/run-deep-subtype/Tuple-last.check new file mode 100644 index 000000000000..cc750f5e721c --- /dev/null +++ b/tests/run-deep-subtype/Tuple-last.check @@ -0,0 +1,26 @@ +0 +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 \ No newline at end of file diff --git a/tests/run-deep-subtype/Tuple-last.scala b/tests/run-deep-subtype/Tuple-last.scala new file mode 100644 index 000000000000..d4bad1719b64 --- /dev/null +++ b/tests/run-deep-subtype/Tuple-last.scala @@ -0,0 +1,65 @@ +import scala.reflect.ClassTag + +object Test { + def main(args: Array[String]): Unit = { + def printArray[T: ClassTag](n: Int, elem: Int => T): Unit = { + val t: Int *: Tuple = 0 *: Tuple.fromArray(Array.tabulate(n)(elem)) + println(t.last) + } + + for (i <- 0 to 25) + printArray(i, j => j) + + assert(1 == Tuple1(1).last) + assert(2 == (1, 2).last) + assert(3 == (1, 2, 3).last) + assert(4 == (1, 2, 3, 4).last) + assert(5 == (1, 2, 3, 4, 5).last) + assert(6 == (1, 2, 3, 4, 5, 6).last) + assert(7 == (1, 2, 3, 4, 5, 6, 7).last) + assert(8 == (1, 2, 3, 4, 5, 6, 7, 8).last) + assert(9 == (1, 2, 3, 4, 5, 6, 7, 8, 9).last) + assert(10 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10).last) + assert(11 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11).last) + assert(12 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12).last) + assert(13 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13).last) + assert(14 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14).last) + assert(15 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15).last) + assert(16 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16).last) + assert(17 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17).last) + assert(18 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18).last) + assert(19 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19).last) + assert(20 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20).last) + assert(21 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21).last) + assert(22 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22).last) + assert(23 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23).last) + assert(24 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24).last) + assert(25 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25).last) + + assert(1 == (1 *: Tuple()).last) + assert(2 == (1 *: 2 *: Tuple()).last) + assert(3 == (1 *: 2 *: 3 *: Tuple()).last) + assert(4 == (1 *: 2 *: 3 *: 4 *: Tuple()).last) + assert(5 == (1 *: 2 *: 3 *: 4 *: 5 *: Tuple()).last) + assert(6 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: Tuple()).last) + assert(7 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: Tuple()).last) + assert(8 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: Tuple()).last) + assert(9 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: Tuple()).last) + assert(10 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: Tuple()).last) + assert(11 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: Tuple()).last) + assert(12 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: Tuple()).last) + assert(13 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: Tuple()).last) + assert(14 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: Tuple()).last) + assert(15 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: Tuple()).last) + assert(16 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: 16 *: Tuple()).last) + assert(17 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: 16 *: 17 *: Tuple()).last) + assert(18 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: 16 *: 17 *: 18 *: Tuple()).last) + assert(19 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: 16 *: 17 *: 18 *: 19 *: Tuple()).last) + assert(20 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: 16 *: 17 *: 18 *: 19 *: 20 *: Tuple()).last) + assert(21 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: 16 *: 17 *: 18 *: 19 *: 20 *: 21 *: Tuple()).last) + assert(22 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: 16 *: 17 *: 18 *: 19 *: 20 *: 21 *: 22 *: Tuple()).last) + assert(23 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: 16 *: 17 *: 18 *: 19 *: 20 *: 21 *: 22 *: 23 *: Tuple()).last) + assert(24 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: 16 *: 17 *: 18 *: 19 *: 20 *: 21 *: 22 *: 23 *: 24 *: Tuple()).last) + assert(25 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: 16 *: 17 *: 18 *: 19 *: 20 *: 21 *: 22 *: 23 *: 24 *: 25 *: Tuple()).last) + } +}