From 3b35795a0fee77f550d8219d39173798393df613 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Thu, 23 Jan 2020 09:31:21 +0100 Subject: [PATCH] Workaround LazyRef CyclicReference in genDocs Add more explicit types to avoid inference involving type matches. Also avoid recomputing tuple sizes. --- .../src/scala/internal/quoted/Matcher.scala | 6 ++- .../src/scala/quoted/unsafe/UnsafeExpr.scala | 8 ++-- library/src/scala/runtime/DynamicTuple.scala | 37 ++++++++++--------- 3 files changed, 27 insertions(+), 24 deletions(-) diff --git a/library/src/scala/internal/quoted/Matcher.scala b/library/src/scala/internal/quoted/Matcher.scala index 5b41e3fd8ca6..422ec25f1f9b 100644 --- a/library/src/scala/internal/quoted/Matcher.scala +++ b/library/src/scala/internal/quoted/Matcher.scala @@ -259,9 +259,11 @@ private[quoted] object Matcher { if (hasBindAnnotation(pattern.symbol)) bindingMatch(scrutinee.symbol) else matched def rhsEnv = - summon[Env] + (scrutinee.symbol -> pattern.symbol) ++ - typeParams1.zip(typeParams2).map((tparam1, tparam2) => tparam1.symbol -> tparam2.symbol) ++ + val oldEnv: Env = summon[Env] + val newEnv: List[(Symbol, Symbol)] = + (scrutinee.symbol -> pattern.symbol) :: typeParams1.zip(typeParams2).map((tparam1, tparam2) => tparam1.symbol -> tparam2.symbol) ::: paramss1.flatten.zip(paramss2.flatten).map((param1, param2) => param1.symbol -> param2.symbol) + oldEnv ++ newEnv bindMatch && typeParams1 =?= typeParams2 && diff --git a/library/src/scala/quoted/unsafe/UnsafeExpr.scala b/library/src/scala/quoted/unsafe/UnsafeExpr.scala index fa447bff7ec5..3730241c1cc5 100644 --- a/library/src/scala/quoted/unsafe/UnsafeExpr.scala +++ b/library/src/scala/quoted/unsafe/UnsafeExpr.scala @@ -40,23 +40,23 @@ object UnsafeExpr { */ def open[T1, R, X](f: Expr[T1 => R])(content: (Expr[R], [t] => Expr[t] => Expr[T1] => Expr[t]) => X)(given qctx: QuoteContext): X = { import qctx.tasty.{given, _} - val (params, bodyExpr) = paramsAndBody(f) + val (params, bodyExpr) = paramsAndBody[R](f) content(bodyExpr, [t] => (e: Expr[t]) => (v: Expr[T1]) => bodyFn[t](e.unseal, params, List(v.unseal)).seal.asInstanceOf[Expr[t]]) } def open[T1, T2, R, X](f: Expr[(T1, T2) => R])(content: (Expr[R], [t] => Expr[t] => (Expr[T1], Expr[T2]) => Expr[t]) => X)(given qctx: QuoteContext)(given DummyImplicit): X = { import qctx.tasty.{given, _} - val (params, bodyExpr) = paramsAndBody(f) + val (params, bodyExpr) = paramsAndBody[R](f) content(bodyExpr, [t] => (e: Expr[t]) => (v1: Expr[T1], v2: Expr[T2]) => bodyFn[t](e.unseal, params, List(v1.unseal, v2.unseal)).seal.asInstanceOf[Expr[t]]) } def open[T1, T2, T3, R, X](f: Expr[(T1, T2, T3) => R])(content: (Expr[R], [t] => Expr[t] => (Expr[T1], Expr[T2], Expr[T3]) => Expr[t]) => X)(given qctx: QuoteContext)(given DummyImplicit, DummyImplicit): X = { import qctx.tasty.{given, _} - val (params, bodyExpr) = paramsAndBody(f) + val (params, bodyExpr) = paramsAndBody[R](f) content(bodyExpr, [t] => (e: Expr[t]) => (v1: Expr[T1], v2: Expr[T2], v3: Expr[T3]) => bodyFn[t](e.unseal, params, List(v1.unseal, v2.unseal, v3.unseal)).seal.asInstanceOf[Expr[t]]) } - private def paramsAndBody[R](given qctx: QuoteContext)(f: Expr[Any]) = { + private def paramsAndBody[R](given qctx: QuoteContext)(f: Expr[Any]): (List[qctx.tasty.ValDef], Expr[R]) = { import qctx.tasty.{given, _} val Block(List(DefDef("$anonfun", Nil, List(params), _, Some(body))), Closure(Ident("$anonfun"), None)) = f.unseal.etaExpand (params, body.seal.asInstanceOf[Expr[R]]) diff --git a/library/src/scala/runtime/DynamicTuple.scala b/library/src/scala/runtime/DynamicTuple.scala index 457b1780b414..6d3c9f6bf6c3 100644 --- a/library/src/scala/runtime/DynamicTuple.scala +++ b/library/src/scala/runtime/DynamicTuple.scala @@ -274,31 +274,29 @@ object DynamicTuple { def dynamicConcat[This <: Tuple, That <: Tuple](self: This, that: That): Concat[This, That] = { type Result = Concat[This, That] + val selfSize: Int = self.size // If one of the tuples is empty, we can leave early - (self: Any) match { - case self: Unit => return that.asInstanceOf[Result] - case _ => - } + if selfSize == 0 then + return that.asInstanceOf[Result] - (that: Any) match { - case that: Unit => return self.asInstanceOf[Result] - case _ => - } + val thatSize: Int = that.size + if thatSize == 0 then + return self.asInstanceOf[Result] - val arr = new Array[Object](self.size + that.size) + val arr = new Array[Object](selfSize + thatSize) // Copies the tuple to an array, at the given offset - inline def copyToArray[T <: Tuple](tuple: T, array: Array[Object], offset: Int): Unit = (tuple: Any) match { + inline def copyToArray[T <: Tuple](tuple: T, size: Int, array: Array[Object], offset: Int): Unit = (tuple: Any) match { case xxl: TupleXXL => - System.arraycopy(xxl.elems, 0, array, offset, tuple.size) + System.arraycopy(xxl.elems, 0, array, offset, size) case _ => tuple.asInstanceOf[Product].productIterator.asInstanceOf[Iterator[Object]] - .copyToArray(array, offset, tuple.size) + .copyToArray(array, offset, size) } // In the general case, we copy the two tuples to an array, and convert it back to a tuple - copyToArray(self, arr, 0) - copyToArray(that, arr, self.size) + copyToArray(self, selfSize, arr, 0) + copyToArray(that, thatSize, arr, selfSize) dynamicFromIArray[Result](arr.asInstanceOf[IArray[Object]]) } @@ -401,9 +399,11 @@ object DynamicTuple { } def dynamicZip[This <: Tuple, T2 <: Tuple](t1: This, t2: T2): Zip[This, T2] = { - if (t1.size == 0 || t2.size == 0) return ().asInstanceOf[Zip[This, T2]] - val size = Math.min(t1.size, t2.size) - Tuple.fromIArray( + val t1Size: Int = t1.size + val t2Size: Int = t2.size + val size = Math.min(t1Size, t2Size) + if size == 0 then ().asInstanceOf[Zip[This, T2]] + else Tuple.fromIArray( zipIterators( t1.asInstanceOf[Product].productIterator, t2.asInstanceOf[Product].productIterator, @@ -475,7 +475,8 @@ object DynamicTuple { def dynamicTake[This <: Tuple, N <: Int](self: This, n: N): Take[This, N] = { if (n < 0) throw new IndexOutOfBoundsException(n.toString) - val actualN = Math.min(n, self.size) + val selfSize: Int = self.size + val actualN = Math.min(n, selfSize) type Result = Take[This, N]