Scala 3 Macros - quotes: how to match scala.Array(1,2,3))

given ArrayIntFromExpr: FromExpr[Array[Int]] with
  def unapply(x: Expr[Array[Int]])(using Quotes) = x match
    case '{ scala.Array($h: Int, (${Varargs[Int](Exprs[Int](elems))}: Seq[Int])*) } => Some(Array(h.valueOrAbort, elems *))
    case _ => None

As you showed in the tree, Array(1,2,3) is apply(Int, Int*).

The generic array needs the class tag, including for empty array.

given ArrayFromExpr[T](using Type[T], FromExpr[T])(using reflect.ClassTag[T]): FromExpr[Array[T]] with
  def unapply(x: Expr[Array[T]])(using Quotes) = x match
    case '{ scala.Array[T](${Varargs[T](Exprs[T](elems))}*)($ct) } => Some(Array(elems*))
    case _ => None

This is my first time learning the API, so thanks for the impetus.

def _arraysum(xs: Expr[Array[Int]])(using Quotes): Expr[Int] =
  xs match
  case Expr(vs) => Expr(vs.sum)
  case '{ $ys: Array[Int] } => '{ $ys.sum }

In this case, it could do elems.sum directly since the array is not of interest.

Tree at inlining showing both cases in a unit test; also showing that JUnit 4 does not have assertEquals(Int, Int).

[info]         org.junit.Assert.assertEquals(10L, Int.int2long(10:Int))
[info]         org.junit.Assert.assertEquals(10L,
[info]           Int.int2long(
[info]             wrapIntArray(Array.apply(1, [2,3,this.i : Int]*)).sum[Int](
[info]               scala.math.Numeric.IntIsIntegral):Int
[info]           )
[info]         )
1 Like