Skip to content

Commit 218b48c

Browse files
Handle inlining of statements in inline trait body
Statements in the body of an inline trait need to be inlined properly: - before any statement of the implementing child - making sure that the body is not executed twice (statements removed in Inlining)
1 parent 053a3fd commit 218b48c

File tree

4 files changed

+44
-7
lines changed

4 files changed

+44
-7
lines changed

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

+8-3
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ object Inlines:
220220
val overriddenSymbols = clsOverriddenSyms ++ defs.flatMap(_.symbol.allOverriddenSymbols)
221221
defs ::: InlineParentTrait(parent)(using ctx.withOwner(cls.symbol)).expandDefs(overriddenSymbols)
222222
)
223-
val impl1 = cpy.Template(impl)(body = impl.body ::: inlineDefs)
223+
val impl1 = cpy.Template(impl)(body = inlineDefs ::: impl.body)
224224
cpy.TypeDef(cls)(rhs = impl1)
225225
case _ =>
226226
cls
@@ -531,8 +531,13 @@ object Inlines:
531531
def expandDefs(overriddenDecls: Set[Symbol]): List[Tree] =
532532
paramAccessorsMapper.registerParamValuesOf(parent)
533533
val stats = Inlines.defsToInline(parentSym).filterNot(stat => overriddenDecls.contains(stat.symbol))
534-
val inlinedSymbols = stats.map(stat => inlinedSym(stat.symbol))
535-
stats.zip(inlinedSymbols).map(expandStat)
534+
stats.map{
535+
case member: MemberDef => Left((member, inlinedSym(member.symbol)))
536+
case stat => Right(stat)
537+
}.map{
538+
case Left((tree, inlinedSym)) => expandStat(tree, inlinedSym)
539+
case Right(tree) => inlinedRhs(tree)
540+
}
536541
end expandDefs
537542

538543
protected class InlineTraitTypeMap extends InlinerTypeMap {

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

+6-4
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ class Inlining extends MacroTransform, SymTransformer {
6868
else
6969
sym
7070

71-
def transformInnerClasses(inlineTrait: TypeDef)(using Context): TypeDef =
71+
def transformInlineTrait(inlineTrait: TypeDef)(using Context): TypeDef =
7272
val tpd.TypeDef(_, tmpl: Template) = inlineTrait: @unchecked
7373
val body1 = tmpl.body.flatMap {
7474
case innerClass @ tpd.TypeDef(name, tmpl1: Template) =>
@@ -89,8 +89,10 @@ class Inlining extends MacroTransform, SymTransformer {
8989
nestingLevel = innerClass.symbol.nestingLevel,
9090
).asType
9191
List(newTrait, TypeDef(newTypeSym))
92-
case member =>
92+
case member: MemberDef =>
9393
List(member)
94+
case _ =>
95+
Nil
9496
}
9597
val tmpl1 = cpy.Template(tmpl)(body = body1)
9698
cpy.TypeDef(inlineTrait)(rhs = tmpl1)
@@ -105,11 +107,11 @@ class Inlining extends MacroTransform, SymTransformer {
105107
override def transform(tree: Tree)(using Context): Tree = {
106108
tree match
107109
case tree: TypeDef if tree.symbol.isInlineTrait =>
108-
transformInnerClasses(tree)
110+
transformInlineTrait(tree)
109111
case tree: TypeDef if Inlines.needsInlining(tree) =>
110112
val tree1 = super.transform(tree).asInstanceOf[TypeDef]
111113
if tree1.tpe.isError then tree1
112-
else if tree1.symbol.isInlineTrait then transformInnerClasses(tree1)
114+
else if tree1.symbol.isInlineTrait then transformInlineTrait(tree1)
113115
else Inlines.inlineParentInlineTraits(tree1)
114116
case tree: MemberDef =>
115117
if tree.symbol.is(Inline) then tree
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
1
2+
foo
3+
foo
4+
1
5+
foo
6+
bar
7+
bar
8+
bar
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
inline trait A[T]:
2+
var x = 1
3+
def foo =
4+
if x == 1 then println("1")
5+
x = 1 - x
6+
println("foo")
7+
8+
foo
9+
foo
10+
foo
11+
12+
class B extends A[Int]:
13+
def bar =
14+
if x == 1 then println("1")
15+
println("bar")
16+
17+
bar
18+
bar
19+
bar
20+
21+
@main def Test =
22+
B()

0 commit comments

Comments
 (0)