Skip to content

Commit 37fac7f

Browse files
committed
Generate super accessor for traits
1 parent 8dd35ac commit 37fac7f

File tree

3 files changed

+22
-16
lines changed

3 files changed

+22
-16
lines changed

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

+11-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import SymUtils._
99
import Symbols._
1010
import Decorators._
1111
import DenotTransformers._
12+
import Names._
13+
import StdNames._
1214
import NameOps._
1315
import NameKinds._
1416
import ResolveSuper._
@@ -80,10 +82,18 @@ object ResolveSuper {
8082
def rebindSuper(base: Symbol, acc: Symbol)(using Context): Symbol = {
8183
var bcs = base.info.baseClasses.dropWhile(acc.owner != _).tail
8284
var sym: Symbol = NoSymbol
83-
val SuperAccessorName(memberName) = acc.name.unexpandedName
85+
var mix: Name = nme.EMPTY
86+
val memberName = acc.name.unexpandedName match
87+
case SuperAccessorName(ExpandPrefixName(name, mixName)) =>
88+
mix = mixName.toTypeName
89+
name
90+
case SuperAccessorName(name) =>
91+
name
92+
8493
ctx.debuglog(i"starting rebindsuper from $base of ${acc.showLocated}: ${acc.info} in $bcs, name = $memberName")
8594
while (bcs.nonEmpty && sym == NoSymbol) {
8695
val other = bcs.head.info.nonPrivateDecl(memberName)
96+
.filterWithPredicate(denot => denot.exists && (mix.isEmpty || denot.symbol.owner.name == mix))
8797
.matchingDenotation(base.thisType, base.thisType.memberInfo(acc))
8898
ctx.debuglog(i"rebindsuper ${bcs.head} $other deferred = ${other.symbol.is(Deferred)}")
8999
if other.exists && !other.symbol.is(Deferred) then

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

+8-12
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ 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._, Types.SuperType
8+
import Contexts._, Flags._, Symbols._, Names._, StdNames._, NameOps._, Trees._
99
import TypeUtils._, SymUtils._
1010
import DenotTransformers.DenotTransformer
1111
import Symbols._
1212
import util.Spans._
1313
import Decorators._
14-
import NameKinds.SuperAccessorName
14+
import NameKinds.{ SuperAccessorName, ExpandPrefixName }
1515

1616
/** This class adds super accessors for all super calls that either
1717
* appear in a trait or have as a target a member of some outer class.
@@ -62,11 +62,12 @@ class SuperAccessors(thisPhase: DenotTransformer) {
6262
private val accDefs = newMutableSymbolMap[mutable.ListBuffer[Tree]]
6363

6464
/** A super accessor call corresponding to `sel` */
65-
private def superAccessorCall(sel: Select)(using Context) = {
65+
private def superAccessorCall(sel: Select, mixName: Name = nme.EMPTY)(using Context) = {
6666
val Select(qual, name) = sel
6767
val sym = sel.symbol
6868
val clazz = qual.symbol.asClass
69-
var superName = SuperAccessorName(name.asTermName)
69+
val preName = if (mixName.isEmpty) name.toTermName else ExpandPrefixName(name.toTermName, mixName.toTermName)
70+
var superName = SuperAccessorName(preName)
7071
if (clazz.is(Trait)) superName = superName.expandedName(clazz)
7172
val superInfo = sel.tpe.widenSingleton.ensureMethodic
7273

@@ -147,19 +148,14 @@ class SuperAccessors(thisPhase: DenotTransformer) {
147148
}
148149
}
149150

150-
def mixIsTrait = sup.tpe match {
151-
case SuperType(thisTpe, superTpe) => superTpe.typeSymbol.is(Trait)
152-
}
153-
154151
val needAccessor = name.isTermName && {
155152
mix.name.isEmpty && (clazz.is(Trait) || clazz != currentClass || !validCurrentClass) ||
156153
// 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
154+
// where A is the superclass we need an accessor.
155+
!mix.name.isEmpty && (clazz != currentClass || !validCurrentClass)
160156
}
161157

162-
if (needAccessor) atPhase(thisPhase.next)(superAccessorCall(sel))
158+
if (needAccessor) atPhase(thisPhase.next)(superAccessorCall(sel, mix.name))
163159
else sel
164160
}
165161

tests/run/t10290.scala

+3-3
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ object Test {
2121
def main(args : Array[String]) : Unit = {
2222
val b = new B
2323
val c = new b.C
24-
assert(c.t1 == "A1")
25-
assert(c.t2 == "A2")
26-
assert(c.t3 == "B")
24+
assert(c.t1 == "A1", c.t1)
25+
assert(c.t2 == "A2", c.t2)
26+
assert(c.t3 == "B", c.t3)
2727
}
2828
}

0 commit comments

Comments
 (0)