Skip to content

Commit 19181ce

Browse files
committed
Fix parser and add more tests
Undoes: - Drop InlineIf and InlineMatch (reverted from commit 8ae9d6a)
1 parent f5944a7 commit 19181ce

File tree

12 files changed

+257
-37
lines changed

12 files changed

+257
-37
lines changed

compiler/src/dotty/tools/dotc/parsing/Parsers.scala

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1212,8 +1212,11 @@ object Parsers {
12121212
if (isIdent(nme.INLINEkw)) {
12131213
val start = in.skipToken()
12141214
val t = postfixExpr()
1215-
accept(MATCH)
1216-
matchExpr(t, start, MatchKind.Inline)
1215+
if (in.token == MATCH) matchExpr(t, start, MatchKind.Inline)
1216+
else {
1217+
syntaxErrorOrIncomplete(i"`match` expected but ${in.token} found")
1218+
t
1219+
}
12171220
}
12181221
else expr1Rest(postfixExpr(), location)
12191222
}

library/src-scala3/scala/Tuple.scala

Lines changed: 233 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,29 +4,118 @@ import typelevel._
44

55
sealed trait Tuple extends Any {
66
import Tuple._
7-
import StagedTuple._
87

98
inline def toArray: Array[Object] =
10-
~toArrayStaged('(this), constValueOpt[BoundedSize[this.type]])
9+
if (specialize)
10+
inline constValueOpt[BoundedSize[this.type]] match {
11+
case Some(0) =>
12+
$emptyArray
13+
case Some(1) =>
14+
val t = asInstanceOf[Tuple1[Object]]
15+
Array(t._1)
16+
case Some(2) =>
17+
val t = asInstanceOf[Tuple2[Object, Object]]
18+
Array(t._1, t._2)
19+
case Some(3) =>
20+
val t = asInstanceOf[Tuple3[Object, Object, Object]]
21+
Array(t._1, t._2, t._3)
22+
case Some(4) =>
23+
val t = asInstanceOf[Tuple4[Object, Object, Object, Object]]
24+
Array(t._1, t._2, t._3, t._4)
25+
case Some(n) if n <= $MaxSpecialized =>
26+
$toArray(this, n)
27+
case Some(n) =>
28+
asInstanceOf[TupleXXL].elems
29+
case None =>
30+
dynamicToArray(this)
31+
}
32+
else dynamicToArray(this)
1133

1234
inline def *: [H] (x: H): H *: this.type =
13-
~stagedCons('(this), '(x), constValueOpt[BoundedSize[this.type]])
35+
if (specialize) {
36+
type Result = H *: this.type
37+
inline constValueOpt[BoundedSize[this.type]] match {
38+
case Some(0) =>
39+
Tuple1(x).asInstanceOf[Result]
40+
case Some(1) =>
41+
Tuple2(x, asInstanceOf[Tuple1[_]]._1).asInstanceOf[Result]
42+
case Some(2) =>
43+
val t = asInstanceOf[Tuple2[_, _]]
44+
Tuple3(x, t._1, t._2).asInstanceOf[Result]
45+
case Some(3) =>
46+
val t = asInstanceOf[Tuple3[_, _, _]]
47+
Tuple4(x, t._1, t._2, t._3).asInstanceOf[Result]
48+
case Some(4) =>
49+
val t = asInstanceOf[Tuple4[_, _, _, _]]
50+
Tuple5(x, t._1, t._2, t._3, t._4).asInstanceOf[Result]
51+
case Some(n) =>
52+
fromArray[Result]($consArray(x, toArray))
53+
case _ =>
54+
dynamic_*:[this.type, H](this, x)
55+
}
56+
}
57+
else dynamic_*:[this.type, H](this, x)
1458

1559
inline def ++(that: Tuple): Concat[this.type, that.type] =
16-
~stagedConcat('(this), constValueOpt[BoundedSize[this.type]], '(that), constValueOpt[BoundedSize[that.type]])
60+
if (specialize) {
61+
type Result = Concat[this.type, that.type]
62+
inline constValueOpt[BoundedSize[this.type]] match {
63+
case Some(0) =>
64+
that.asInstanceOf[Result]
65+
case Some(1) =>
66+
if (constValue[BoundedSize[that.type]] == 0) this.asInstanceOf[Result]
67+
else (asInstanceOf[Tuple1[_]]._1 *: that).asInstanceOf[Result]
68+
case Some(2) =>
69+
val t = asInstanceOf[Tuple2[_, _]]
70+
inline constValue[BoundedSize[that.type]] match {
71+
case 0 => this.asInstanceOf[Result]
72+
case 1 =>
73+
val u = that.asInstanceOf[Tuple1[_]]
74+
Tuple3(t._1, t._2, u._1).asInstanceOf[Result]
75+
case 2 =>
76+
val u = that.asInstanceOf[Tuple2[_, _]]
77+
Tuple4(t._1, t._2, u._1, u._2).asInstanceOf[Result]
78+
case _ =>
79+
genericConcat[Result](this, that).asInstanceOf[Result]
80+
}
81+
case Some(3) =>
82+
val t = asInstanceOf[Tuple3[_, _, _]]
83+
inline constValue[BoundedSize[that.type]] match {
84+
case 0 => this.asInstanceOf[Result]
85+
case 1 =>
86+
val u = that.asInstanceOf[Tuple1[_]]
87+
Tuple4(t._1, t._2, t._3, u._1).asInstanceOf[Result]
88+
case _ =>
89+
genericConcat[Result](this, that).asInstanceOf[Result]
90+
}
91+
case Some(_) =>
92+
if (constValue[BoundedSize[that.type]] == 0) this.asInstanceOf[Result]
93+
else genericConcat[Result](this, that).asInstanceOf[Result]
94+
case None =>
95+
dynamic_++[this.type, that.type](this, that)
96+
}
97+
}
98+
else dynamic_++[this.type, that.type](this, that)
1799

18-
inline def size: Size[this.type] =
19-
~sizeStaged[Size[this.type]]('(this), constValueOpt[BoundedSize[this.type]])
100+
inline def genericConcat[T <: Tuple](xs: Tuple, ys: Tuple): Tuple =
101+
fromArray[T](xs.toArray ++ ys.toArray)
20102

103+
inline def size: Size[this.type] =
104+
if (specialize) {
105+
type Result = Size[this.type]
106+
inline constValueOpt[BoundedSize[this.type]] match {
107+
case Some(n) => n.asInstanceOf[Result]
108+
case _ => dynamicSize(this)
109+
}
110+
}
111+
else dynamicSize(this)
21112
}
22113

23114
object Tuple {
24-
import StagedTuple._
25-
26115
inline val $MaxSpecialized = 22
27116
inline private val XXL = $MaxSpecialized + 1
28117

29-
final val specialize = true
118+
final val specialize = false
30119

31120
type Head[+X <: NonEmptyTuple] = X match {
32121
case x *: _ => x
@@ -86,7 +175,34 @@ object Tuple {
86175
}
87176

88177
inline def fromArray[T <: Tuple](xs: Array[Object]): T =
89-
~fromArrayStaged[T]('(xs), constValueOpt[BoundedSize[this.type]])
178+
if (specialize)
179+
inline constValue[BoundedSize[T]] match {
180+
case 0 => ().asInstanceOf[T]
181+
case 1 => Tuple1(xs(0)).asInstanceOf[T]
182+
case 2 => Tuple2(xs(0), xs(1)).asInstanceOf[T]
183+
case 3 => Tuple3(xs(0), xs(1), xs(2)).asInstanceOf[T]
184+
case 4 => Tuple4(xs(0), xs(1), xs(2), xs(3)).asInstanceOf[T]
185+
case 5 => Tuple5(xs(0), xs(1), xs(2), xs(3), xs(4)).asInstanceOf[T]
186+
case 6 => Tuple6(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5)).asInstanceOf[T]
187+
case 7 => Tuple7(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6)).asInstanceOf[T]
188+
case 8 => Tuple8(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6), xs(7)).asInstanceOf[T]
189+
case 9 => Tuple9(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6), xs(7), xs(8)).asInstanceOf[T]
190+
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]
191+
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]
192+
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]
193+
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]
194+
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]
195+
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]
196+
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]
197+
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]
198+
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]
199+
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]
200+
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]
201+
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]
202+
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]
203+
case _ => TupleXXL(xs).asInstanceOf[T]
204+
}
205+
else dynamicFromArray[T](xs)
90206

