Skip to content

Commit 246df88

Browse files
committed
WIP Move inline β-reduction after post typer
1 parent 9aa3811 commit 246df88

File tree

3 files changed

+31
-15
lines changed

3 files changed

+31
-15
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ class Compiler {
3737
protected def frontendPhases: List[List[Phase]] =
3838
List(new FrontEnd) :: // Compiler frontend: scanner, parser, namer, typer
3939
List(new sbt.ExtractDependencies) :: // Sends information on classes' dependencies to sbt via callbacks
40-
List(new InlineCalls) :: // β-reduce inline calls
4140
List(new PostTyper) :: // Additional checks and cleanups after type checking
4241
List(new sbt.ExtractAPI) :: // Sends a representation of the API of classes to sbt via callbacks
42+
List(new InlineCalls) :: // β-reduce inline calls
4343
Nil
4444

4545
/** Phases dealing with TASTY tree pickling and unpickling */

compiler/src/dotty/tools/dotc/transform/InlineCalls.scala

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,33 @@ class InlineCalls extends MacroTransform { thisPhase =>
2323
class InlineCallsTransformer extends Transformer {
2424
override def transform(tree: Tree)(implicit ctx: Context): Tree = tree match {
2525
case _: RefTree | _: GenericApply[_] if Inliner.isInlineable(tree) && !ctx.reporter.hasErrors =>
26-
transform(Inliner.inlineCall(tree, tree.tpe.widen))
26+
normalize(transform(Inliner.inlineCall(tree, tree.tpe.widen)))
27+
case _: MemberDef =>
28+
val newTree = super.transform(tree)
29+
newTree.symbol.defTree = newTree // update tree set in PostTyper or set for inlined members
30+
newTree
2731
case _ =>
2832
super.transform(tree)
2933
}
34+
}
3035

36+
def normalize(tree: Tree)(implicit ctx: Context): Tree = tree match {
37+
case Inlined(call, bindings, expansion) if !call.isEmpty =>
38+
// TODO: Normalize when Inlined is created. We never use the full call, we always collapse it first.
39+
// Leave only a call trace consisting of
40+
// - a reference to the top-level class from which the call was inlined,
41+
// - the call's position
42+
// in the call field of an Inlined node.
43+
// The trace has enough info to completely reconstruct positions.
44+
// The minimization is done for two reasons:
45+
// 1. To save space (calls might contain large inline arguments, which would otherwise
46+
// be duplicated
47+
// 2. To enable correct pickling (calls can share symbols with the inlined code, which
48+
// would trigger an assertion when pickling).
49+
val callTrace = Ident(call.symbol.topLevelClass.typeRef).withPos(call.pos)
50+
cpy.Inlined(tree)(callTrace, bindings, expansion)
51+
case _ =>
52+
tree
3153
}
3254
}
3355

compiler/src/dotty/tools/dotc/transform/PostTyper.scala

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,11 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
178178
}
179179
}
180180

181+
private def handleInlineCall(sym: Symbol)(implicit ctx: Context): Unit = {
182+
if (sym.is(Inline))
183+
ctx.compilationUnit.containsQuotesOrSplices = true
184+
}
185+
181186
private object dropInlines extends TreeMap {
182187
override def transform(tree: Tree)(implicit ctx: Context): Tree = tree match {
183188
case Inlined(call, _, _) =>
@@ -189,12 +194,14 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
189194
override def transform(tree: Tree)(implicit ctx: Context): Tree =
190195
try tree match {
191196
case tree: Ident if !tree.isType =>
197+
handleInlineCall(tree.symbol)
192198
handleMeta(tree.symbol)
193199
tree.tpe match {
194200
case tpe: ThisType => This(tpe.cls).withPos(tree.pos)
195201
case _ => tree
196202
}
197203
case tree @ Select(qual, name) =>
204+
handleInlineCall(tree.symbol)
198205
handleMeta(tree.symbol)
199206
if (name.isTypeName) {
200207
Checking.checkRealizable(qual.tpe, qual.pos.focus)
@@ -236,19 +243,6 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
236243
case _ =>
237244
super.transform(tree1)
238245
}
239-
case Inlined(call, bindings, expansion) if !call.isEmpty =>
240-
// Leave only a call trace consisting of
241-
// - a reference to the top-level class from which the call was inlined,
242-
// - the call's position
243-
// in the call field of an Inlined node.
244-
// The trace has enough info to completely reconstruct positions.
245-
// The minimization is done for two reasons:
246-
// 1. To save space (calls might contain large inline arguments, which would otherwise
247-
// be duplicated
248-
// 2. To enable correct pickling (calls can share symbols with the inlined code, which
249-
// would trigger an assertion when pickling).
250-
val callTrace = Ident(call.symbol.topLevelClass.typeRef).withPos(call.pos)
251-
cpy.Inlined(tree)(callTrace, transformSub(bindings), transform(expansion)(inlineContext(call)))
252246
case tree: Template =>
253247
withNoCheckNews(tree.parents.flatMap(newPart)) {
254248
val templ1 = paramFwd.forwardParamAccessors(tree)

0 commit comments

Comments
 (0)