Skip to content

Commit b20f5f7

Browse files
authored
Merge pull request #14604 from dotty-staging/fix-14603
Only make the staged parts of a quote inlineable
2 parents efc637e + 9c2992f commit b20f5f7

File tree

3 files changed

+40
-2
lines changed

3 files changed

+40
-2
lines changed

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

Lines changed: 14 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._
@@ -61,13 +62,17 @@ object PrepareInlineable {
6162
*
6263
* Constant vals don't need accessors since they are inlined in FirstTransform.
6364
* Inline methods don't need accessors since they are inlined in Typer.
65+
*
66+
* When creating accessors for staged/quoted code we only need to create accessors
67+
* for the code that is staged. This excludes code at level 0 (except if it is inlined).
6468
*/
6569
def needsAccessor(sym: Symbol)(using Context): Boolean =
6670
sym.isTerm &&
6771
(sym.isOneOf(AccessFlags) || sym.privateWithin.exists) &&
6872
!sym.isContainedIn(inlineSym) &&
6973
!(sym.isStableMember && sym.info.widenTermRefExpr.isInstanceOf[ConstantType]) &&
70-
!sym.isInlineMethod
74+
!sym.isInlineMethod &&
75+
(Inliner.inInlineMethod || StagingContext.level > 0)
7176

7277
def preTransform(tree: Tree)(using Context): Tree
7378

@@ -79,7 +84,14 @@ object PrepareInlineable {
7984
}
8085

8186
override def transform(tree: Tree)(using Context): Tree =
82-
postTransform(super.transform(preTransform(tree)))
87+
inContext(stagingContext(tree)) {
88+
postTransform(super.transform(preTransform(tree)))
89+
}
90+
91+
private def stagingContext(tree: Tree)(using Context): Context = tree match
92+
case tree: Apply if tree.symbol.isQuote => StagingContext.quoteContext
93+
case tree: Apply if tree.symbol.isExprSplice => StagingContext.spliceContext
94+
case _ => ctx
8395
}
8496

8597
/** 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)