From c6a860898b363797a600743d29bd3fcb8821b2fc Mon Sep 17 00:00:00 2001 From: Antoine Brunner Date: Wed, 27 Nov 2019 18:40:59 +0100 Subject: [PATCH 1/2] Add tests for the current tuple API --- tests/run/tuple-concat.check | 14 +++++++++----- tests/run/tuple-concat.scala | 26 ++++++++++++++++++-------- tests/run/tuple-cons.check | 4 ++++ tests/run/tuple-cons.scala | 13 +++++++++++++ tests/run/tuple-map.check | 3 +++ tests/run/tuple-map.scala | 17 +++++++++++++++++ tests/run/tuple-tail.check | 4 ++++ tests/run/tuple-tail.scala | 13 +++++++++++++ tests/run/tuple-zip.check | 9 +++++++++ tests/run/tuple-zip.scala | 20 ++++++++++++++++++++ 10 files changed, 110 insertions(+), 13 deletions(-) create mode 100644 tests/run/tuple-cons.check create mode 100644 tests/run/tuple-cons.scala create mode 100644 tests/run/tuple-map.check create mode 100644 tests/run/tuple-map.scala create mode 100644 tests/run/tuple-tail.check create mode 100644 tests/run/tuple-tail.scala create mode 100644 tests/run/tuple-zip.check create mode 100644 tests/run/tuple-zip.scala diff --git a/tests/run/tuple-concat.check b/tests/run/tuple-concat.check index 32888b26a398..38350e9aba87 100644 --- a/tests/run/tuple-concat.check +++ b/tests/run/tuple-concat.check @@ -1,5 +1,9 @@ -tuple1 ++ emptyTuple = (e1,e2,e3) -emptyTuple ++ tuple1 = (e1,e2,e3) -tuple2 ++ emptyTuple = (e4,e5,e6) -emptyTuple ++ tuple2 = (e4,e5,e6) -tuple1 ++ tuple2 = (e1,e2,e3,e4,e5,e6) +() +(1,2,3,4,5) +(1,2,3,4,5) +(11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35) +(11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35) +(1,2,3,4,5,6,7,8,9,10) +(1,2,3,4,5,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35) +(11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,1,2,3,4,5) +(11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60) \ No newline at end of file diff --git a/tests/run/tuple-concat.scala b/tests/run/tuple-concat.scala index 86b6e428f2c9..a2f75591ab28 100644 --- a/tests/run/tuple-concat.scala +++ b/tests/run/tuple-concat.scala @@ -1,15 +1,25 @@ object Test extends App { val emptyTuple: Tuple = () - val tuple1: Tuple = "e1" *: "e2" *: "e3" *: () - val tuple2: Tuple = "e4" *: "e5" *: "e6" *: () - val result: Tuple = "e1" *: "e2" *: "e3" *: "e4" *: "e5" *: "e6" *: () + val tuple1: Tuple = ("1", "2", "3", "4", "5") + val tuple2: Tuple = ("6", "7", "8", "9", "10") + val tupleXXL1: Tuple = ("11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35") + val tupleXXL2: Tuple = ("36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "60") - println("tuple1 ++ emptyTuple = " + (tuple1 ++ emptyTuple)) - println("emptyTuple ++ tuple1 = " + (emptyTuple ++ tuple1)) - println("tuple2 ++ emptyTuple = " + (tuple2 ++ emptyTuple)) - println("emptyTuple ++ tuple2 = " + (emptyTuple ++ tuple2)) - println("tuple1 ++ tuple2 = " + (tuple1 ++ tuple2)) + // All possible combinations of concatenating two tuples + println(emptyTuple ++ emptyTuple) + println(emptyTuple ++ tuple1) + println(tuple1 ++ emptyTuple) + println(tupleXXL1 ++ emptyTuple) + println(emptyTuple ++ tupleXXL1) + println(tuple1 ++ tuple2) + println(tuple1 ++ tupleXXL1) + println(tupleXXL1 ++ tuple1) + println(tupleXXL1 ++ tupleXXL2) + + // Concatenation with an empty tuple should be a no-op assert((tuple1 ++ emptyTuple).asInstanceOf[AnyRef] eq tuple1.asInstanceOf[AnyRef]) + assert((tupleXXL1 ++ emptyTuple).asInstanceOf[AnyRef] eq tupleXXL1.asInstanceOf[AnyRef]) assert((emptyTuple ++tuple1).asInstanceOf[AnyRef] eq tuple1.asInstanceOf[AnyRef]) + assert((emptyTuple ++ tupleXXL1).asInstanceOf[AnyRef] eq tupleXXL1.asInstanceOf[AnyRef]) } diff --git a/tests/run/tuple-cons.check b/tests/run/tuple-cons.check new file mode 100644 index 000000000000..e347bf425496 --- /dev/null +++ b/tests/run/tuple-cons.check @@ -0,0 +1,4 @@ +(head) +(head,1,2,3,4,5) +(head,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35) +(head,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57) \ No newline at end of file diff --git a/tests/run/tuple-cons.scala b/tests/run/tuple-cons.scala new file mode 100644 index 000000000000..bae6c0bce3ca --- /dev/null +++ b/tests/run/tuple-cons.scala @@ -0,0 +1,13 @@ + +object Test extends App { + val emptyTuple: Tuple = () + val tuple: Tuple = ("1", "2", "3", "4", "5") + val tupleXXL: Tuple = ("11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35") + val tuple22: Tuple = ("36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", "53", "54", "55", "56", "57") + + // Test all possible combinations of making + println("head" *: emptyTuple) + println("head" *: tuple) + println("head" *: tupleXXL) + println("head" *: tuple22) +} diff --git a/tests/run/tuple-map.check b/tests/run/tuple-map.check new file mode 100644 index 000000000000..18be0e395aad --- /dev/null +++ b/tests/run/tuple-map.check @@ -0,0 +1,3 @@ +() +(2,3,4,5,6) +(21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45) \ No newline at end of file diff --git a/tests/run/tuple-map.scala b/tests/run/tuple-map.scala new file mode 100644 index 000000000000..10ddb6bf0241 --- /dev/null +++ b/tests/run/tuple-map.scala @@ -0,0 +1,17 @@ + +object Test extends App { + val emptyTuple: Tuple = () + val tuple: Tuple = ("1", "2", "3", "4", "5") + val tupleXXL: Tuple = ("11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35") + + type Id[X] = X + val f: [t] => t => Id[t] = [t] => (x: t) => { + val str = x.asInstanceOf[String] + str.updated(0, (str(0) + 1).toChar).asInstanceOf[t] + } + + // Test all possible combinations of making + println(emptyTuple.map(f)) + println(tuple.map(f)) + println(tupleXXL.map(f)) +} diff --git a/tests/run/tuple-tail.check b/tests/run/tuple-tail.check new file mode 100644 index 000000000000..3181792894ca --- /dev/null +++ b/tests/run/tuple-tail.check @@ -0,0 +1,4 @@ +() +(2,3,4,5) +(12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35) +(37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58) \ No newline at end of file diff --git a/tests/run/tuple-tail.scala b/tests/run/tuple-tail.scala new file mode 100644 index 000000000000..349f9871efde --- /dev/null +++ b/tests/run/tuple-tail.scala @@ -0,0 +1,13 @@ + +object Test extends App { + val singletonTuple: NonEmptyTuple = Tuple1("59") + val tuple: NonEmptyTuple = ("1", "2", "3", "4", "5") + val tupleXXL: NonEmptyTuple = ("11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35") + val tuple23: NonEmptyTuple = ("36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", "53", "54", "55", "56", "57", "58") + + // Test all possible combinations of making + println(singletonTuple.tail) + println(tuple.tail) + println(tupleXXL.tail) + println(tuple23.tail) +} diff --git a/tests/run/tuple-zip.check b/tests/run/tuple-zip.check new file mode 100644 index 000000000000..affc778af032 --- /dev/null +++ b/tests/run/tuple-zip.check @@ -0,0 +1,9 @@ +() +() +() +() +() +((1,6),(2,7),(3,8),(4,9),(5,10)) +((1,11),(2,12),(3,13),(4,14),(5,15)) +((11,1),(12,2),(13,3),(14,4),(15,5)) +((11,36),(12,37),(13,38),(14,39),(15,40),(16,41),(17,42),(18,43),(19,44),(20,45),(21,46),(22,47),(23,48),(24,49),(25,50),(26,51),(27,52),(28,53),(29,54),(30,55),(31,56),(32,57),(33,58),(34,59),(35,60)) \ No newline at end of file diff --git a/tests/run/tuple-zip.scala b/tests/run/tuple-zip.scala new file mode 100644 index 000000000000..e5f36d7a1583 --- /dev/null +++ b/tests/run/tuple-zip.scala @@ -0,0 +1,20 @@ + +object Test extends App { + val emptyTuple: Tuple = () + val tuple1: Tuple = ("1", "2", "3", "4", "5") + val tuple2: Tuple = ("6", "7", "8", "9", "10") + val tupleXXL1: Tuple = ("11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35") + val tupleXXL2: Tuple = ("36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "60") + + // All possible combinations of zipping two tuples + println(emptyTuple zip emptyTuple) + println(emptyTuple zip tuple1) + println(tuple1 zip emptyTuple) + println(tupleXXL1 zip emptyTuple) + println(emptyTuple zip tupleXXL1) + println(tuple1 zip tuple2) + println(tuple1 zip tupleXXL1) + println(tupleXXL1 zip tuple1) + println(tupleXXL1 zip tupleXXL2) +} + From dbd777d66dab8cd455093e554605b7547eaceef2 Mon Sep 17 00:00:00 2001 From: Antoine Brunner Date: Wed, 27 Nov 2019 20:19:14 +0100 Subject: [PATCH 2/2] Fix issue with tuple map --- library/src/scala/runtime/DynamicTuple.scala | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/library/src/scala/runtime/DynamicTuple.scala b/library/src/scala/runtime/DynamicTuple.scala index ae75f133a5c1..53d44f75d449 100644 --- a/library/src/scala/runtime/DynamicTuple.scala +++ b/library/src/scala/runtime/DynamicTuple.scala @@ -257,9 +257,12 @@ object DynamicTuple { ).asInstanceOf[Zip[This, T2]] } - def dynamicMap[This <: Tuple, F[_]](self: This, f: [t] => t => F[t]): Map[This, F] = - Tuple.fromArray(self.asInstanceOf[Product].productIterator.map(f(_)).toArray) // TODO use toIArray of Object to avoid double/triple array copy - .asInstanceOf[Map[This, F]] + def dynamicMap[This <: Tuple, F[_]](self: This, f: [t] => t => F[t]): Map[This, F] = (self: Any) match { + case self: Unit => ().asInstanceOf[Map[This, F]] + case _ => + Tuple.fromArray(self.asInstanceOf[Product].productIterator.map(f(_)).toArray) // TODO use toIArray of Object to avoid double/triple array copy + .asInstanceOf[Map[This, F]] + } def consIterator(head: Any, tail: Tuple): Iterator[Any] = Iterator.single(head) ++ tail.asInstanceOf[Product].productIterator