Skip to content

Commit 7d715fe

Browse files
authored
Merge pull request #10803 from dotty-staging/fix-staging-inline-calls-in-quotes
Fix staging using inline methods in quotes
2 parents cea8a6f + b4240ed commit 7d715fe

File tree

8 files changed

+84
-11
lines changed

8 files changed

+84
-11
lines changed
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package dotty.tools.dotc
2+
package transform
3+
4+
import core._
5+
import Decorators._
6+
import Flags._
7+
import Types._
8+
import Contexts._
9+
import Symbols._
10+
import Constants._
11+
import ast.Trees._
12+
import ast.{TreeTypeMap, untpd}
13+
import util.Spans._
14+
import tasty.TreePickler.Hole
15+
import SymUtils._
16+
import NameKinds._
17+
import dotty.tools.dotc.ast.tpd
18+
import typer.Implicits.SearchFailureType
19+
20+
import scala.collection.mutable
21+
import dotty.tools.dotc.core.Annotations._
22+
import dotty.tools.dotc.core.Names._
23+
import dotty.tools.dotc.core.StdNames._
24+
import dotty.tools.dotc.core.StagingContext._
25+
import dotty.tools.dotc.quoted._
26+
import dotty.tools.dotc.transform.TreeMapWithStages._
27+
import dotty.tools.dotc.typer.Inliner
28+
import dotty.tools.dotc.typer.ImportInfo.withRootImports
29+
30+
import scala.annotation.constructorOnly
31+
32+
/** Inlines all calls to inline methods that are not in an inline method or a quote */
33+
class Inlining extends MacroTransform {
34+
import tpd._
35+
36+
override def phaseName: String = Inlining.name
37+
38+
override def allowsImplicitSearch: Boolean = true
39+
40+
override def checkPostCondition(tree: Tree)(using Context): Unit =
41+
tree match {
42+
case tree: RefTree if !Inliner.inInlineMethod && StagingContext.level == 0 =>
43+
assert(!tree.symbol.isInlineMethod)
44+
case _ =>
45+
}
46+
47+
protected def newTransformer(using Context): Transformer = new Transformer {
48+
override def transform(tree: tpd.Tree)(using Context): tpd.Tree =
49+
tree match
50+
case tree: DefTree =>
51+
if tree.symbol.is(Inline) then tree
52+
else super.transform(tree)
53+
case _: Typed | _: Block =>
54+
super.transform(tree)
55+
case _ if Inliner.isInlineable(tree) && !tree.tpe.widen.isInstanceOf[MethodOrPoly] && StagingContext.level == 0 =>
56+
val tree1 = super.transform(tree)
57+
val inlined = Inliner.inlineCall(tree1)
58+
if tree1 eq inlined then inlined
59+
else transform(inlined)
60+
case _: TypeApply if tree.symbol.isQuote =>
61+
ctx.compilationUnit.needsStaging = true
62+
super.transform(tree)
63+
case _ =>
64+
super.transform(tree)
65+
66+
}
67+
}
68+
69+
object Inlining {
70+
val name: String = "inlining"
71+
}

staging/src/scala/quoted/staging/QuoteCompiler.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import dotty.tools.dotc.core.Symbols._
1616
import dotty.tools.dotc.core.Types.ExprType
1717
import dotty.tools.dotc.quoted.PickledQuotes
1818
import dotty.tools.dotc.transform.Splicer.checkEscapedVariables
19-
import dotty.tools.dotc.transform.PickleQuotes
19+
import dotty.tools.dotc.transform.{Inlining, PickleQuotes}
2020
import dotty.tools.dotc.util.Spans.Span
2121
import dotty.tools.dotc.util.SourceFile
2222
import dotty.tools.io.{Path, VirtualFile}
@@ -39,7 +39,9 @@ private class QuoteCompiler extends Compiler:
3939
List(List(new QuotedFrontend))
4040

4141
override protected def picklerPhases: List[List[Phase]] =
42-
List(List(new PickleQuotes))
42+
List(new Inlining) ::
43+
List(new PickleQuotes) ::
44+
Nil
4345

4446
override def newRun(implicit ctx: Context): ExprRun =
4547
reset()

tests/run-staging/i3876-d.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
6
2-
6
2+
Test.inlineLambda.apply(3)

tests/run-staging/i3876-e.check

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11

22
6
3-
{
4-
val x: 3 = {
5-
scala.Predef.println()
6-
3
7-
}
8-
6
9-
}
3+
Test.inlineLambda.apply({
4+
scala.Predef.println()
5+
3
6+
})

tests/run-staging/quote-toExprOfTuple.check

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,6 @@
2121
(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20)
2222
(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21)
2323
(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22)
24+
(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23)
25+
(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24)
26+
(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25)

tests/run-staging/quote-toExprOfTuple.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import scala.quoted.staging._
55
object Test {
66
given Toolbox = Toolbox.make(getClass.getClassLoader)
77
def main(args: Array[String]): Unit = {
8-
for (n <- 0 to 22) { // FIXME should go up to 25. This should be fixed in #9984
8+
for (n <- 0 to 25) {
99
prev = 0
1010
println(run { Expr.ofTupleFromSeq(Seq.fill(n)('{next})) })
1111
}

0 commit comments

Comments
 (0)