Skip to content

Commit fbc1609

Browse files
committed
Merge pull request #767 from dotty-staging/fix-#756-super-accessors
Fix #756 super accessors
2 parents 6ccd6b5 + 4689bd3 commit fbc1609

File tree

6 files changed

+34
-4
lines changed

6 files changed

+34
-4
lines changed

src/dotty/tools/dotc/core/NameOps.scala

+5
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,11 @@ object NameOps {
167167

168168
def expandedName(prefix: Name): N = expandedName(prefix, nme.EXPAND_SEPARATOR)
169169

170+
/** Revert the expanded name. Note: This currently gives incorrect results
171+
* if the normal name contains `nme.EXPAND_SEPARATOR`, i.e. two consecutive '$'
172+
* signs. This can happen for instance if a super accessor is paired with
173+
* an encoded name, e.g. super$$plus$eq. See #765.
174+
*/
170175
def unexpandedName: N = {
171176
val idx = name.lastIndexOfSlice(nme.EXPAND_SEPARATOR)
172177
if (idx < 0) name else (name drop (idx + nme.EXPAND_SEPARATOR.length)).asInstanceOf[N]

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

+7-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,13 @@ class ResolveSuper extends MiniPhaseTransform with IdentityDenotTransformer { th
5959
private def rebindSuper(base: Symbol, acc: Symbol)(implicit ctx: Context): Symbol = {
6060
var bcs = base.info.baseClasses.dropWhile(acc.owner != _).tail
6161
var sym: Symbol = NoSymbol
62-
val SuperAccessorName(memberName) = ctx.atPhase(ctx.picklerPhase){ implicit ctx => acc.name }: Name // dotty deviation: ": Name" needed otherwise pattern type is neither a subtype nor a supertype of selector type
62+
val unexpandedAccName =
63+
if (acc.is(ExpandedName)) // Cannot use unexpandedName because of #765. t2183.scala would fail if we did.
64+
acc.name
65+
.drop(acc.name.indexOfSlice(nme.EXPAND_SEPARATOR ++ nme.SUPER_PREFIX))
66+
.drop(nme.EXPAND_SEPARATOR.length)
67+
else acc.name
68+
val SuperAccessorName(memberName) = unexpandedAccName: Name // dotty deviation: ": Name" needed otherwise pattern type is neither a subtype nor a supertype of selector type
6369
ctx.debuglog(i"starting rebindsuper from $base of ${acc.showLocated}: ${acc.info} in $bcs, name = $memberName")
6470
while (bcs.nonEmpty && sym == NoSymbol) {
6571
val other = bcs.head.info.nonPrivateDecl(memberName)

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

+5-3
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,12 @@ class SuperAccessors(thisTransformer: DenotTransformer) {
7171
val Select(qual, name) = sel
7272
val sym = sel.symbol
7373
val clazz = qual.symbol.asClass
74-
val supername = name.superName
74+
var supername = name.superName
75+
if (clazz is Trait) supername = supername.expandedName(clazz)
7576

7677
val superAcc = clazz.info.decl(supername).suchThat(_.signature == sym.signature).symbol orElse {
7778
ctx.debuglog(s"add super acc ${sym.showLocated} to $clazz")
78-
val deferredOrPrivate = if (clazz is Trait) Deferred else Private
79+
val deferredOrPrivate = if (clazz is Trait) Deferred | ExpandedName else Private
7980
val acc = ctx.newSymbol(
8081
clazz, supername, SuperAccessor | Artifact | Method | deferredOrPrivate,
8182
sel.tpe.widenSingleton.ensureMethodic, coord = sym.coord).enteredAfter(thisTransformer)
@@ -106,10 +107,11 @@ class SuperAccessors(thisTransformer: DenotTransformer) {
106107
val member = sym.overridingSymbol(clazz)
107108
if (mix != tpnme.EMPTY ||
108109
!member.exists ||
109-
!(member is AbsOverride) && member.isIncompleteIn(clazz))
110+
!((member is AbsOverride) && member.isIncompleteIn(clazz)))
110111
ctx.error(
111112
i"${sym.showLocated} is accessed from super. It may not be abstract unless it is overridden by a member declared `abstract' and `override'",
112113
sel.pos)
114+
else println(i"ok super $sel ${sym.showLocated} $member $clazz ${member.isIncompleteIn(clazz)}")
113115
}
114116
else if (mix == tpnme.EMPTY && !(sym.owner is Trait))
115117
// SI-4989 Check if an intermediate class between `clazz` and `sym.owner` redeclares the method as abstract.

test/dotc/tests.scala

+1
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ class tests extends CompilerTest {
9696

9797
@Test def new_all = compileFiles(newDir, twice)
9898

99+
@Test def neg_abstractOverride() = compileFile(negDir, "abstract-override", xerrors = 2)
99100
@Test def neg_blockescapes() = compileFile(negDir, "blockescapesNeg", xerrors = 1)
100101
@Test def neg_typedapply() = compileFile(negDir, "typedapply", xerrors = 4)
101102
@Test def neg_typedidents() = compileFile(negDir, "typedIdents", xerrors = 2)

tests/neg/abstract-override.scala

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
trait T { def foo: Int }
2+
trait T1 extends T { override def foo = super.foo }
3+
trait T2 extends T { override def foo = super.foo }
4+
object Test extends T2 with T1 {
5+
def main(args: Array[String]) = {
6+
assert(foo == 3)
7+
}
8+
}

tests/run/i756.scala

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
trait T { def foo: Int = 3 }
2+
trait T1 extends T { override def foo = super.foo }
3+
trait T2 extends T { override def foo = super.foo }
4+
object Test extends T2 with T1 {
5+
def main(args: Array[String]) = {
6+
assert(foo == 3)
7+
}
8+
}

0 commit comments

Comments
 (0)