Skip to content

Inlined quoted valdef failing to typecheck #4734

Closed
@nicolasstucki

Description

@nicolasstucki

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
...

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions