Skip to content

Commit 01c5eac

Browse files
Merge pull request #4885 from dotty-staging/fix-#4734
Fix #4734: Pickle positions for quotes
2 parents 09a968a + aed0b29 commit 01c5eac

File tree

6 files changed

+89
-3
lines changed

6 files changed

+89
-3
lines changed

compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@ import dotty.tools.dotc.core.Contexts._
88
import dotty.tools.dotc.core.Decorators._
99
import dotty.tools.dotc.core.StdNames._
1010
import dotty.tools.dotc.core.NameKinds
11+
import dotty.tools.dotc.core.Mode
1112
import dotty.tools.dotc.core.Symbols._
1213
import dotty.tools.dotc.core.Types.Type
1314
import dotty.tools.dotc.core.tasty.TreePickler.Hole
14-
import dotty.tools.dotc.core.tasty.{TastyPickler, TastyPrinter, TastyString}
15+
import dotty.tools.dotc.core.tasty.{PositionPickler, TastyPickler, TastyPrinter, TastyString}
1516
import dotty.tools.dotc.core.tasty.TreeUnpickler.UnpickleMode
1617

1718
import scala.quoted.Types._
@@ -66,13 +67,13 @@ object PickledQuotes {
6667
/** Unpickle the tree contained in the TastyExpr */
6768
private def unpickleExpr(expr: TastyExpr[_])(implicit ctx: Context): Tree = {
6869
val tastyBytes = TastyString.unpickle(expr.tasty)
69-
unpickle(tastyBytes, expr.args, isType = false)
70+
unpickle(tastyBytes, expr.args, isType = false)(ctx.addMode(Mode.ReadPositions))
7071
}
7172

7273
/** Unpickle the tree contained in the TastyType */
7374
private def unpickleType(ttpe: TastyType[_])(implicit ctx: Context): Tree = {
7475
val tastyBytes = TastyString.unpickle(ttpe.tasty)
75-
unpickle(tastyBytes, ttpe.args, isType = true)
76+
unpickle(tastyBytes, ttpe.args, isType = true)(ctx.addMode(Mode.ReadPositions))
7677
}
7778

7879
// TASTY picklingtests/pos/quoteTest.scala
@@ -85,6 +86,8 @@ object PickledQuotes {
8586
treePkl.compactify()
8687
pickler.addrOfTree = treePkl.buf.addrOfTree
8788
pickler.addrOfSym = treePkl.addrOfSym
89+
if (tree.pos.exists)
90+
new PositionPickler(pickler, treePkl.buf.addrOfTree).picklePositions(tree :: Nil)
8891

8992
if (pickling ne noPrinter)
9093
println(i"**** pickling quote of \n${tree.show}")

tests/pos/i4734/Macro_1.scala

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import scala.annotation.tailrec
2+
import scala.quoted._
3+
4+
object Macros {
5+
transparent def unrolledForeach(f: Int => Int): Int =
6+
~unrolledForeachImpl('(f))
7+
8+
def unrolledForeachImpl(f: Expr[Int => Int]): Expr[Int] = '{
9+
val size: Int = 5
10+
(~f)(3)
11+
}
12+
}

tests/pos/i4734/Test_2.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import scala.quoted._
2+
import Macros._
3+
4+
object Test {
5+
def main(args: Array[String]): Unit = {
6+
unrolledForeach((x: Int) => 2)
7+
}
8+
}

tests/run/i4734.check

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
0
2+
2
3+
4
4+
6
5+
8
6+
10
7+
12
8+
14
9+
16
10+
18
11+
20
12+
22
13+
24
14+
26
15+
28
16+
30
17+
32
18+
34
19+
36
20+
38
21+
40

tests/run/i4734/Macro_1.scala

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import scala.annotation.tailrec
2+
import scala.quoted._
3+
4+
object Macros {
5+
transparent def unrolledForeach(seq: IndexedSeq[Int], f: => Int => Unit, transparent unrollSize: Int): Unit = // or f: Int => Unit
6+
~unrolledForeachImpl('(seq), '(f), unrollSize)
7+
8+
def unrolledForeachImpl(seq: Expr[IndexedSeq[Int]], f: Expr[Int => Unit], unrollSize: Int): Expr[Unit] = '{
9+
val size = (~seq).length
10+
assert(size % (~unrollSize.toExpr) == 0) // for simplicity of the implementation
11+
var i = 0
12+
while (i < size) {
13+
~{
14+
for (j <- new UnrolledRange(0, unrollSize)) '{
15+
val index = i + ~j.toExpr
16+
val element = (~seq)(index)
17+
~f('(element)) // or `(~f)(element)` if `f` should not be inlined
18+
}
19+
}
20+
i += ~unrollSize.toExpr
21+
}
22+
23+
}
24+
25+
class UnrolledRange(start: Int, end: Int) {
26+
def foreach(f: Int => Expr[Unit]): Expr[Unit] = {
27+
@tailrec def loop(i: Int, acc: Expr[Unit]): Expr[Unit] =
28+
if (i >= 0) loop(i - 1, '{ ~f(i); ~acc })
29+
else acc
30+
loop(end - 1, '())
31+
}
32+
}
33+
}

tests/run/i4734/Test_2.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import scala.quoted._
2+
import Macros._
3+
4+
object Test {
5+
def main(args: Array[String]): Unit = {
6+
val seq = IndexedSeq.tabulate[Int](21)(x => x)
7+
unrolledForeach(seq, (x: Int) => println(2*x), 3)
8+
}
9+
}

0 commit comments

Comments
 (0)