Skip to content

Commit

Permalink
Merge pull request scala#767 from dotty-staging/fix-#756-super-accessors
Browse files Browse the repository at this point in the history
Fix scala#756 super accessors
  • Loading branch information
DarkDimius committed Aug 28, 2015
2 parents 6ccd6b5 + 4689bd3 commit fbc1609
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 4 deletions.
5 changes: 5 additions & 0 deletions src/dotty/tools/dotc/core/NameOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,11 @@ object NameOps {

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

/** Revert the expanded name. Note: This currently gives incorrect results
* if the normal name contains `nme.EXPAND_SEPARATOR`, i.e. two consecutive '$'
* signs. This can happen for instance if a super accessor is paired with
* an encoded name, e.g. super$$plus$eq. See #765.
*/
def unexpandedName: N = {
val idx = name.lastIndexOfSlice(nme.EXPAND_SEPARATOR)
if (idx < 0) name else (name drop (idx + nme.EXPAND_SEPARATOR.length)).asInstanceOf[N]
Expand Down
8 changes: 7 additions & 1 deletion src/dotty/tools/dotc/transform/ResolveSuper.scala
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,13 @@ class ResolveSuper extends MiniPhaseTransform with IdentityDenotTransformer { th
private def rebindSuper(base: Symbol, acc: Symbol)(implicit ctx: Context): Symbol = {
var bcs = base.info.baseClasses.dropWhile(acc.owner != _).tail
var sym: Symbol = NoSymbol
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
val unexpandedAccName =
if (acc.is(ExpandedName)) // Cannot use unexpandedName because of #765. t2183.scala would fail if we did.
acc.name
.drop(acc.name.indexOfSlice(nme.EXPAND_SEPARATOR ++ nme.SUPER_PREFIX))
.drop(nme.EXPAND_SEPARATOR.length)
else acc.name
val SuperAccessorName(memberName) = unexpandedAccName: Name // dotty deviation: ": Name" needed otherwise pattern type is neither a subtype nor a supertype of selector type
ctx.debuglog(i"starting rebindsuper from $base of ${acc.showLocated}: ${acc.info} in $bcs, name = $memberName")
while (bcs.nonEmpty && sym == NoSymbol) {
val other = bcs.head.info.nonPrivateDecl(memberName)
Expand Down
8 changes: 5 additions & 3 deletions src/dotty/tools/dotc/transform/SuperAccessors.scala
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,12 @@ class SuperAccessors(thisTransformer: DenotTransformer) {
val Select(qual, name) = sel
val sym = sel.symbol
val clazz = qual.symbol.asClass
val supername = name.superName
var supername = name.superName
if (clazz is Trait) supername = supername.expandedName(clazz)

val superAcc = clazz.info.decl(supername).suchThat(_.signature == sym.signature).symbol orElse {
ctx.debuglog(s"add super acc ${sym.showLocated} to $clazz")
val deferredOrPrivate = if (clazz is Trait) Deferred else Private
val deferredOrPrivate = if (clazz is Trait) Deferred | ExpandedName else Private
val acc = ctx.newSymbol(
clazz, supername, SuperAccessor | Artifact | Method | deferredOrPrivate,
sel.tpe.widenSingleton.ensureMethodic, coord = sym.coord).enteredAfter(thisTransformer)
Expand Down Expand Up @@ -106,10 +107,11 @@ class SuperAccessors(thisTransformer: DenotTransformer) {
val member = sym.overridingSymbol(clazz)
if (mix != tpnme.EMPTY ||
!member.exists ||
!(member is AbsOverride) && member.isIncompleteIn(clazz))
!((member is AbsOverride) && member.isIncompleteIn(clazz)))
ctx.error(
i"${sym.showLocated} is accessed from super. It may not be abstract unless it is overridden by a member declared `abstract' and `override'",
sel.pos)
else println(i"ok super $sel ${sym.showLocated} $member $clazz ${member.isIncompleteIn(clazz)}")
}
else if (mix == tpnme.EMPTY && !(sym.owner is Trait))
// SI-4989 Check if an intermediate class between `clazz` and `sym.owner` redeclares the method as abstract.
Expand Down
1 change: 1 addition & 0 deletions test/dotc/tests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ class tests extends CompilerTest {

@Test def new_all = compileFiles(newDir, twice)

@Test def neg_abstractOverride() = compileFile(negDir, "abstract-override", xerrors = 2)
@Test def neg_blockescapes() = compileFile(negDir, "blockescapesNeg", xerrors = 1)
@Test def neg_typedapply() = compileFile(negDir, "typedapply", xerrors = 4)
@Test def neg_typedidents() = compileFile(negDir, "typedIdents", xerrors = 2)
Expand Down
8 changes: 8 additions & 0 deletions tests/neg/abstract-override.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
trait T { def foo: Int }
trait T1 extends T { override def foo = super.foo }
trait T2 extends T { override def foo = super.foo }
object Test extends T2 with T1 {
def main(args: Array[String]) = {
assert(foo == 3)
}
}
8 changes: 8 additions & 0 deletions tests/run/i756.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
trait T { def foo: Int = 3 }
trait T1 extends T { override def foo = super.foo }
trait T2 extends T { override def foo = super.foo }
object Test extends T2 with T1 {
def main(args: Array[String]) = {
assert(foo == 3)
}
}

0 comments on commit fbc1609

Please sign in to comment.