91207
def dynamicFromArray[T <: Tuple](xs: Array[Object]): T = xs.length match {
92208
case 0 => ().asInstanceOf[T]
@@ -179,17 +295,117 @@ object Tuple {
179295
abstract sealed class NonEmptyTuple extends Tuple {
180296
import Tuple._
181297
import NonEmptyTuple._
182-
import StagedTuple._
183298

184299
inline def head: Head[this.type] =
185-
~headStaged[this.type]('(this), constValueOpt[BoundedSize[this.type]])
300+
if (specialize) {
301+
type Result = Head[this.type]
302+
val resVal = inline constValueOpt[BoundedSize[this.type]] match {
303+
case Some(1) =>
304+
val t = asInstanceOf[Tuple1[_]]
305+
t._1
306+
case Some(2) =>
307+
val t = asInstanceOf[Tuple2[_, _]]
308+
t._1
309+
case Some(3) =>
310+
val t = asInstanceOf[Tuple3[_, _, _]]
311+
t._1
312+
case Some(4) =>
313+
val t = asInstanceOf[Tuple4[_, _, _, _]]
314+
t._1
315+
case Some(n) if n > 4 && n <= $MaxSpecialized =>
316+
asInstanceOf[Product].productElement(0)
317+
case Some(n) if n > $MaxSpecialized =>
318+
val t = asInstanceOf[TupleXXL]
319+
t.elems(0)
320+
case None =>
321+
dynamicHead[this.type](this)
322+
}
323+
resVal.asInstanceOf[Result]
324+
}
325+
else dynamicHead[this.type](this)
186326

187327
inline def tail: Tail[this.type] =
188-
~tailStaged[this.type]('(this), constValueOpt[BoundedSize[this.type]])
328+
if (specialize) {
329+
type Result = Tail[this.type]
330+
inline constValueOpt[BoundedSize[this.type]] match {
331+
case Some(1) =>
332+
().asInstanceOf[Result]
333+
case Some(2) =>
334+
val t = asInstanceOf[Tuple2[_, _]]
335+
Tuple1(t._2).asInstanceOf[Result]
336+
case Some(3) =>
337+
val t = asInstanceOf[Tuple3[_, _, _]]
338+
Tuple2(t._2, t._3).asInstanceOf[Result]
339+
case Some(4) =>
340+
val t = asInstanceOf[Tuple4[_, _, _, _]]
341+
Tuple3(t._2, t._3, t._4).asInstanceOf[Result]
342+
case Some(5) =>
343+
val t = asInstanceOf[Tuple5[_, _, _, _, _]]
344+
Tuple4(t._2, t._3, t._4, t._5).asInstanceOf[Result]
345+
case Some(n) if n > 5 =>
346+
fromArray[Result](toArray.tail)
347+
case None =>
348+
dynamicTail[this.type](this)
349+
}
350+
}
351+
else dynamicTail[this.type](this)
189352

190-
inline def apply(n: Int): Elem[this.type, n.type] =
191-
~applyStaged[this.type, n.type]('(this), constValueOpt[Size[this.type]], '(n), constValueOpt[n.type])
353+
inline def fallbackApply(n: Int) =
354+
inline constValueOpt[n.type] match {
355+
case Some(n: Int) => error("index out of bounds: ", n)
356+
case None => dynamicApply[this.type](this, n)
357+
}
192358

359+
inline def apply(n: Int): Elem[this.type, n.type] =
360+
if (specialize) {
361+
type Result = Elem[this.type, n.type]
362+
inline constValueOpt[Size[this.type]] match {
363+
case Some(1) =>
364+
val t = asInstanceOf[Tuple1[_]]
365+
inline constValueOpt[n.type] match {
366+
case Some(0) => t._1.asInstanceOf[Result]
367+
case _ => fallbackApply(n).asInstanceOf[Result]
368+
}
369+
case Some(2) =>
370+
val t = asInstanceOf[Tuple2[_, _]]
371+
inline constValueOpt[n.type] match {
372+
case Some(0) => t._1.asInstanceOf[Result]
373+
case Some(1) => t._2.asInstanceOf[Result]
374+
case _ => fallbackApply(n).asInstanceOf[Result]
375+
}
376+
case Some(3) =>
377+
val t = asInstanceOf[Tuple3[_, _, _]]
378+
inline constValueOpt[n.type] match {
379+
case Some(0) => t._1.asInstanceOf[Result]
380+
case Some(1) => t._2.asInstanceOf[Result]
381+
case Some(2) => t._3.asInstanceOf[Result]
382+
case _ => fallbackApply(n).asInstanceOf[Result]
383+
}
384+
case Some(4) =>
385+
val t = asInstanceOf[Tuple4[_, _, _, _]]
386+
inline constValueOpt[n.type] match {
387+
case Some(0) => t._1.asInstanceOf[Result]
388+
case Some(1) => t._2.asInstanceOf[Result]
389+
case Some(2) => t._3.asInstanceOf[Result]
390+
case Some(3) => t._4.asInstanceOf[Result]
391+
case _ => fallbackApply(n).asInstanceOf[Result]
392+
}
393+
case Some(s) if s > 4 && s <= $MaxSpecialized =>
394+
val t = asInstanceOf[Product]
395+
inline constValueOpt[n.type] match {
396+
case Some(n) if n >= 0 && n < s => t.productElement(n).asInstanceOf[Result]
397+
case _ => fallbackApply(n).asInstanceOf[Result]
398+
}
399+
case Some(s) if s > $MaxSpecialized =>
400+
val t = asInstanceOf[TupleXXL]
401+
inline constValueOpt[n.type] match {
402+
case Some(n) if n >= 0 && n < s => t.elems(n).asInstanceOf[Result]
403+
case _ => fallbackApply(n).asInstanceOf[Result]
404+
}
405+
case _ => fallbackApply(n).asInstanceOf[Result]
406+
}
407+
}
408+
else dynamicApply[this.type](this, n)
193409
}
194410

195411
object NonEmptyTuple {
@@ -234,6 +450,6 @@ object NonEmptyTuple {
234450
sealed class *:[+H, +T <: Tuple] extends NonEmptyTuple
235451

236452
object *: {
237-
def unapply[H, T <: Tuple](x: H *: T): (H, T) =
238-
(NonEmptyTuple.dynamicHead(x), NonEmptyTuple.dynamicTail(x))
453+
// TODO: make inline
454+
def unapply[H, T <: Tuple](x: H *: T) = (x.head, x.tail)
239455
}

tests/neg/inlinevals.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,3 @@ object Test {
3333
inline def byname(inline f: => String): Int = ??? // ok
3434

3535
}
36-
// error: `}` expected

tests/neg/nested-rewrites.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,14 @@ object Test {
1515
object Test0 {
1616

1717
def f(x: Int) = {
18-
inline def g(x: Int) = x match {
18+
inline def g(x: Int) = inline x match {
1919
case 0 => 0
2020
}
2121
g(0)
2222
inline val Y = 0
2323
g(Y)
2424

25-
inline def h(x: Int) = x match {
25+
inline def h(x: Int) = inline x match {
2626
case Y => 0
2727
}
2828
h(0)
@@ -35,14 +35,14 @@ object Test0 {
3535
object Test1 {
3636

3737
erased inline def f(x: Int) = {
38-
erased inline def g(x: Int) = x match { // error: implementation restriction: nested inline methods are not supported
38+
erased inline def g(x: Int) = inline x match { // error: implementation restriction: nested inline methods are not supported
3939
case 0 => 0
4040
}
4141
g(0)
4242
inline val Y = 0
4343
g(Y)
4444

45-
inline def h(x: Int) = x match { // error: implementation restriction: nested inline methods are not supported
45+
inline def h(x: Int) = inline x match { // error: implementation restriction: nested inline methods are not supported
4646
case Y => 0
4747
}
4848
h(0)

tests/neg/transparent-override/B_2.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
class B extends A {
2-
inline def f(x: Int): Int = x match { // error
2+
inline def f(x: Int): Int = inline x match { // error
33
case 0 => 1
44
case _ => x
55
}

tests/neg/typelevel-noeta.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22
object Test {
33
def anyValue[T]: T = ???
44

5-
inline def test(x: Int) = x match {
5+
inline def test(x: Int) = inline x match {
66
case _: Byte =>
77
case _: Char =>
88
}
99

10-
inline def test2() = 1 match {
10+
inline def test2() = inline 1 match {
1111
case _: Byte =>
1212
case _: Char =>
1313
}

tests/pos-deep-subtype/tuples23.check

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23)
2+
276

tests/pos-deep-subtype/tuples23.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,16 @@ object Test extends App {
1414
case (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22, x23) =>
1515
println(x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18 + x19 + x20 + x21 + x22 + x23)
1616
}
17-
inline def decompose3 = x23 match { case x *: y *: xs => (x, y, xs) }
17+
/* TODO: re-enable
18+
inline def decompose3 = inline x23 match { case x *: y *: xs => (x, y, xs) }
1819
1920
{ val (x, y, xs) = decompose3
2021
val xc: Int = x
2122
val yc: Int = y
2223
val xsc: Unit = xs
2324
println(s"$x23 -> $x, $y, $xs")
2425
}
26+
*/
2527

2628
val x23s: 23 = x23.size
2729
}

0 commit comments

Comments
 (0)