Skip to content

Commit bac02d5

Browse files
committed
Only make the staged parts of a quote inlineable
Contents of splices do not need to be transformed as they will be evaluated before the code is inlined. Therefore we only want to make code at staging level 1 or grater inlineable. If the quote is in an inline method, we also need to make the contents of the splices inlineable (i.e. for any level). Fix #14603
1 parent fae7c09 commit bac02d5

File tree

3 files changed

+37
-2
lines changed

3 files changed

+37
-2
lines changed

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

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import NameKinds.{InlineAccessorName, UniqueInlineName}
1717
import NameOps._
1818
import Annotations._
1919
import transform.{AccessProxies, PCPCheckAndHeal, Splicer}
20+
import transform.SymUtils.*
2021
import config.Printers.inlining
2122
import util.Property
2223
import dotty.tools.dotc.transform.TreeMapWithStages._
@@ -67,7 +68,8 @@ object PrepareInlineable {
6768
(sym.isOneOf(AccessFlags) || sym.privateWithin.exists) &&
6869
!sym.isContainedIn(inlineSym) &&
6970
!(sym.isStableMember && sym.info.widenTermRefExpr.isInstanceOf[ConstantType]) &&
70-
!sym.isInlineMethod
71+
!sym.isInlineMethod &&
72+
(Inliner.inInlineMethod || StagingContext.level > 0)
7173

7274
def preTransform(tree: Tree)(using Context): Tree
7375

@@ -79,7 +81,14 @@ object PrepareInlineable {
7981
}
8082

8183
override def transform(tree: Tree)(using Context): Tree =
82-
postTransform(super.transform(preTransform(tree)))
84+
inContext(stagingContext(tree)) {
85+
postTransform(super.transform(preTransform(tree)))
86+
}
87+
88+
private def stagingContext(tree: Tree)(using Context): Context = tree match
89+
case tree: Apply if tree.symbol.isQuote => StagingContext.quoteContext
90+
case tree: Apply if tree.symbol.isExprSplice => StagingContext.spliceContext
91+
case _ => ctx
8392
}
8493

8594
/** Direct approach: place the accessor with the accessed symbol. This has the

tests/pos-macros/i14603.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import scala.quoted.*
2+
3+
class Macro(using qctx: Quotes): // Anti-pattern: put Quotes in a field
4+
import qctx.reflect._
5+
6+
def apply: Expr[Unit] = '{
7+
println("in quote")
8+
${ val a: Term = '{ println("in nested quote") }.asTerm; ??? }
9+
}

tests/pos-macros/i14603b.scala

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import scala.language.experimental.macros
2+
import scala.quoted.*
3+
4+
class Runtime
5+
6+
class Macro(using qctx: Quotes) { // Anti-pattern: put Quotes in a field
7+
import qctx.reflect._
8+
9+
def apply[A: Type](x: Expr[A]): Expr[Unit] = {
10+
'{
11+
val rt: Runtime = ???
12+
${Block(doExprs('{ rt }.asTerm), '{ () }.asTerm).asExprOf[Unit]}
13+
}
14+
}
15+
16+
private def doExprs(rt: Term): List[Term] = Nil
17+
}

0 commit comments

Comments
 (0)