Skip to content

Commit f1afb7c

Browse files
committed
Add basic infrastructure to inline after typer
1 parent 50f5a43 commit f1afb7c

File tree

4 files changed

+74
-1
lines changed

4 files changed

+74
-1
lines changed

compiler/src/dotty/tools/dotc/Compiler.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ class Compiler {
5050
/** Phases dealing with TASTY tree pickling and unpickling */
5151
protected def picklerPhases: List[List[Phase]] =
5252
List(new Pickler) :: // Generate TASTY info
53+
List(new Inlining) :: // Inline and execute macros
5354
List(new ReifyQuotes) :: // Turn quoted trees into explicit run-time data structures
5455
Nil
5556

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
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.quoted._
25+
import dotty.tools.dotc.transform.TreeMapWithStages._
26+
import dotty.tools.dotc.typer.Inliner
27+
28+
import scala.annotation.constructorOnly
29+
30+
31+
class Inlining extends MacroTransform {
32+
import tpd._
33+
34+
override def phaseName: String = Inlining.name
35+
36+
override def allowsImplicitSearch: Boolean = true
37+
38+
override def run(using Context): Unit =
39+
if (ctx.settings.YinlineBlackboxAfterTyper.value) super.run
40+
41+
override def checkPostCondition(tree: Tree)(using Context): Unit =
42+
tree match {
43+
case tree: RefTree if !Inliner.inInlineMethod =>
44+
assert(!tree.symbol.isInlineMethod)
45+
case _ =>
46+
}
47+
48+
protected def newTransformer(using Context): Transformer = new Transformer {
49+
override def transform(tree: tpd.Tree)(using Context): tpd.Tree =
50+
tree match
51+
case tree: DefTree =>
52+
if tree.symbol.is(Inline) then tree
53+
else super.transform(tree)
54+
case _: Typed =>
55+
super.transform(tree)
56+
case _ if Inliner.isInlineable(tree) && !Inliner.inInlineMethod =>
57+
val inlined = Inliner.inlineCall(tree)
58+
super.transform(inlined)
59+
case _ =>
60+
super.transform(tree)
61+
62+
}
63+
}
64+
65+
object Inlining {
66+
val name: String = "inlining"
67+
}

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ object Inliner {
4242
* @pre hasBodyToInline(sym)
4343
*/
4444
def bodyToInline(sym: SymDenotation)(using Context): Tree =
45-
if (sym.isInlineMethod && sym.hasAnnotation(defn.BodyAnnot))
45+
if hasBodyToInline(sym) then
4646
sym.getAnnotation(defn.BodyAnnot).get.tree
4747
else
4848
EmptyTree
@@ -61,6 +61,10 @@ object Inliner {
6161
case _ => isInlineable(tree.symbol) && !tree.tpe.isInstanceOf[MethodOrPoly]
6262
}
6363

64+
/** `sym` is an inline method with a known body to inline which looks like a tansparent inline */
65+
def hasTransparentBody(sym: SymDenotation)(using Context): Boolean =
66+
!bodyToInline(sym).isInstanceOf[Typed] // may have false negatives
67+
6468
/** Try to inline a call to an inline method. Fail with error if the maximal
6569
* inline depth is exceeded.
6670
*

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3249,6 +3249,7 @@ class Typer extends Namer
32493249
else if (methPart(tree).symbol.isAllOf(Inline | Deferred) && !Inliner.inInlineMethod) then
32503250
errorTree(tree, i"Deferred inline ${methPart(tree).symbol.showLocated} cannot be invoked")
32513251
else if (Inliner.isInlineable(tree) &&
3252+
(!ctx.settings.YinlineBlackboxAfterTyper.value || Inliner.hasTransparentBody(tree.symbol)) &&
32523253
!ctx.settings.YnoInline.value &&
32533254
!suppressInline) {
32543255
tree.tpe <:< wildApprox(pt)

0 commit comments

Comments
 (0)