Skip to content

Fix staging using inline methods in quotes #10803

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions compiler/src/dotty/tools/dotc/transform/Inlining.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package dotty.tools.dotc
package transform

import core._
import Decorators._
import Flags._
import Types._
import Contexts._
import Symbols._
import Constants._
import ast.Trees._
import ast.{TreeTypeMap, untpd}
import util.Spans._
import tasty.TreePickler.Hole
import SymUtils._
import NameKinds._
import dotty.tools.dotc.ast.tpd
import typer.Implicits.SearchFailureType

import scala.collection.mutable
import dotty.tools.dotc.core.Annotations._
import dotty.tools.dotc.core.Names._
import dotty.tools.dotc.core.StdNames._
import dotty.tools.dotc.core.StagingContext._
import dotty.tools.dotc.quoted._
import dotty.tools.dotc.transform.TreeMapWithStages._
import dotty.tools.dotc.typer.Inliner
import dotty.tools.dotc.typer.ImportInfo.withRootImports
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This import seems to be not used.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those are from #9984. I kept them to simplify the merge afterward.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will cleanup all imports in #9984


import scala.annotation.constructorOnly

/** Inlines all calls to inline methods that are not in an inline method or a quote */
class Inlining extends MacroTransform {
import tpd._

override def phaseName: String = Inlining.name

override def allowsImplicitSearch: Boolean = true

override def checkPostCondition(tree: Tree)(using Context): Unit =
tree match {
case tree: RefTree if !Inliner.inInlineMethod && StagingContext.level == 0 =>
assert(!tree.symbol.isInlineMethod)
case _ =>
}

protected def newTransformer(using Context): Transformer = new Transformer {
override def transform(tree: tpd.Tree)(using Context): tpd.Tree =
tree match
case tree: DefTree =>
if tree.symbol.is(Inline) then tree
else super.transform(tree)
case _: Typed | _: Block =>
super.transform(tree)
case _ if Inliner.isInlineable(tree) && !tree.tpe.widen.isInstanceOf[MethodOrPoly] && StagingContext.level == 0 =>
val tree1 = super.transform(tree)
val inlined = Inliner.inlineCall(tree1)
if tree1 eq inlined then inlined
else transform(inlined)
case _: TypeApply if tree.symbol.isQuote =>
ctx.compilationUnit.needsStaging = true
super.transform(tree)
case _ =>
super.transform(tree)

}
}

object Inlining {
val name: String = "inlining"
}
6 changes: 4 additions & 2 deletions staging/src/scala/quoted/staging/QuoteCompiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import dotty.tools.dotc.core.Symbols._
import dotty.tools.dotc.core.Types.ExprType
import dotty.tools.dotc.quoted.PickledQuotes
import dotty.tools.dotc.transform.Splicer.checkEscapedVariables
import dotty.tools.dotc.transform.PickleQuotes
import dotty.tools.dotc.transform.{Inlining, PickleQuotes}
import dotty.tools.dotc.util.Spans.Span
import dotty.tools.dotc.util.SourceFile
import dotty.tools.io.{Path, VirtualFile}
Expand All @@ -39,7 +39,9 @@ private class QuoteCompiler extends Compiler:
List(List(new QuotedFrontend))

override protected def picklerPhases: List[List[Phase]] =
List(List(new PickleQuotes))
List(new Inlining) ::
List(new PickleQuotes) ::
Nil

override def newRun(implicit ctx: Context): ExprRun =
reset()
Expand Down
2 changes: 1 addition & 1 deletion tests/run-staging/i3876-d.check
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
6
6
Test.inlineLambda.apply(3)
11 changes: 4 additions & 7 deletions tests/run-staging/i3876-e.check
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@

6
{
val x: 3 = {
scala.Predef.println()
3
}
6
}
Test.inlineLambda.apply({
scala.Predef.println()
3
})
3 changes: 3 additions & 0 deletions tests/run-staging/quote-toExprOfTuple.check
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,6 @@
(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20)
(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21)
(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22)
(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23)
(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24)
(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)
2 changes: 1 addition & 1 deletion tests/run-staging/quote-toExprOfTuple.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import scala.quoted.staging._
object Test {
given Toolbox = Toolbox.make(getClass.getClassLoader)
def main(args: Array[String]): Unit = {
for (n <- 0 to 22) { // FIXME should go up to 25. This should be fixed in #9984
for (n <- 0 to 25) {
prev = 0
println(run { Expr.ofTupleFromSeq(Seq.fill(n)('{next})) })
}
Expand Down