Skip to content

Commit 047309f

Browse files
committed
Fix inline function types as macros args
* Show that there is no semantic difference between inline functions and by name functions
1 parent 4e5cf82 commit 047309f

File tree

4 files changed

+88
-1
lines changed

4 files changed

+88
-1
lines changed

compiler/src/dotty/tools/dotc/transform/Splicer.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ object Splicer {
6565
val args1 = args.head.zip(tp.paramInfos).map {
6666
case (arg: Literal, tp) if tp.hasAnnotation(defn.InlineParamAnnot) => arg.const.value
6767
case (arg, tp) =>
68-
assert(!tp.hasAnnotation(defn.InlineParamAnnot))
68+
assert(!tp.hasAnnotation(defn.InlineParamAnnot) || defn.isFunctionType(tp))
6969
// Replace argument by its binding
7070
val arg1 = bindMap.getOrElse(arg, arg)
7171
new scala.quoted.Exprs.TastyTreeExpr(arg1)

tests/run/quote-inline-function.check

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
Normal function
2+
{
3+
var i: Int = 0
4+
val j: Int = 5
5+
<label> def while$(): Unit =
6+
if i.<(j) then
7+
{
8+
val x$1: Int = i
9+
f.apply(x$1)
10+
i = i.+(1)
11+
while$()
12+
}
13+
else ()
14+
while$()
15+
}
16+
17+
By name function
18+
{
19+
var i: Int = 0
20+
val j: Int = 5
21+
<label> def while$(): Unit =
22+
if i.<(j) then
23+
{
24+
val x$1: Int = i
25+
scala.Predef.println(x$1)
26+
i = i.+(1)
27+
while$()
28+
}
29+
else ()
30+
while$()
31+
}
32+
33+
inline function
34+
{
35+
var i: Int = 0
36+
val j: Int = 5
37+
<label> def while$(): Unit =
38+
if i.<(j) then
39+
{
40+
val x$1: Int = i
41+
scala.Predef.println(x$1)
42+
i = i.+(1)
43+
while$()
44+
}
45+
else ()
46+
while$()
47+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import scala.quoted._
2+
3+
import dotty.tools.dotc.quoted.Toolbox._
4+
5+
object Macros {
6+
7+
inline def foreach1(start: Int, end: Int, f: Int => Unit): String = ~impl('(start), '(end), '(f))
8+
inline def foreach2(start: Int, end: Int, f: => Int => Unit): String = ~impl('(start), '(end), '(f))
9+
inline def foreach3(start: Int, end: Int, inline f: Int => Unit): String = ~impl('(start), '(end), '(f))
10+
11+
def impl(start: Expr[Int], end: Expr[Int], f: Expr[Int => Unit]): Expr[String] = {
12+
val res = '{
13+
var i = ~start
14+
val j = ~end
15+
while (i < j) {
16+
~f.apply('(i))
17+
i += 1
18+
}
19+
}
20+
res.show.toExpr
21+
}
22+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import scala.quoted._
2+
import Macros._
3+
4+
object Test {
5+
def main(args: Array[String]): Unit = {
6+
println("Normal function")
7+
println(foreach1(0, 5, x => println(x)))
8+
println()
9+
10+
println("By name function")
11+
println(foreach2(0, 5, x => println(x)))
12+
println()
13+
14+
println("inline function")
15+
println(foreach3(0, 5, x => println(x)))
16+
17+
}
18+
}

0 commit comments

Comments
 (0)