Skip to content

Commit 8e323b1

Browse files
Merge pull request #5822 from dotty-staging/fix-#5409
StagedTuple changes
2 parents 2ecb0f3 + 70db6b5 commit 8e323b1

File tree

14 files changed

+254
-198
lines changed

14 files changed

+254
-198
lines changed

compiler/src/dotty/tools/dotc/transform/Splicer.scala

+8-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,14 @@ object Splicer {
4646
}
4747
catch {
4848
case ex: scala.quoted.QuoteError =>
49-
ctx.error(ex.getMessage, pos)
49+
val pos1 = ex.from match {
50+
case None => pos
51+
case Some(expr) =>
52+
val reflect: scala.tasty.Reflection = ReflectionImpl(ctx)
53+
import reflect._
54+
expr.unseal.underlyingArgument.pos.asInstanceOf[SourcePosition]
55+
}
56+
ctx.error(ex.getMessage, pos1)
5057
EmptyTree
5158
case NonFatal(ex) =>
5259
val msg =

docs/docs/reference/other-new-features/tasty-reflect.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,10 @@ def natConstImpl(x: Expr[Int])(implicit reflection: Reflection): Expr[Int] = {
4242
xTree match {
4343
case Term.Literal(Constant.Int(n)) =>
4444
if (n <= 0)
45-
throw new QuoteError("Parameter must be natural number")
45+
QuoteError("Parameter must be natural number")
4646
n.toExpr
4747
case _ =>
48-
throw new QuoteError("Parameter must be a known constant")
48+
QuoteError("Parameter must be a known constant")
4949
}
5050
}
5151
```
+40-167
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
package scala
22
import annotation.showAsInfix
33
import compiletime._
4-
import scala.StagedTuple
4+
import internal._
55

66
sealed trait Tuple extends Any {
77
import Tuple._
88

99
inline def toArray: Array[Object] =
10-
if (stageIt) stagedToArray
10+
if (stageIt) toArrayStaged
1111
else inline constValueOpt[BoundedSize[this.type]] match {
1212
case Some(0) =>
13-
empty$Array
13+
scala.runtime.DynamicTuple.empty$Array
1414
case Some(1) =>
1515
val t = asInstanceOf[Tuple1[Object]]
1616
Array(t._1)
@@ -23,19 +23,19 @@ sealed trait Tuple extends Any {
2323
case Some(4) =>
2424
val t = asInstanceOf[Tuple4[Object, Object, Object, Object]]
2525
Array(t._1, t._2, t._3, t._4)
26-
case Some(n) if n <= MaxSpecialized =>
26+
case Some(n) if n <= scala.runtime.DynamicTuple.MaxSpecialized =>
2727
to$Array(this, n)
2828
case Some(n) =>
2929
asInstanceOf[TupleXXL].elems
3030
case None =>
31-
dynamicToArray(this)
31+
runtime.DynamicTuple.dynamicToArray(this)
3232
}
3333

34-
inline def stagedToArray: Array[Object] =
34+
inline def toArrayStaged: Array[Object] =
3535
${ StagedTuple.toArrayStaged('this, constValueOpt[BoundedSize[this.type]]) }
3636

3737
inline def *: [H, This >: this.type <: Tuple] (x: H): H *: This =
38-
if (stageIt) stagedCons[H](x)
38+
if (stageIt) consStaged[H](x)
3939
else {
4040
type Result = H *: This
4141
inline constValueOpt[BoundedSize[this.type]] match {
@@ -55,15 +55,15 @@ sealed trait Tuple extends Any {
5555
case Some(n) =>
5656
fromArray[H *: this.type](cons$Array(x, toArray))
5757
case _ =>
58-
dynamic_*:[This, H](this, x)
58+
runtime.DynamicTuple.dynamic_*:[This, H](this, x)
5959
}
6060
}
6161

62-
inline def stagedCons[H] (x: H): H *: this.type =
63-
${ StagedTuple.stagedCons('this, 'x, constValueOpt[BoundedSize[this.type]]) }
62+
inline def consStaged[H] (x: H): H *: this.type =
63+
${ StagedTuple.consStaged('this, 'x, constValueOpt[BoundedSize[this.type]]) }
6464

6565
inline def ++ [This >: this.type <: Tuple](that: Tuple): Concat[This, that.type] =
66-
if (stageIt) stagedConcat(that).asInstanceOf
66+
if (stageIt) concatStaged(that).asInstanceOf
6767
else {
6868
type Result = Concat[This, that.type]
6969
inline constValueOpt[BoundedSize[this.type]] match {
@@ -99,35 +99,32 @@ sealed trait Tuple extends Any {
9999
if (constValue[BoundedSize[that.type]] == 0) this.asInstanceOf[Result]
100100
else genericConcat[Result](this, that).asInstanceOf[Result]
101101
case None =>
102-
dynamic_++[This, that.type](this, that)
102+
runtime.DynamicTuple.dynamic_++[This, that.type](this, that)
103103
}
104104
}
105105

106-
inline def stagedConcat(that: Tuple): Concat[this.type, that.type] =
107-
${ StagedTuple.stagedConcat('this, constValueOpt[BoundedSize[this.type]],
106+
inline def concatStaged(that: Tuple): Concat[this.type, that.type] =
107+
${ StagedTuple.concatStaged('this, constValueOpt[BoundedSize[this.type]],
108108
'that, constValueOpt[BoundedSize[that.type]]) }
109109

110110
inline def genericConcat[T <: Tuple](xs: Tuple, ys: Tuple): Tuple =
111111
fromArray[T](xs.toArray ++ ys.toArray)
112112

113113
inline def size[This >: this.type <: Tuple]: Size[This] =
114-
if (stageIt) stagedSize.asInstanceOf
114+
if (stageIt) sizeStaged.asInstanceOf
115115
else {
116116
type Result = Size[This]
117117
inline constValueOpt[BoundedSize[this.type]] match {
118118
case Some(n) => n.asInstanceOf[Result]
119-
case _ => dynamicSize(this)
119+
case _ => runtime.DynamicTuple.dynamicSize(this)
120120
}
121121
}
122122

123-
inline def stagedSize: Size[this.type] =
123+
inline def sizeStaged: Size[this.type] =
124124
${ StagedTuple.sizeStaged[Size[this.type]]('this, constValueOpt[BoundedSize[this.type]]) }
125125
}
126126

127127
object Tuple {
128-
inline val MaxSpecialized = 22
129-
inline private val XXL = MaxSpecialized + 1
130-
131128
final val stageIt = false
132129

133130
type Head[X <: NonEmptyTuple] = X match {
@@ -167,7 +164,7 @@ object Tuple {
167164

168165
private[scala] type BoundedSize[X] = BoundedSizeRecur[X, 23]
169166

170-
val empty$Array = Array[Object]()
167+
val $emptyArray = Array[Object]()
171168

172169
def to$Array(xs: Tuple, n: Int) = {
173170
val arr = new Array[Object](n)
@@ -188,7 +185,7 @@ object Tuple {
188185
}
189186

190187
inline def fromArray[T <: Tuple](xs: Array[Object]): T =
191-
if (stageIt) stagedFromArray[T](xs)
188+
if (stageIt) fromArrayStaged[T](xs)
192189
else inline constValue[BoundedSize[T]] match {
193190
case 0 => ().asInstanceOf[T]
194191
case 1 => Tuple1(xs(0)).asInstanceOf[T]
@@ -216,103 +213,15 @@ object Tuple {
216213
case _ => TupleXXL(xs).asInstanceOf[T]
217214
}
218215

219-
inline def stagedFromArray[T <: Tuple](xs: Array[Object]): T =
220-
${ StagedTuple.fromArrayStaged[T]('xs, constValueOpt[BoundedSize[this.type]]) }
221-
222-
def dynamicFromArray[T <: Tuple](xs: Array[Object]): T = xs.length match {
223-
case 0 => ().asInstanceOf[T]
224-
case 1 => Tuple1(xs(0)).asInstanceOf[T]
225-
case 2 => Tuple2(xs(0), xs(1)).asInstanceOf[T]
226-
case 3 => Tuple3(xs(0), xs(1), xs(2)).asInstanceOf[T]
227-
case 4 => Tuple4(xs(0), xs(1), xs(2), xs(3)).asInstanceOf[T]
228-
case 5 => Tuple5(xs(0), xs(1), xs(2), xs(3), xs(4)).asInstanceOf[T]
229-
case 6 => Tuple6(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5)).asInstanceOf[T]
230-
case 7 => Tuple7(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6)).asInstanceOf[T]
231-
case 8 => Tuple8(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6), xs(7)).asInstanceOf[T]
232-
case 9 => Tuple9(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6), xs(7), xs(8)).asInstanceOf[T]
233-
case 10 => Tuple10(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6), xs(7), xs(8), xs(9)).asInstanceOf[T]
234-
case 11 => Tuple11(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6), xs(7), xs(8), xs(9), xs(10)).asInstanceOf[T]
235-
case 12 => Tuple12(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6), xs(7), xs(8), xs(9), xs(10), xs(11)).asInstanceOf[T]
236-
case 13 => Tuple13(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6), xs(7), xs(8), xs(9), xs(10), xs(11), xs(12)).asInstanceOf[T]
237-
case 14 => Tuple14(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6), xs(7), xs(8), xs(9), xs(10), xs(11), xs(12), xs(13)).asInstanceOf[T]
238-
case 15 => Tuple15(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6), xs(7), xs(8), xs(9), xs(10), xs(11), xs(12), xs(13), xs(14)).asInstanceOf[T]
239-
case 16 => Tuple16(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6), xs(7), xs(8), xs(9), xs(10), xs(11), xs(12), xs(13), xs(14), xs(15)).asInstanceOf[T]
240-
case 17 => Tuple17(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6), xs(7), xs(8), xs(9), xs(10), xs(11), xs(12), xs(13), xs(14), xs(15), xs(16)).asInstanceOf[T]
241-
case 18 => Tuple18(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6), xs(7), xs(8), xs(9), xs(10), xs(11), xs(12), xs(13), xs(14), xs(15), xs(16), xs(17)).asInstanceOf[T]
242-
case 19 => Tuple19(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6), xs(7), xs(8), xs(9), xs(10), xs(11), xs(12), xs(13), xs(14), xs(15), xs(16), xs(17), xs(18)).asInstanceOf[T]
243-
case 20 => Tuple20(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6), xs(7), xs(8), xs(9), xs(10), xs(11), xs(12), xs(13), xs(14), xs(15), xs(16), xs(17), xs(18), xs(19)).asInstanceOf[T]
244-
case 21 => Tuple21(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6), xs(7), xs(8), xs(9), xs(10), xs(11), xs(12), xs(13), xs(14), xs(15), xs(16), xs(17), xs(18), xs(19), xs(20)).asInstanceOf[T]
245-
case 22 => Tuple22(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6), xs(7), xs(8), xs(9), xs(10), xs(11), xs(12), xs(13), xs(14), xs(15), xs(16), xs(17), xs(18), xs(19), xs(20), xs(21)).asInstanceOf[T]
246-
case _ => TupleXXL(xs).asInstanceOf[T]
247-
}
248-
249-
def dynamicToArray(self: Tuple): Array[Object] = (self: Any) match {
250-
case self: Unit =>
251-
empty$Array
252-
case self: Tuple1[_] =>
253-
val t = self.asInstanceOf[Tuple1[Object]]
254-
Array(t._1)
255-
case self: Tuple2[_, _] =>
256-
val t = self.asInstanceOf[Tuple2[Object, Object]]
257-
Array(t._1, t._2)
258-
case self: Tuple3[_, _, _] =>
259-
val t = self.asInstanceOf[Tuple3[Object, Object, Object]]
260-
Array(t._1, t._2, t._3)
261-
case self: Tuple4[_, _, _, _] =>
262-
val t = self.asInstanceOf[Tuple4[Object, Object, Object, Object]]
263-
Array(t._1, t._2, t._3, t._4)
264-
case self: TupleXXL =>
265-
self.elems
266-
case self: Product =>
267-
val arr = new Array[Object](self.productArity)
268-
for (i <- 0 until arr.length) arr(i) = self.productElement(i).asInstanceOf[Object]
269-
arr
270-
}
271-
272-
def dynamic_*: [This <: Tuple, H] (self: Tuple, x: H): H *: This = {
273-
type Result = H *: This
274-
(self: Any) match {
275-
case Unit =>
276-
Tuple1(x).asInstanceOf[Result]
277-
case self: Tuple1[_] =>
278-
Tuple2(x, self._1).asInstanceOf[Result]
279-
case self: Tuple2[_, _] =>
280-
Tuple3(x, self._1, self._2).asInstanceOf[Result]
281-
case self: Tuple3[_, _, _] =>
282-
Tuple4(x, self._1, self._2, self._3).asInstanceOf[Result]
283-
case self: Tuple4[_, _, _, _] =>
284-
Tuple5(x, self._1, self._2, self._3, self._4).asInstanceOf[Result]
285-
case _ =>
286-
dynamicFromArray[Result](cons$Array(x, dynamicToArray(self)))
287-
}
288-
}
289-
290-
def dynamic_++[This <: Tuple, That <: Tuple](self: This, that: That): Concat[This, That] = {
291-
type Result = Concat[This, That]
292-
(this: Any) match {
293-
case self: Unit => return self.asInstanceOf[Result]
294-
case _ =>
295-
}
296-
(that: Any) match {
297-
case that: Unit => return self.asInstanceOf[Result]
298-
case _ =>
299-
}
300-
dynamicFromArray[Result](dynamicToArray(self) ++ dynamicToArray(that))
301-
}
302-
303-
def dynamicSize[This <: Tuple](self: This): Size[This] = (self: Any) match {
304-
case self: Unit => 0.asInstanceOf[Size[This]]
305-
case self: TupleXXL => self.elems.length.asInstanceOf[Size[This]]
306-
case self: Product => self.productArity.asInstanceOf[Size[This]]
307-
}
216+
inline def fromArrayStaged[T <: Tuple](xs: Array[Object]): T =
217+
${StagedTuple.fromArrayStaged[T]('xs, constValueOpt[BoundedSize[this.type]])}
308218
}
309219

310220
sealed trait NonEmptyTuple extends Tuple {
311221
import Tuple._
312-
import NonEmptyTuple._
313222

314223
inline def head[This >: this.type <: NonEmptyTuple]: Head[This] =
315-
if (stageIt) stagedHead.asInstanceOf
224+
if (stageIt) headStaged.asInstanceOf
316225
else {
317226
type Result = Head[This]
318227
val resVal = inline constValueOpt[BoundedSize[this.type]] match {
@@ -328,22 +237,22 @@ sealed trait NonEmptyTuple extends Tuple {
328237
case Some(4) =>
329238
val t = asInstanceOf[Tuple4[_, _, _, _]]
330239
t._1
331-
case Some(n) if n > 4 && n <= MaxSpecialized =>
240+
case Some(n) if n > 4 && n <= scala.runtime.DynamicTuple.MaxSpecialized =>
332241
asInstanceOf[Product].productElement(0)
333-
case Some(n) if n > MaxSpecialized =>
242+
case Some(n) if n > scala.runtime.DynamicTuple.MaxSpecialized =>
334243
val t = asInstanceOf[TupleXXL]
335244
t.elems(0)
336245
case None =>
337-
dynamicHead[this.type](this)
246+
scala.runtime.DynamicTuple.dynamicHead[this.type](this)
338247
}
339248
resVal.asInstanceOf[Result]
340249
}
341250

342-
inline def stagedHead: Head[this.type] =
251+
inline def headStaged: Head[this.type] =
343252
${ StagedTuple.headStaged[this.type]('this, constValueOpt[BoundedSize[this.type]]) }
344253

345254
inline def tail[This >: this.type <: NonEmptyTuple]: Tail[This] =
346-
if (stageIt) stagedTail.asInstanceOf
255+
if (stageIt) tailStaged.asInstanceOf
347256
else {
348257
type Result = Tail[This]
349258
inline constValueOpt[BoundedSize[this.type]] match {
@@ -364,21 +273,21 @@ sealed trait NonEmptyTuple extends Tuple {
364273
case Some(n) if n > 5 =>
365274
fromArray[Result](toArray.tail)
366275
case None =>
367-
dynamicTail[This](this)
276+
runtime.DynamicTuple.dynamicTail[This](this)
368277
}
369278
}
370279

371-
inline def stagedTail: Tail[this.type] =
280+
inline def tailStaged: Tail[this.type] =
372281
${ StagedTuple.tailStaged[this.type]('this, constValueOpt[BoundedSize[this.type]]) }
373282

374283
inline def fallbackApply(n: Int) =
375284
inline constValueOpt[n.type] match {
376285
case Some(n: Int) => error("index out of bounds: ", n)
377-
case None => dynamicApply[this.type, n.type](this, n)
286+
case None => runtime.DynamicTuple.dynamicApply[this.type, n.type](this, n)
378287
}
379288

380289
inline def apply[This >: this.type <: NonEmptyTuple](n: Int): Elem[This, n.type] =
381-
if (stageIt) stagedApply(n).asInstanceOf
290+
if (stageIt) applyStaged(n).asInstanceOf
382291
else {
383292
type Result = Elem[This, n.type]
384293
inline constValueOpt[Size[this.type]] match {
@@ -412,13 +321,13 @@ sealed trait NonEmptyTuple extends Tuple {
412321
case Some(3) => t._4.asInstanceOf[Result]
413322
case _ => fallbackApply(n).asInstanceOf[Result]
414323
}
415-
case Some(s) if s > 4 && s <= MaxSpecialized =>
324+
case Some(s) if s > 4 && s <= scala.runtime.DynamicTuple.MaxSpecialized =>
416325
val t = asInstanceOf[Product]
417326
inline constValueOpt[n.type] match {
418327
case Some(n) if n >= 0 && n < s => t.productElement(n).asInstanceOf[Result]
419328
case _ => fallbackApply(n).asInstanceOf[Result]
420329
}
421-
case Some(s) if s > MaxSpecialized =>
330+
case Some(s) if s > scala.runtime.DynamicTuple.MaxSpecialized =>
422331
val t = asInstanceOf[TupleXXL]
423332
inline constValueOpt[n.type] match {
424333
case Some(n) if n >= 0 && n < s => t.elems(n).asInstanceOf[Result]
@@ -428,53 +337,17 @@ sealed trait NonEmptyTuple extends Tuple {
428337
}
429338
}
430339

431-
inline def stagedApply(n: Int): Elem[this.type, n.type] =
432-
${ StagedTuple.applyStaged[this.type, n.type](
433-
'this, constValueOpt[Size[this.type]],
434-
'n, constValueOpt[n.type]) }
435-
}
436-
437-
object NonEmptyTuple {
438-
import Tuple._
439-
440-
def dynamicHead[This <: NonEmptyTuple] (self: This): Head[This] = {
441-
type Result = Head[This]
442-
val res = (self: Any) match {
443-
case self: Tuple1[_] => self._1
444-
case self: Tuple2[_, _] => self._1
445-
case self: Tuple3[_, _, _] => self._1
446-
case self: Tuple4[_, _, _, _] => self._1
447-
case self: TupleXXL => self.elems(0)
448-
case self: Product => self.productElement(0)
449-
}
450-
res.asInstanceOf[Result]
451-
}
452-
453-
def dynamicTail[This <: NonEmptyTuple] (self: This): Tail[This] = {
454-
type Result = Tail[This]
455-
val res = (self: Any) match {
456-
case self: Tuple1[_] => ()
457-
case self: Tuple2[_, _] => Tuple1(self._2)
458-
case self: Tuple3[_, _, _] => Tuple2(self._2, self._3)
459-
case self: Tuple4[_, _, _, _] => Tuple3(self._2, self._3, self._4)
460-
case _ => dynamicFromArray[Result](dynamicToArray(self).tail)
461-
}
462-
res.asInstanceOf[Result]
463-
}
464-
465-
def dynamicApply[This <: NonEmptyTuple, N <: Int] (self: This, n: N): Elem[This, N] = {
466-
type Result = Elem[This, N]
467-
val res = (self: Any) match {
468-
case self: TupleXXL => self.elems(n)
469-
case self: Product => self.productElement(n)
470-
}
471-
res.asInstanceOf[Result]
472-
}
340+
inline def applyStaged(n: Int): Elem[this.type, n.type] =
341+
${StagedTuple.applyStaged[this.type, n.type](
342+
'this, constValueOpt[Size[this.type]], 'n, constValueOpt[n.type])}
473343
}
474344

475345
@showAsInfix
476346
sealed class *:[+H, +T <: Tuple] extends NonEmptyTuple
477347

478348
object *: {
479-
inline def unapply[H, T <: Tuple](x: H *: T) = (x.head, x.tail)
349+
inline def unapply[H, T <: Tuple](x: H *: T) =
350+
// With stageIt on we cannot expand x.head in the same run and fails
351+
if (Tuple.stageIt) (scala.runtime.DynamicTuple.dynamicHead(x), scala.runtime.DynamicTuple.dynamicTail(x))
352+
else (x.head, x.tail)
480353
}

0 commit comments

Comments
 (0)