From 3d9b5d174ea5c4347be7d9248166a8049e9289f1 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 24 Oct 2018 08:35:54 +0200 Subject: [PATCH 1/2] Fix #5269: Fix StagedTuple/Tuple implementation --- compiler/test/dotty/tools/dotc/CompilationTests.scala | 1 + library/src-scala3/scala/StagedTuple.scala | 2 +- library/src-scala3/scala/Tuple.scala | 2 +- tests/{pending => run-custom-args}/tuple-cons.scala | 0 tests/run/tuple-cons-2.scala | 7 +++++++ 5 files changed, 10 insertions(+), 2 deletions(-) rename tests/{pending => run-custom-args}/tuple-cons.scala (100%) create mode 100644 tests/run/tuple-cons-2.scala diff --git a/compiler/test/dotty/tools/dotc/CompilationTests.scala b/compiler/test/dotty/tools/dotc/CompilationTests.scala index 566b6bcbf4cb..55fa7181faec 100644 --- a/compiler/test/dotty/tools/dotc/CompilationTests.scala +++ b/compiler/test/dotty/tools/dotc/CompilationTests.scala @@ -171,6 +171,7 @@ class CompilationTests extends ParallelTesting { @Test def runAll: Unit = { implicit val testGroup: TestGroup = TestGroup("runAll") compileFilesInDir("tests/run-custom-args/Yretain-trees", defaultOptions and "-Yretain-trees") + + compileFile("tests/run-custom-args/tuple-cons.scala", allowDeepSubtypes) + compileFilesInDir("tests/run", defaultOptions) }.checkRuns() diff --git a/library/src-scala3/scala/StagedTuple.scala b/library/src-scala3/scala/StagedTuple.scala index c3fd0aaf45f8..974ac98306e1 100644 --- a/library/src-scala3/scala/StagedTuple.scala +++ b/library/src-scala3/scala/StagedTuple.scala @@ -190,7 +190,7 @@ object StagedTuple { case Some(4) => self.as[Tuple4[_, _, _, _]].bind(t => '(Tuple5(~x, (~t)._1, (~t)._2, (~t)._3, (~t)._4))) case Some(n) => - fromArrayStaged('($consArray(~x, ~toArrayStaged(self, tailSize))), Some(n + 1)) + fromArrayStaged[H *: T]('($consArray(~x, ~toArrayStaged(self, tailSize))), Some(n + 1)) case _ => '(dynamic_*:[T, H](~self, ~x)) } diff --git a/library/src-scala3/scala/Tuple.scala b/library/src-scala3/scala/Tuple.scala index 655af4d075c2..3a6358f9c7aa 100644 --- a/library/src-scala3/scala/Tuple.scala +++ b/library/src-scala3/scala/Tuple.scala @@ -131,7 +131,7 @@ object Tuple { val t = self.asInstanceOf[Tuple4[Object, Object, Object, Object]] Array(t._1, t._2, t._3, t._4) case self: TupleXXL => - asInstanceOf[TupleXXL].elems + self.elems case self: Product => val arr = new Array[Object](self.productArity) for (i <- 0 until arr.length) arr(i) = self.productElement(i).asInstanceOf[Object] diff --git a/tests/pending/tuple-cons.scala b/tests/run-custom-args/tuple-cons.scala similarity index 100% rename from tests/pending/tuple-cons.scala rename to tests/run-custom-args/tuple-cons.scala diff --git a/tests/run/tuple-cons-2.scala b/tests/run/tuple-cons-2.scala new file mode 100644 index 000000000000..2a74c47aaea5 --- /dev/null +++ b/tests/run/tuple-cons-2.scala @@ -0,0 +1,7 @@ + +object Test { + def main(args: Array[String]): Unit = { + val t6: (Int,Int,Int,Int,Int,Int) = 1 *: (2, 3, 4, 5, 6) + println(t6) + } +} From 872a20e22ed442810c346cf9ff2b48d4e0012ca1 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 24 Oct 2018 09:38:16 +0200 Subject: [PATCH 2/2] Evaluate creation of array only once --- library/src-scala3/scala/StagedTuple.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/src-scala3/scala/StagedTuple.scala b/library/src-scala3/scala/StagedTuple.scala index 974ac98306e1..68fd9ab4980f 100644 --- a/library/src-scala3/scala/StagedTuple.scala +++ b/library/src-scala3/scala/StagedTuple.scala @@ -30,7 +30,7 @@ object StagedTuple { def fromArrayStaged[T <: Tuple : Type](xs: Expr[Array[Object]], size: Option[Int]): Expr[T] = { if (!specialize) '(dynamicFromArray[T](~xs)) - else { + else xs.bind { xs => val tup: Expr[Any] = size match { case Some(0) => '() case Some(1) => '(Tuple1( (~xs)(0)))