Closed
Description
Files (compiled one after the other)
import scala.annotation.tailrec
import scala.quoted._
object Macros {
inline def unrolledForeach(seq: IndexedSeq[Int], f: => Int => Unit, inline unrollSize: Int): Unit = // or f: Int => Unit
~unrolledForeachImpl('(seq), '(f), unrollSize)
def unrolledForeachImpl(seq: Expr[IndexedSeq[Int]], f: Expr[Int => Unit], unrollSize: Int): Expr[Unit] = '{
val size = (~seq).length
assert(size % (~unrollSize.toExpr) == 0) // for simplicity of the implementation
var i = 0
while (i < size) {
~{
for (j <- new UnrolledRange(0, unrollSize)) '{
val index = i + ~j.toExpr
val element = (~seq)(index)
~f('(element)) // or `(~f)(element)` if `f` should not be inlined
}
}
i += ~unrollSize.toExpr
}
}
class UnrolledRange(start: Int, end: Int) {
def foreach(f: Int => Expr[Unit]): Expr[Unit] = {
@tailrec def loop(i: Int, acc: Expr[Unit]): Expr[Unit] =
if (i >= 0) loop(i - 1, '{ ~f(i); ~acc })
else acc
loop(end - 1, '())
}
}
}
import scala.quoted._
import Macros._
object Test {
def main(args: Array[String]): Unit = {
val seq = IndexedSeq.tabulate[Int](21)(x => x)
unrolledForeach(seq, (x: Int) => println(2*x), 3)
}
}
fail with on Ycheck
with
exception while typing val index: Int = i.+(0) of class class dotty.tools.dotc.ast.Trees$ValDef # 4370
exception while typing {
val index: Int = i.+(0)
val element: Int = seq.apply(index)
{
val x$1: Int = element
println(2.*(x$1))
}
} of class class dotty.tools.dotc.ast.Trees$Block # 4380
...