Skip to content

Commit 1526e65

Browse files
Merge pull request #6945 from dotty-staging/specialize-IArray-liftables
Specialize liftable for Arrays and IArrays
2 parents ca03fd8 + dc52c3d commit 1526e65

File tree

6 files changed

+184
-10
lines changed

6 files changed

+184
-10
lines changed

library/src-bootstrapped/scala/quoted/Liftable.scala

Lines changed: 59 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,26 +37,75 @@ object Liftable {
3737
}
3838
}
3939

40-
implicit def ClassIsLiftable[T]: Liftable[Class[T]] = new Liftable[Class[T]] {
40+
given ClassIsLiftable[T] as Liftable[Class[T]] = new Liftable[Class[T]] {
4141
/** Lift a `Class[T]` into `'{ classOf[T] }` */
4242
def toExpr(x: Class[T]) = given qctx => {
4343
import qctx.tasty._
4444
Ref(definitions.Predef_classOf).appliedToType(Type(x)).seal.asInstanceOf[Expr[Class[T]]]
4545
}
4646
}
4747

48+
given ClassTagIsLiftable[T: Type] as Liftable[ClassTag[T]] = new Liftable[ClassTag[T]] {
49+
def toExpr(ct: ClassTag[T]): given QuoteContext => Expr[ClassTag[T]] =
50+
'{ ClassTag[T](${ct.runtimeClass.toExpr}) }
51+
}
52+
4853
given ArrayIsLiftable[T: Type: Liftable: ClassTag] as Liftable[Array[T]] = new Liftable[Array[T]] {
49-
def toExpr(arr: Array[T]): given QuoteContext => Expr[Array[T]] = '{
50-
val array = new Array[T](${arr.length.toExpr})(ClassTag(${the[ClassTag[T]].runtimeClass.toExpr}))
51-
${ Expr.block(List.tabulate(arr.length)(i => '{ array(${i.toExpr}) = ${arr(i).toExpr} }), '{ array }) }
52-
}
54+
def toExpr(arr: Array[T]): given QuoteContext => Expr[Array[T]] =
55+
'{ Array[T](${arr.toSeq.toExpr}: _*)(${the[ClassTag[T]].toExpr}) }
5356
}
5457

55-
given IArrayIsLiftable[T: Type: Liftable: ClassTag] as Liftable[IArray[T]] = new Liftable[IArray[T]] {
56-
def toExpr(iarray: IArray[T]): given QuoteContext => Expr[IArray[T]] = '{
57-
val array = new Array[T](${iarray.length.toExpr})(ClassTag(${the[ClassTag[T]].runtimeClass.toExpr}))
58-
${ Expr.block(List.tabulate(iarray.length)(i => '{ array(${i.toExpr}) = ${iarray(i).toExpr} }), '{ array.asInstanceOf[IArray[T]] }) }
59-
}
58+
given ArrayOfBooleanIsLiftable as Liftable[Array[Boolean]] = new Liftable[Array[Boolean]] {
59+
def toExpr(array: Array[Boolean]): given QuoteContext => Expr[Array[Boolean]] =
60+
if (array.length == 0) '{ Array.emptyBooleanArray }
61+
else '{ Array(${array(0).toExpr}, ${array.toSeq.tail.toExpr}: _*) }
62+
}
63+
64+
given ArrayOfByteIsLiftable as Liftable[Array[Byte]] = new Liftable[Array[Byte]] {
65+
def toExpr(array: Array[Byte]): given QuoteContext => Expr[Array[Byte]] =
66+
if (array.length == 0) '{ Array.emptyByteArray }
67+
else '{ Array(${array(0).toExpr}, ${array.toSeq.tail.toExpr}: _*) }
68+
}
69+
70+
given ArrayOfShortIsLiftable as Liftable[Array[Short]] = new Liftable[Array[Short]] {
71+
def toExpr(array: Array[Short]): given QuoteContext => Expr[Array[Short]] =
72+
if (array.length == 0) '{ Array.emptyShortArray }
73+
else '{ Array(${array(0).toExpr}, ${array.toSeq.tail.toExpr}: _*) }
74+
}
75+
76+
given ArrayOfCharIsLiftable as Liftable[Array[Char]] = new Liftable[Array[Char]] {
77+
def toExpr(array: Array[Char]): given QuoteContext => Expr[Array[Char]] =
78+
if (array.length == 0) '{ Array.emptyCharArray }
79+
else '{ Array(${array(0).toExpr}, ${array.toSeq.tail.toExpr}: _*) }
80+
}
81+
82+
given ArrayOfIntIsLiftable as Liftable[Array[Int]] = new Liftable[Array[Int]] {
83+
def toExpr(array: Array[Int]): given QuoteContext => Expr[Array[Int]] =
84+
if (array.length == 0) '{ Array.emptyIntArray }
85+
else '{ Array(${array(0).toExpr}, ${array.toSeq.tail.toExpr}: _*) }
86+
}
87+
88+
given ArrayOfLongIsLiftable as Liftable[Array[Long]] = new Liftable[Array[Long]] {
89+
def toExpr(array: Array[Long]): given QuoteContext => Expr[Array[Long]] =
90+
if (array.length == 0) '{ Array.emptyLongArray }
91+
else '{ Array(${array(0).toExpr}, ${array.toSeq.tail.toExpr}: _*) }
92+
}
93+
94+
given ArrayOfFloatIsLiftable as Liftable[Array[Float]] = new Liftable[Array[Float]] {
95+
def toExpr(array: Array[Float]): given QuoteContext => Expr[Array[Float]] =
96+
if (array.length == 0) '{ Array.emptyFloatArray }
97+
else '{ Array(${array(0).toExpr}, ${array.toSeq.tail.toExpr}: _*) }
98+
}
99+
100+
given ArrayOfDoubleIsLiftable as Liftable[Array[Double]] = new Liftable[Array[Double]] {
101+
def toExpr(array: Array[Double]): given QuoteContext => Expr[Array[Double]] =
102+
if (array.length == 0) '{ Array.emptyDoubleArray }
103+
else '{ Array(${array(0).toExpr}, ${array.toSeq.tail.toExpr}: _*) }
104+
}
105+
106+
given IArrayIsLiftable[T: Type] as Liftable[IArray[T]] given (ltArray: Liftable[Array[T]]) = new Liftable[IArray[T]] {
107+
def toExpr(iarray: IArray[T]): given QuoteContext => Expr[IArray[T]] =
108+
'{ ${ltArray.toExpr(iarray.asInstanceOf[Array[T]])}.asInstanceOf[IArray[T]] }
60109
}
61110

62111
given [T: Type: Liftable] as Liftable[Seq[T]] = new Liftable[Seq[T]] {

tests/run-with-compiler/quote-lib.scala

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,32 @@ object Test {
6868
val iarray: IArray[Int] = IArray(1, 2, 3)
6969
val liftedIArray: Expr[IArray[Int]] = iarray
7070

71+
val iarray2: IArray[String] = IArray("a", "b", "c")
72+
iarray2.toExpr
73+
74+
IArray(false).toExpr
75+
IArray(1: Byte).toExpr
76+
IArray(1: Short).toExpr
77+
IArray(1).toExpr
78+
IArray(1L).toExpr
79+
IArray(1.1f).toExpr
80+
IArray(1.1d).toExpr
81+
IArray('a').toExpr
82+
IArray((1, 3)).toExpr
83+
7184
val array: Array[Int] = Array(1, 2, 3)
7285
val liftedArray: Expr[Array[Int]] = array
7386

87+
Array(false).toExpr
88+
Array(1: Byte).toExpr
89+
Array(1: Short).toExpr
90+
Array(1).toExpr
91+
Array(1L).toExpr
92+
Array(1.1f).toExpr
93+
Array(1.1d).toExpr
94+
Array('a').toExpr
95+
Array((1, 3)).toExpr
96+
7497
val some: Option[Int] = Some(2)
7598
val none: Option[Int] = Some(2)
7699
val liftedSome: Expr[Option[Int]] = some
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
[]
2+
[]
3+
[]
4+
[]
5+
[]
6+
[]
7+
[]
8+
[]
9+
[]
10+
11+
[true]
12+
[1, 2]
13+
[2, 3]
14+
[a, b]
15+
[4, 5]
16+
[6, 7]
17+
[2.1, 3.2]
18+
[2.2, 3.3]
19+
[abc, xyz]
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import scala.quoted._
2+
import scala.quoted.autolift._
3+
4+
object Test {
5+
implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader)
6+
def main(args: Array[String]): Unit = run {
7+
'{
8+
def p[T](arr: Array[T]): Unit = {
9+
println(arr.asInstanceOf[Array[_]].mkString("[", ", ", "]"))
10+
}
11+
p(${Array.empty[Boolean]})
12+
p(${Array.empty[Byte]})
13+
p(${Array.empty[Short]})
14+
p(${Array.empty[Char]})
15+
p(${Array.empty[Int]})
16+
p(${Array.empty[Long]})
17+
p(${Array.empty[Float]})
18+
p(${Array.empty[Double]})
19+
p(${Array.empty[String]})
20+
println()
21+
p(${Array(true)})
22+
p(${Array[Byte](1, 2)})
23+
p(${Array[Short](2, 3)})
24+
p(${Array[Char]('a', 'b')})
25+
p(${Array[Int](4, 5)})
26+
p(${Array[Long](6L, 7L)})
27+
p(${Array[Float](2.1f, 3.2f)})
28+
p(${Array[Double](2.2, 3.3)})
29+
p(${Array("abc", "xyz")})
30+
}
31+
}
32+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
[]
2+
[]
3+
[]
4+
[]
5+
[]
6+
[]
7+
[]
8+
[]
9+
[]
10+
11+
[true]
12+
[1, 2]
13+
[2, 3]
14+
[a, b]
15+
[4, 5]
16+
[6, 7]
17+
[2.1, 3.2]
18+
[2.2, 3.3]
19+
[abc, xyz]
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import scala.quoted._
2+
import scala.quoted.autolift._
3+
4+
object Test {
5+
implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader)
6+
def main(args: Array[String]): Unit = run {
7+
'{
8+
def p[T](arr: IArray[T]): Unit = {
9+
println(arr.asInstanceOf[Array[_]].mkString("[", ", ", "]"))
10+
}
11+
p(${IArray.empty[Boolean]})
12+
p(${IArray.empty[Byte]})
13+
p(${IArray.empty[Short]})
14+
p(${IArray.empty[Char]})
15+
p(${IArray.empty[Int]})
16+
p(${IArray.empty[Long]})
17+
p(${IArray.empty[Float]})
18+
p(${IArray.empty[Double]})
19+
p(${IArray.empty[String]})
20+
println()
21+
p(${IArray(true)})
22+
p(${IArray[Byte](1, 2)})
23+
p(${IArray[Short](2, 3)})
24+
p(${IArray[Char]('a', 'b')})
25+
p(${IArray[Int](4, 5)})
26+
p(${IArray[Long](6L, 7L)})
27+
p(${IArray[Float](2.1f, 3.2f)})
28+
p(${IArray[Double](2.2, 3.3)})
29+
p(${IArray("abc", "xyz")})
30+
}
31+
}
32+
}

0 commit comments

Comments
 (0)