Closed
Description
import scala.annotation.tailrec
import scala.quoted._
object Macro {
inline def unrolledForeach(inline unrollSize: Int, seq: Array[Int], f: => Int => Unit): Unit = // or f: Int => Unit
~unrolledForeachImpl(unrollSize, '(seq), '(f))
private def unrolledForeachImpl(unrollSize: Int, seq: Expr[Array[Int]], f: Expr[Int => Unit]): Expr[Unit] = '{
val size = (~seq).length
assert(size % (~unrollSize.toExpr) == 0) // for simplicity of the implementation
var i = 0
while (i < size) {
println("<log> start loop")
~{
for (j <- new UnrolledRange(0, unrollSize)) '{
val element = (~seq)(i + ~j.toExpr)
~f('(element)) // or `(~f)(element)` if `f` should not be inlined
}
}
i += ~unrollSize.toExpr
}
}
private 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._
object Test {
def main(args: Array[String]): Unit = {
val arr = Array.tabulate[Int](21)(x => x)
for (x <- new Unrolled(arr)) {
System.out.println(2*x)
}
}
}
class Unrolled(arr: Array[Int]) extends AnyVal {
inline def foreach(f: => Int => Unit): Unit = Macro.unrolledForeach(3, arr, f)
}
Fails Ycheck with
exception while typing inline def foreach(f: => Function1[Int, Unit]): Unit = Macro.unrolledForeach(3, this.inline$arr, f) of class class dotty.tools.dotc.ast.Trees$DefDef # 4391
exception while typing @scala.annotation.internal.SourceFile(
"/Users/nicolasstucki/GitHub/dotty/tests/run/quote-unrolled-foreach/quoted_2.scala"
) final class Unrolled(arr: Array[Int]) extends AnyVal() {
private[this] val arr: Array[Int]
inline def foreach(f: => Function1[Int, Unit]): Unit = Macro.unrolledForeach(3, this.inline$arr, f)
def inline$arr: Array[Int] = Unrolled.this.arr
override def hashCode(): Int = Unrolled.this.arr.hashCode()
override def equals(x$0: Any): Boolean =
x$0 match
{
case x$0 @ _: Unrolled @unchecked => this.arr.==(x$0.arr)
case _ => false
}
} of class class dotty.tools.dotc.ast.Trees$TypeDef # 4520
exception while typing package <empty> {
import scala.quoted._
final lazy module val Test: Test = new Test()
@scala.annotation.internal.SourceFile(
"/Users/nicolasstucki/GitHub/dotty/tests/run/quote-unrolled-foreach/quoted_2.scala"
) final module class Test() extends Object() { this: Test.type =>
def main(args: Array[String]): Unit =
{
val arr: Array[Int] =
Array.tabulate[Int](21)(
{
def $anonfun(x: Int): Int = x
closure($anonfun)
}
)(scala.reflect.ClassTag.apply[Int](Integer.TYPE))
/* inlined from Unrolled*/
{
val Unrolled_this: Unrolled = new Unrolled(arr)
/* inlined from Macro*/
{
val seq: Array[Int] = Unrolled_this.inline$arr
{
val size: Int = seq.length
assert(size.%(3).==(0))
var i: Int = 0
{
<label> def while$(): Unit =
if i.<(size) then
{
{
println("<log> start loop")
{
{
val element: Int = seq.apply(i.+(0))
{
val x$1: Int = element
{
System.out.println(2.*(x$1))
}
}
}
{
{
val element: Int = seq.apply(i.+(1))
{
val x$2: Int = element
{
System.out.println(2.*(x$2))
}
}
}
{
{
val element: Int = seq.apply(i.+(2))
{
val x$3: Int = element
{
System.out.println(2.*(x$3))
}
}
}
()
}
}
}
i = i.+(3)
}
while$()
}
else ()
while$()
}
}
}
}
}
}
@scala.annotation.internal.SourceFile(
"/Users/nicolasstucki/GitHub/dotty/tests/run/quote-unrolled-foreach/quoted_2.scala"
) final class Unrolled(arr: Array[Int]) extends AnyVal() {
private[this] val arr: Array[Int]
inline def foreach(f: => Function1[Int, Unit]): Unit = Macro.unrolledForeach(3, this.inline$arr, f)
def inline$arr: Array[Int] = Unrolled.this.arr
override def hashCode(): Int = Unrolled.this.arr.hashCode()
override def equals(x$0: Any): Boolean =
x$0 match
{
case x$0 @ _: Unrolled @unchecked => this.arr.==(x$0.arr)
case _ => false
}
}
final lazy module val Unrolled: Unrolled = new Unrolled()
@scala.annotation.internal.SourceFile(
"/Users/nicolasstucki/GitHub/dotty/tests/run/quote-unrolled-foreach/quoted_2.scala"
) final module class Unrolled() extends Object() { this: Unrolled.type =>}
} of class class dotty.tools.dotc.ast.Trees$PackageDef # 4733
*** error while checking /Users/nicolasstucki/GitHub/dotty/tests/run/quote-unrolled-foreach/quoted_2.scala after phase reifyQuotes ***