Skip to content

Commit 29d8988

Browse files
committed
Specialize tuples by inlining
- adapt tests
1 parent 36323a4 commit 29d8988

11 files changed

+148
-6
lines changed

compiler/test/dotc/pos-test-pickling.blacklist

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ i3976.scala
1111
i4125.scala
1212
implicit-dep.scala
1313
inline-access-levels
14+
inline-rewrite.scala
1415
macro-with-array
1516
macro-with-type
1617
matchtype.scala

library/src-scala3/scala/Tuple.scala

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ object Tuple {
115115
inline val $MaxSpecialized = 22
116116
inline private val XXL = $MaxSpecialized + 1
117117

118-
final val specialize = false
118+
final val specialize = true
119119

120120
type Head[+X <: NonEmptyTuple] = X match {
121121
case x *: _ => x
@@ -450,6 +450,5 @@ object NonEmptyTuple {
450450
sealed class *:[+H, +T <: Tuple] extends NonEmptyTuple
451451

452452
object *: {
453-
// TODO: make inline
454-
def unapply[H, T <: Tuple](x: H *: T) = (x.head, x.tail)
453+
inline def unapply[H, T <: Tuple](x: H *: T) = (x.head, x.tail)
455454
}

tests/invalid/run/typelevel1.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,10 @@ object Test extends App {
3030

3131
inline implicit def hlistDeco(xs: HList): HListDeco = new HListDeco(xs)
3232

33-
inline def concat[T1, T2](xs: HList, ys: HList): HList =
34-
if xs.isEmpty then ys
33+
// Does not work since it infers `Any` as a type argument for `::`
34+
// and we cannot undo that without a typing from untyped.
35+
inline def concat[T1, T2](xs: HList, ys: HList) <: HList =
36+
inline if xs.isEmpty then ys
3537
else new ::(xs.head, concat(xs.tail, ys))
3638

3739
val xs = 1 :: "a" :: "b" :: HNil

tests/neg/inline-unapply.scala

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
object Test {
2+
3+
class C(val x: Int, val y: Int)
4+
5+
inline def unapply(c: C): Option[(Int, Int)] = Some((c.x, c.y)) // ok
6+
7+
}
8+
object Test2 {
9+
10+
class C(x: Int, y: Int)
11+
12+
inline def unapply(c: C): Option[(Int, Int)] = inline c match { // error: inline match cannot be used in an inline unapply
13+
case x: C => (1, 1)
14+
}
15+
}
File renamed without changes.

tests/neg/inline-i1773.scala renamed to tests/pos/inline-i1773.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ object Test {
77
}
88

99
def main(args: Array[String]): Unit = {
10-
val q"class $name extends $parent" = new Object // error: method unapply is used
10+
val q"class $name extends $parent" = new Object // now ok, was an error that "method unapply is used"
1111
println(name)
1212
println(parent)
1313
}

tests/pos/inline-rewrite.scala

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
object Test {
2+
3+
inline def f(x: Int) = inline x match {
4+
case 1 => "a"
5+
case 2 => 22
6+
}
7+
8+
val x: String = f(1)
9+
val y = f(2)
10+
val yc: Int = y
11+
12+
inline def g(x: Any) = inline x match {
13+
case x: String => (x, x)
14+
case x: Double => x
15+
}
16+
17+
val a: (String, String) = g("")
18+
val b: Double = g(1.0)
19+
20+
}

tests/pos/typelevel0.scala

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
2+
trait HList {
3+
def length: Int = ???
4+
def head: Any
5+
def tail: HList
6+
7+
inline def isEmpty <: Boolean = length == 0
8+
}
9+
10+
case object HNil extends HList {
11+
inline override def length <: Int = 0
12+
def head: Nothing = ???
13+
def tail: Nothing = ???
14+
}
15+
16+
case class :: [+H, +T <: HList] (hd: H, tl: T) extends HList {
17+
inline override def length <: Int = 1 + tl.length
18+
def head: H = this.hd
19+
def tail: T = this.tl
20+
}
21+
22+
object Test extends App {
23+
type HNil = HNil.type
24+
val xs = new ::(1, new ::("a", HNil))
25+
inline val y = xs.length
26+
inline val ise = xs.isEmpty
27+
val hd = xs.head
28+
val tl = xs.tail
29+
val tl2 = xs.tail.tail
30+
31+
type Concat[+Xs <: HList, +Ys <: HList] <: HList = Xs match {
32+
case HNil => Ys
33+
case x1 :: xs1 => x1 :: Concat[xs1, Ys]
34+
}
35+
36+
def concat[Xs <: HList, Ys <: HList](xs: Xs, ys: Ys): Concat[Xs, Ys] = {
37+
if xs.isEmpty then ys
38+
else ::(xs.head, concat(xs.tail, ys))
39+
}.asInstanceOf
40+
41+
val xs0 = concat(HNil, xs)
42+
val xs1 = concat(xs, HNil)
43+
val xs2 = concat(xs, xs)
44+
val e2: Int = xs2.tail.tail.head
45+
}

tests/run/tuples1.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ object Test extends App {
44
val x2 = ("A", 1); println(x2)
55
val x3 = 2 *: x2; println(x3)
66
val x4 = "B" *: x3; println(x4)
7+
val y0 = x4(0)
8+
val y1 = x4(1)
79
val x5 = 3 *: x4; println(x5)
810
val x6 = "C" *: x5; println(x6)
911
val x7 = 4 *: x6; println(x7)

tests/run/typelevel-peano.check

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
0
2+
1
3+
2
4+
0
5+
1
6+
2
7+
1
8+
2
9+
3
10+
-1
11+
1

tests/run/typelevel-peano.scala

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
2+
import typelevel._
3+
4+
object Test extends App {
5+
6+
inline def toInt[N]: Int =
7+
inline constValue[N] match {
8+
case _: S[n1] => 1 + toInt[n1]
9+
case 0 => 0
10+
}
11+
12+
println(toInt[0])
13+
println(toInt[1])
14+
println(toInt[2])
15+
16+
locally {
17+
inline def toInt[N]: Int =
18+
inline constValueOpt[N] match {
19+
case Some(_: S[n1]) => 1 + toInt[n1]
20+
case Some(0) => 0
21+
case None => 0
22+
}
23+
println(toInt[0])
24+
println(toInt[1])
25+
println(toInt[2])
26+
}
27+
28+
val xs = List(1, 2, 3)
29+
30+
inline def select(n: Int) =
31+
inline constValueOpt[n.type] match {
32+
case Some(0) => xs(0)
33+
case Some(1) => xs(1)
34+
case Some(2) => xs(2)
35+
case Some(_) => -1
36+
}
37+
38+
println(select(0))
39+
println(select(1))
40+
println(select(2))
41+
println(select(3))
42+
final val idx = 0
43+
println(select(idx))
44+
}
45+
46+
47+

0 commit comments

Comments
 (0)