Skip to content

Commit e674b6e

Browse files
Strip parents of inner class from concrete elements
When "transforming" an inner class into an inner trait, we need to adapt its parents as well. When declaring its parents, a trait cannot call their constructor, therefore the different Apply and other trees should be pruned from them. For example: ``` inline trait A: class InnerA extends Object ``` will result in the following code after Inlining: ``` inline trait A: trait InnerA$trait extends Object type InnerA <: InnerA$trait ``` The tree for `Object` in the first case is ``` Apply(Select(New(Ident(Object)),<init>),List()) ``` but if we make InnerA a trait instead, it is simply ``` Ident(Object) ``` The goal is therefore to strip the different "concrete" elements of the parents when transforming a class into a trait.
1 parent ff6061e commit e674b6e

File tree

1 file changed

+16
-1
lines changed

1 file changed

+16
-1
lines changed

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

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,13 +78,18 @@ class Inlining extends MacroTransform, SymTransformer {
7878
case member: MemberDef =>
7979
List(member)
8080
case _ =>
81+
// Remove non-memberdefs, as they are normally placed into $init()
8182
Nil
8283
}
8384
val tmpl1 = cpy.Template(tmpl)(body = body1)
8485
cpy.TypeDef(inlineTrait)(rhs = tmpl1)
8586

8687
private def makeTraitFromInnerClass(innerClass: TypeDef)(using Context): TypeDef =
87-
cpy.TypeDef(innerClass)(name = newInnerClassName(innerClass.name))
88+
val TypeDef(name, tmpl: Template) = innerClass: @unchecked
89+
val newInnerParents = tmpl.parents.mapConserve(ConcreteParentStripper.apply)
90+
val tmpl1 = cpy.Template(tmpl)(parents = newInnerParents) // TODO .withType(???)
91+
cpy.TypeDef(innerClass)(name = newInnerClassName(name), rhs = tmpl1)
92+
end makeTraitFromInnerClass
8893

8994
private def makeTypeFromInnerClass(parentSym: Symbol, innerClass: TypeDef, newTraitSym: Symbol)(using Context): TypeDef =
9095
val upperBound = innerClass.symbol.primaryConstructor.info match {
@@ -164,6 +169,16 @@ class Inlining extends MacroTransform, SymTransformer {
164169
}
165170

166171
private def newInnerClassName(name: Name): name.ThisName = name ++ str.INLINE_TRAIT_INNER_CLASS_SUFFIX
172+
173+
private object ConcreteParentStripper extends TreeAccumulator[Tree] {
174+
def apply(tree: Tree)(using Context): Tree = apply(tree, tree)
175+
176+
override def apply(x: Tree, tree: Tree)(using Context): Tree = tree match {
177+
case ident: Ident => ident
178+
case tpt: TypeTree => tpt
179+
case _ => foldOver(x, tree)
180+
}
181+
}
167182
}
168183

169184
object Inlining:

0 commit comments

Comments
 (0)