@@ -5,7 +5,7 @@ import dotty.tools.dotc.ast.{Trees, tpd}
5
5
import scala .collection .mutable
6
6
import ValueClasses .isMethodWithExtension
7
7
import core ._
8
- import Contexts ._ , Flags ._ , Symbols ._ , NameOps ._ , Trees ._
8
+ import Contexts ._ , Flags ._ , Symbols ._ , NameOps ._ , Trees ._ , Types . SuperType
9
9
import TypeUtils ._ , SymUtils ._
10
10
import DenotTransformers .DenotTransformer
11
11
import Symbols ._
@@ -99,6 +99,7 @@ class SuperAccessors(thisPhase: DenotTransformer) {
99
99
val sym = sel.symbol
100
100
assert(sup.symbol.exists, s " missing symbol in $sel: ${sup.tpe}" )
101
101
val clazz = sup.symbol
102
+ val currentClass = ctx.owner.enclosingClass
102
103
103
104
if (sym.isTerm && ! sym.is(Method , butNot = Accessor ) && ! ctx.owner.isAllOf(ParamForwarder ))
104
105
// ParamForwaders as installed ParamForwarding.scala do use super calls to vals
@@ -145,9 +146,20 @@ class SuperAccessors(thisPhase: DenotTransformer) {
145
146
sel.sourcePos)
146
147
}
147
148
}
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))
151
163
else sel
152
164
}
153
165
0 commit comments