Skip to content

Commit 3d162cb

Browse files
Implement ancestors inline traits without term args
Ancestors without term args do not need to be specified in the list of extended symbols This means that we need to recreate the trees manually, and most importantly, make sure the inlined members are overridden in the correct order The order of inheritance is defined by a left-handed DFS and is accessible through SymDenotation#baseClasses
1 parent 845c00b commit 3d162cb

File tree

3 files changed

+106
-9
lines changed

3 files changed

+106
-9
lines changed

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

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,26 @@ object Inlines:
8585
private def symbolFromParent(parent: Tree)(using Context): Symbol =
8686
if parent.symbol.isConstructor then parent.symbol.owner else parent.symbol
8787

88+
private def inlineTraitAncestors(cls: TypeDef)(using Context): List[Tree] = cls match {
89+
case tpd.TypeDef(_, tmpl: Template) =>
90+
val parentTrees: Map[Symbol, Tree] = tmpl.parents.map(par => symbolFromParent(par) -> par).toMap.filter(_._1.isInlineTrait)
91+
val ancestors: List[ClassSymbol] = cls.tpe.baseClasses.filter(sym => sym.isInlineTrait && sym != cls.symbol)
92+
ancestors.flatMap(ancestor =>
93+
def baseTree =
94+
cls.tpe.baseType(ancestor) match
95+
case AppliedType(tycon, targs) =>
96+
Some(AppliedTypeTree(TypeTree(tycon), targs.map(TypeTree(_))))
97+
case tref: TypeRef =>
98+
Some(Ident(tref))
99+
case baseTpe =>
100+
report.error(s"unknown base type ${baseTpe.show} for ancestor ${ancestor.show} of ${cls.symbol.show}")
101+
None
102+
parentTrees.get(ancestor).orElse(baseTree.map(_.withSpan(cls.span)))
103+
)
104+
case _ =>
105+
Nil
106+
}
107+
88108
private def needsTransparentInlining(tree: Tree)(using Context): Boolean =
89109
tree.symbol.is(Transparent)
90110
|| ctx.mode.is(Mode.ForceInline)
@@ -190,16 +210,14 @@ object Inlines:
190210

191211
def inlineParentInlineTraits(cls: Tree)(using Context): Tree =
192212
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
213+
case cls @ tpd.TypeDef(_, impl: Template) =>
214+
val clsOverriddenSyms = cls.symbol.info.decls.toList.flatMap(_.allOverriddenSymbols).toSet
215+
val inlineDefs = inlineTraitAncestors(cls).foldLeft(List.empty[Tree])(
216+
(defs, parent) =>
217+
val overriddenSymbols = clsOverriddenSyms ++ defs.flatMap(_.symbol.allOverriddenSymbols)
218+
defs ::: InlineParentTrait(parent)(using ctx.withOwner(cls.symbol)).expandDefs(overriddenSymbols)
201219
)
202-
val impl1 = cpy.Template(impl)(body = inlineDefs ::: impl.body)
220+
val impl1 = cpy.Template(impl)(body = impl.body ::: inlineDefs)
203221
cpy.TypeDef(cls)(rhs = impl1)
204222
case _ =>
205223
cls
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
0
2+
11
3+
12
4+
13
5+
21
6+
22
7+
30
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
* Inheritance tree:
3+
*
4+
* ___T0___
5+
* / | \
6+
* T11 T12 T13
7+
* \ /\ /
8+
* T21 T22
9+
* \ /
10+
* C
11+
*
12+
* Each trait overrides members so that they should have the same value as their name in C
13+
* (zero should be 0, eleven should be 11, etc.).
14+
*/
15+
16+
@main def Test =
17+
val c = C()
18+
for v <- allValues(c)
19+
do println(v)
20+
21+
def allValues(c: C): List[Int] =
22+
List(
23+
c.zero,
24+
c.eleven,
25+
c.twelve,
26+
c.thirteen,
27+
c.twentyOne,
28+
c.twentyTwo,
29+
c.thirty,
30+
)
31+
32+
inline trait T0:
33+
def zero: Int = 0
34+
def eleven: Int = 0
35+
def twelve: Int = 0
36+
def twentyOne: Int = 0
37+
def thirteen: Int = 0
38+
def twentyTwo: Int = 0
39+
def thirty: Int = 0
40+
41+
inline trait T11 extends T0:
42+
override def eleven: Int = 11
43+
override def twelve: Int = 11
44+
override def twentyOne: Int = 11
45+
override def thirteen: Int = 11
46+
override def twentyTwo: Int = 11
47+
override def thirty: Int = 11
48+
49+
inline trait T12 extends T0:
50+
override def twelve: Int = 12
51+
override def twentyOne: Int = 12
52+
override def thirteen: Int = 12
53+
override def twentyTwo: Int = 12
54+
override def thirty: Int = 12
55+
56+
inline trait T21 extends T11, T12:
57+
override def twentyOne: Int = 21
58+
override def thirteen: Int = 21
59+
override def twentyTwo: Int = 21
60+
override def thirty: Int = 21
61+
62+
inline trait T13 extends T0:
63+
override def thirteen: Int = 13
64+
override def twentyTwo: Int = 13
65+
override def thirty: Int = 13
66+
67+
inline trait T22 extends T12, T13:
68+
override def twentyTwo: Int = 22
69+
override def thirty: Int = 22
70+
71+
class C extends T21, T22:
72+
override def thirty: Int = 30

0 commit comments

Comments
 (0)