Skip to content

Commit e9e4702

Browse files
committed
Fix #3912: account for units and blocks in inline and macros
1 parent b24f80d commit e9e4702

File tree

8 files changed

+67
-3
lines changed

8 files changed

+67
-3
lines changed

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

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,16 +321,21 @@ class ReifyQuotes extends MacroTransformWithImplicits {
321321
val last = enteredSyms
322322
stats.foreach(markDef)
323323
mapOverTree(last)
324-
case Inlined(call, bindings, expansion @ Select(body, name)) if expansion.symbol.isSplice =>
324+
325+
case Inlined(call, bindings, InlineSplice(expansion @ Select(body, name))) =>
325326
// To maintain phase consistency, we move the binding of the this parameter into the spliced code
326327
val (splicedBindings, stagedBindings) = bindings.partition {
327328
case vdef: ValDef => vdef.symbol.is(Synthetic) // Assume that only _this bindings are tagged with Synthetic
328329
case _ => false
329330
}
331+
330332
val tree1 =
331333
if (level == 0) cpy.Inlined(tree)(call, stagedBindings, Splicer.splice(seq(splicedBindings, body)))
332334
else seq(stagedBindings, cpy.Select(expansion)(cpy.Inlined(tree)(call, splicedBindings, body), name))
333335
transform(tree1)
336+
337+
if (tree.tpe =:= defn.UnitType) Block(tree1 :: Nil, Literal(Constant(())))
338+
else tree1
334339
case _: Import =>
335340
tree
336341
case tree: DefDef if tree.symbol.is(Macro) && level == 0 =>
@@ -343,5 +348,20 @@ class ReifyQuotes extends MacroTransformWithImplicits {
343348
checkLevel(mapOverTree(enteredSyms))
344349
}
345350
}
351+
352+
/** InlineSplice is used to detect cases where the expansion
353+
* consists of a (possibly multiple & nested) block or a sole expression.
354+
*/
355+
object InlineSplice {
356+
def unapply(tree: Tree)(implicit ctx: Context): Option[Select] = {
357+
tree match {
358+
case expansion: Select if expansion.symbol.isSplice =>
359+
Some(expansion)
360+
case Block(List(stat), Literal(Constant(()))) => unapply(stat)
361+
case Block(Nil, expr) => unapply(expr)
362+
case _ => None
363+
}
364+
}
365+
}
346366
}
347367
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ import dotty.tools.dotc.core.Contexts._
66
import dotty.tools.dotc.core.quoted._
77
import dotty.tools.dotc.interpreter._
88

9-
/** Utility class to slice quoted expressions */
9+
/** Utility class to splice quoted expressions */
1010
object Splicer {
1111
import tpd._
1212

1313
/** Splice the Tree for a Quoted expression. `~'(xyz)` becomes `xyz`
1414
* and for `~xyz` the tree of `xyz` is interpreted for which the
15-
* resulting expression is return as a `Tree`
15+
* resulting expression is returned as a `Tree`
1616
*/
1717
def splice(tree: Tree)(implicit ctx: Context): Tree = tree match {
1818
case Quoted(quotedTree) => quotedTree

tests/pos/i3912-1/i3912_1.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import scala.quoted._
2+
3+
object Macros {
4+
inline def foo(): Int = { ~impl() }
5+
6+
def impl(): Expr[Int] = '(1)
7+
}

tests/pos/i3912-1/i3912_2.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import scala.quoted._
2+
import Macros._
3+
4+
class Test {
5+
val a: Unit = foo()
6+
7+
}

tests/pos/i3912-2/i3912_1.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import scala.quoted._
2+
3+
object Macros {
4+
inline def foo2(): Unit = ~impl()
5+
6+
def impl(): Expr[Int] = '(1)
7+
}

tests/pos/i3912-2/i3912_2.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import scala.quoted._
2+
import Macros._
3+
4+
class Test {
5+
val a2: Unit = foo2()
6+
}

tests/pos/i3912-3/i3912_1.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import scala.quoted._
2+
3+
object Macros {
4+
inline def foo3(): Int = {
5+
{
6+
~impl()
7+
}
8+
}
9+
10+
def impl(): Expr[Int] = '(1)
11+
}

tests/pos/i3912-3/i3912_2.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import scala.quoted._
2+
import Macros._
3+
4+
class Test {
5+
val a3: Unit = foo3()
6+
}

0 commit comments

Comments
 (0)