Skip to content

Commit bd493a3

Browse files
Move trait inlining into Inlining phase
1 parent 0988c5f commit bd493a3

File tree

4 files changed

+32
-14
lines changed

4 files changed

+32
-14
lines changed

compiler/src/dotty/tools/dotc/inlines/Inlines.scala

+25-7
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ object Inlines:
5656

5757
/** Can a call to method `meth` be inlined? */
5858
def isInlineable(meth: Symbol)(using Context): Boolean =
59-
meth.is(Inline) && meth.hasAnnotation(defn.BodyAnnot) && !inInlineMethod
59+
meth.isInlineMethod && meth.hasAnnotation(defn.BodyAnnot) && !inInlineMethod
6060

6161
def isInlineableFromInlineTrait(inlinedTraitSym: ClassSymbol, member: tpd.Tree)(using Context): Boolean =
6262
!(member.isInstanceOf[tpd.TypeDef] && inlinedTraitSym.typeParams.contains(member.symbol))
@@ -72,15 +72,19 @@ object Inlines:
7272
)
7373
&& !ctx.typer.hasInliningErrors
7474
&& !ctx.base.stopInlining
75+
&& !ctx.owner.isInlineTrait
7576

7677
tree match
7778
case Block(_, expr) =>
7879
needsInlining(expr)
7980
case tdef @ TypeDef(_, impl: Template) =>
80-
!tdef.symbol.isInlineTrait && impl.parents.exists(_.symbol.isInlineTrait) && isInlineableInCtx
81+
!tdef.symbol.isInlineTrait && impl.parents.map(symbolFromParent).exists(_.isInlineTrait) && isInlineableInCtx
8182
case _ =>
8283
isInlineable(tree.symbol) && !tree.tpe.widenTermRefExpr.isInstanceOf[MethodOrPoly] && isInlineableInCtx
8384

85+
private def symbolFromParent(parent: Tree)(using Context): Symbol =
86+
if parent.symbol.isConstructor then parent.symbol.owner else parent.symbol
87+
8488
private def needsTransparentInlining(tree: Tree)(using Context): Boolean =
8589
tree.symbol.is(Transparent)
8690
|| ctx.mode.is(Mode.ForceInline)
@@ -184,10 +188,22 @@ object Inlines:
184188
tree2
185189
end inlineCall
186190

187-
def inlineParentTrait(parent: tpd.Tree, overriddenDecls: Set[Symbol])(using Context): List[Tree] =
188-
val traitSym = if parent.symbol.isConstructor then parent.symbol.owner else parent.symbol
189-
if traitSym.isInlineTrait then InlineParentTrait(parent, traitSym.asClass).expandDefs(overriddenDecls)
190-
else Nil
191+
def inlineParentInlineTraits(cls: Tree)(using Context): Tree =
192+
cls match {
193+
case cls @ TypeDef(_, impl: Template) =>
194+
val overriddenSyms = cls.symbol.info.decls.toList.flatMap(_.allOverriddenSymbols).toSet
195+
val inlineDefs = impl.parents.flatMap(
196+
parent =>
197+
if symbolFromParent(parent).isInlineTrait then
198+
InlineParentTrait(parent)(using ctx.withOwner(cls.symbol)).expandDefs(overriddenSyms)
199+
else
200+
Nil
201+
)
202+
val impl1 = cpy.Template(impl)(body = inlineDefs ::: impl.body)
203+
cpy.TypeDef(cls)(rhs = impl1)
204+
case _ =>
205+
cls
206+
}
191207

192208
/** Try to inline a pattern with an inline unapply method. Fail with error if the maximal
193209
* inline depth is exceeded.
@@ -480,10 +496,12 @@ object Inlines:
480496
end expand
481497
end InlineCall
482498

483-
private class InlineParentTrait(parent: tpd.Tree, parentSym: ClassSymbol)(using Context) extends Inliner(parent):
499+
private class InlineParentTrait(parent: tpd.Tree)(using Context) extends Inliner(parent):
484500
import tpd._
485501
import Inlines.*
486502

503+
private val parentSym = symbolFromParent(parent)
504+
487505
private val thisInlineTrait = ThisType.raw(TypeRef(ctx.owner.prefix, ctx.owner))
488506

489507
def expandDefs(overriddenDecls: Set[Symbol]): List[Tree] =

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

+4
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ class Inlining extends MacroTransform {
7272

7373
override def transform(tree: Tree)(using Context): Tree = {
7474
tree match
75+
case tree: TypeDef if Inlines.needsInlining(tree) =>
76+
val tree1 = super.transform(tree)
77+
if tree1.tpe.isError then tree1
78+
else Inlines.inlineParentInlineTraits(tree1)
7579
case tree: MemberDef =>
7680
if tree.symbol.is(Inline) then tree
7781
else if tree.symbol.is(Param) then super.transform(tree)

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

+2
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,8 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
388388
val tree1 = cpy.DefDef(tree)(rhs = normalizeErasedRhs(tree.rhs, tree.symbol))
389389
processValOrDefDef(superAcc.wrapDefDef(tree1)(super.transform(tree1).asInstanceOf[DefDef]))
390390
case tree: TypeDef =>
391+
if tree.symbol.isInlineTrait then
392+
ctx.compilationUnit.needsInlining = true
391393
registerIfHasMacroAnnotations(tree)
392394
val sym = tree.symbol
393395
if (sym.isClass)

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

+1-7
Original file line numberDiff line numberDiff line change
@@ -2653,13 +2653,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
26532653
cdef.withType(UnspecifiedErrorType)
26542654
else {
26552655
val dummy = localDummy(cls, impl)
2656-
val inlineTraitDefs =
2657-
if ctx.isAfterTyper || cls.isInlineTrait then
2658-
Nil
2659-
else
2660-
val overriddenSyms = cls.info.decls.toList.flatMap(_.allOverriddenSymbols).toSet
2661-
parents1.flatMap(parent => Inlines.inlineParentTrait(parent, overriddenSyms))
2662-
val body1 = addAccessorDefs(cls, typedStats(impl.body, dummy)(using ctx.inClassContext(self1.symbol))._1) ::: inlineTraitDefs
2656+
val body1 = addAccessorDefs(cls, typedStats(impl.body, dummy)(using ctx.inClassContext(self1.symbol))._1)
26632657

26642658
if !ctx.isAfterTyper && cls.isInlineTrait then
26652659
val membersToInline = body1.filter(member => Inlines.isInlineableFromInlineTrait(cls, member))

0 commit comments

Comments
 (0)