Skip to content

Commit 62f62fb

Browse files
committed
Generate super accessors for inner classes
This is a port of the following PR in Scala 2: scala/scala#3935
1 parent b4a71d7 commit 62f62fb

File tree

1 file changed

+16
-4
lines changed

1 file changed

+16
-4
lines changed

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

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import dotty.tools.dotc.ast.{Trees, tpd}
55
import scala.collection.mutable
66
import ValueClasses.isMethodWithExtension
77
import core._
8-
import Contexts._, Flags._, Symbols._, NameOps._, Trees._
8+
import Contexts._, Flags._, Symbols._, NameOps._, Trees._, Types.SuperType
99
import TypeUtils._, SymUtils._
1010
import DenotTransformers.DenotTransformer
1111
import Symbols._
@@ -99,6 +99,7 @@ class SuperAccessors(thisPhase: DenotTransformer) {
9999
val sym = sel.symbol
100100
assert(sup.symbol.exists, s"missing symbol in $sel: ${sup.tpe}")
101101
val clazz = sup.symbol
102+
val currentClass = ctx.owner.enclosingClass
102103

103104
if (sym.isTerm && !sym.is(Method, butNot = Accessor) && !ctx.owner.isAllOf(ParamForwarder))
104105
// ParamForwaders as installed ParamForwarding.scala do use super calls to vals
@@ -145,9 +146,20 @@ class SuperAccessors(thisPhase: DenotTransformer) {
145146
sel.sourcePos)
146147
}
147148
}
148-
if (name.isTermName && mix.name.isEmpty &&
149-
(clazz.is(Trait) || clazz != ctx.owner.enclosingClass || !validCurrentClass))
150-
atPhase(thisPhase.next)(superAccessorCall(sel))
149+
150+
def mixIsTrait = sup.tpe match {
151+
case SuperType(thisTpe, superTpe) => superTpe.typeSymbol.is(Trait)
152+
}
153+
154+
val needAccessor = name.isTermName && {
155+
mix.name.isEmpty && (clazz.is(Trait) || clazz != currentClass || !validCurrentClass) ||
156+
// SI-8803. If we access super[A] from an inner class (!= currentClass) or closure (validCurrentClass),
157+
// where A is the superclass we need an accessor. If A is a parent trait we don't: in this case mixin
158+
// will re-route the super call directly to the impl class (it's statically known).
159+
!mix.name.isEmpty && (clazz != currentClass || !validCurrentClass) && !mixIsTrait
160+
}
161+
162+
if (needAccessor) atPhase(thisPhase.next)(superAccessorCall(sel))
151163
else sel
152164
}
153165

0 commit comments

Comments
 (0)