Skip to content

Inlined quoted valdef failing to typecheck #4734

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
nicolasstucki opened this issue Jun 28, 2018 · 1 comment
Closed

Inlined quoted valdef failing to typecheck #4734

nicolasstucki opened this issue Jun 28, 2018 · 1 comment

Comments

@nicolasstucki
Copy link
Contributor

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
...
@nicolasstucki
Copy link
Contributor Author

Can be minimized to:

import scala.annotation.tailrec
import scala.quoted._

object Macros {
  transparent def unrolledForeach(f: Int => Int): Int =
    ~unrolledForeachImpl('(f))

  def unrolledForeachImpl(f: Expr[Int => Int]): Expr[Int] = '{
    val size: Int = 5
    (~f)(3)
  }
}
import scala.quoted._
import Macros._

object Test {
  def main(args: Array[String]): Unit = {
    unrolledForeach((x: Int) => 2)
  }
}

It fails -Ycheck because the position is not set for Literal(Constant(5)).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant