Skip to content

Commit 60d1fbd

Browse files
Merge pull request #6792 from dotty-staging/fix-macro-splice-checks
Perform full check that a the contents of a macro are valid in PrepareInlineable
2 parents 354e03c + e54c112 commit 60d1fbd

File tree

3 files changed

+16
-27
lines changed

3 files changed

+16
-27
lines changed

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

Lines changed: 8 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -54,30 +54,14 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages(
5454
* - If inside of a macro definition, check the validity of the macro.
5555
*/
5656
protected def transformSplice(body: Tree, splice: Tree)(implicit ctx: Context): Tree = {
57-
if (level >= 1) {
58-
val body1 = transform(body)(spliceContext)
59-
splice match {
60-
case Apply(fun: TypeApply, _) if splice.isTerm =>
61-
// Type of the splice itsel must also be healed
62-
// internal.Quoted.expr[F[T]](... T ...) --> internal.Quoted.expr[F[$t]](... T ...)
63-
val tp = checkType(splice.sourcePos).apply(splice.tpe.widenTermRefExpr)
64-
cpy.Apply(splice)(cpy.TypeApply(fun)(fun.fun, tpd.TypeTree(tp) :: Nil), body1 :: Nil)
65-
case splice: Select => cpy.Select(splice)(body1, splice.name)
66-
}
67-
}
68-
else {
69-
assert(enclosingInlineds.isEmpty, "unexpanded macro")
70-
assert(ctx.owner.isInlineMethod)
71-
if (Splicer.canBeSpliced(body)) { // level 0 inside an inline definition
72-
transform(body)(spliceContext) // Just check PCP
73-
splice
74-
}
75-
else { // level 0 inside an inline definition
76-
ctx.error(
77-
"Malformed macro call. The contents of the splice ${...} must call a static method and arguments must be quoted or inline.",
78-
splice.sourcePos)
79-
splice
80-
}
57+
val body1 = transform(body)(spliceContext)
58+
splice match {
59+
case Apply(fun: TypeApply, _) if splice.isTerm =>
60+
// Type of the splice itsel must also be healed
61+
// internal.Quoted.expr[F[T]](... T ...) --> internal.Quoted.expr[F[$t]](... T ...)
62+
val tp = checkType(splice.sourcePos).apply(splice.tpe.widenTermRefExpr)
63+
cpy.Apply(splice)(cpy.TypeApply(fun)(fun.fun, tpd.TypeTree(tp) :: Nil), body1 :: Nil)
64+
case splice: Select => cpy.Select(splice)(body1, splice.name)
8165
}
8266
}
8367

compiler/src/dotty/tools/dotc/typer/PrepareInlineable.scala

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -251,9 +251,14 @@ object PrepareInlineable {
251251
*/
252252
object InlineSplice {
253253
def unapply(tree: Tree)(implicit ctx: Context): Option[Tree] = tree match {
254-
case Spliced(code) if Splicer.canBeSpliced(code) =>
255-
if (code.symbol.flags.is(Inline))
254+
case Spliced(code) =>
255+
if (!Splicer.canBeSpliced(code)) {
256+
ctx.error(
257+
"Malformed macro call. The contents of the splice ${...} must call a static method and arguments must be quoted or inline.",
258+
tree.sourcePos)
259+
} else if (code.symbol.flags.is(Inline)) {
256260
ctx.error("Macro cannot be implemented with an `inline` method", code.sourcePos)
261+
}
257262
Some(code)
258263
case Block(List(stat), Literal(Constants.Constant(()))) => unapply(stat)
259264
case Block(Nil, expr) => unapply(expr)

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2263,7 +2263,7 @@ class Typer extends Namer
22632263
ctx.error("Splice ${...} outside quotes '{...} or inline method", tree.sourcePos)
22642264
else if (level < 0)
22652265
ctx.error(
2266-
"""Splice ${...} at level -1.
2266+
s"""Splice $${...} at level $level.
22672267
|
22682268
|Inline method may contain a splice at level 0 but the contents of this splice cannot have a splice.
22692269
|""".stripMargin, tree.sourcePos

0 commit comments

Comments
 (0)