Skip to content

Commit b3d0c47

Browse files
committed
Handle superAccessors in the presence of @TargetNAME
1 parent 8f16a33 commit b3d0c47

File tree

6 files changed

+96
-16
lines changed

6 files changed

+96
-16
lines changed

compiler/src/dotty/tools/dotc/core/SymDenotations.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,9 @@ object SymDenotations {
522522
then carrier.unforcedAnnotation(defn.TargetNameAnnot)
523523
else carrier.getAnnotation(defn.TargetNameAnnot)
524524
myTargetName = computeTargetName(targetNameAnnot)
525+
if name.is(SuperAccessorName) then
526+
myTargetName = myTargetName.unmangle(List(ExpandedName, SuperAccessorName, ExpandPrefixName))
527+
525528
myTargetName
526529

527530
// ----- Tests -------------------------------------------------

compiler/src/dotty/tools/dotc/reporting/messages.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2204,7 +2204,7 @@ import transform.SymUtils._
22042204
def explain = ""
22052205
}
22062206

2207-
class IllegalSuperAccessor(base: Symbol, memberName: Name,
2207+
class IllegalSuperAccessor(base: Symbol, memberName: Name, targetName: Name,
22082208
acc: Symbol, accTp: Type,
22092209
other: Symbol, otherTp: Type)(using Context) extends DeclarationMsg(IllegalSuperAccessorID) {
22102210
def msg = {
@@ -2220,7 +2220,8 @@ import transform.SymUtils._
22202220
// does in classes, i.e. followed the linearization of the trait itself.
22212221
val staticSuperCall = {
22222222
val staticSuper = accMixin.asClass.info.parents.reverse
2223-
.find(_.nonPrivateMember(memberName).matchingDenotation(accMixin.thisType, acc.info).exists)
2223+
.find(_.nonPrivateMember(memberName)
2224+
.matchingDenotation(accMixin.thisType, acc.info, targetName).exists)
22242225
val staticSuperName = staticSuper match {
22252226
case Some(parent) =>
22262227
parent.classSymbol.name.show

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

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -82,20 +82,24 @@ object ResolveSuper {
8282
var bcs = base.info.baseClasses.dropWhile(acc.owner != _).tail
8383
var sym: Symbol = NoSymbol
8484

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
85+
def decomposeSuperName(superName: Name): (Name, TypeName) =
86+
superName.unexpandedName match
87+
case SuperAccessorName(ExpandPrefixName(name, mixName)) =>
88+
(name, mixName.toTypeName)
89+
case SuperAccessorName(name) =>
90+
(name, EmptyTypeName)
91+
92+
val (memberName, mix) = decomposeSuperName(acc.name.unexpandedName)
93+
val targetName =
94+
if acc.name == acc.erasedName then memberName
95+
else decomposeSuperName(acc.erasedName)._1
9296

9397
report.debuglog(i"starting rebindsuper from $base of ${acc.showLocated}: ${acc.info} in $bcs, name = $memberName")
9498

9599
while (bcs.nonEmpty && sym == NoSymbol) {
96100
val other = bcs.head.info.nonPrivateDecl(memberName)
97101
.filterWithPredicate(denot => mix.isEmpty || denot.symbol.owner.name == mix)
98-
.matchingDenotation(base.thisType, base.thisType.memberInfo(acc))
102+
.matchingDenotation(base.thisType, base.thisType.memberInfo(acc), targetName)
99103
report.debuglog(i"rebindsuper ${bcs.head} $other deferred = ${other.symbol.is(Deferred)}")
100104
if other.exists && !other.symbol.is(Deferred) then
101105
sym = other.symbol
@@ -104,11 +108,11 @@ object ResolveSuper {
104108
val otherTp = other.asSeenFrom(base.typeRef).info
105109
val accTp = acc.asSeenFrom(base.typeRef).info
106110
if (!(otherTp.overrides(accTp, matchLoosely = true)))
107-
report.error(IllegalSuperAccessor(base, memberName, acc, accTp, other.symbol, otherTp), base.srcPos)
111+
report.error(IllegalSuperAccessor(base, memberName, targetName, acc, accTp, other.symbol, otherTp), base.srcPos)
108112

109113
bcs = bcs.tail
110114
}
111-
assert(sym.exists)
115+
assert(sym.exists, i"cannot rebind $acc, ${acc.erasedName} $memberName")
112116
sym
113117
}
114118
}

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

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import ValueClasses.isMethodWithExtension
88
import core._
99
import Contexts._, Flags._, Symbols._, Names._, StdNames._, NameOps._, Trees._
1010
import TypeUtils._, SymUtils._
11+
import Constants.Constant
12+
import Annotations.Annotation
1113
import DenotTransformers.DenotTransformer
1214
import Symbols._
1315
import util.Spans._
@@ -67,11 +69,15 @@ class SuperAccessors(thisPhase: DenotTransformer) {
6769
val Select(qual, name) = sel
6870
val sym = sel.symbol
6971
val clazz = qual.symbol.asClass
70-
val preName = if (mixName.isEmpty) name.toTermName else ExpandPrefixName(name.toTermName, mixName.toTermName)
71-
var superName = SuperAccessorName(preName)
72-
if (clazz.is(Trait)) superName = superName.expandedName(clazz)
73-
val superInfo = sel.tpe.widenSingleton.ensureMethodic
7472

73+
def superAccessorName(original: Name) =
74+
val unexpanded = SuperAccessorName(
75+
if mixName.isEmpty then original.toTermName
76+
else ExpandPrefixName(original.toTermName, mixName.toTermName))
77+
if clazz.is(Trait) then unexpanded.expandedName(clazz) else unexpanded
78+
79+
val superName = superAccessorName(name)
80+
val superInfo = sel.tpe.widenSingleton.ensureMethodic
7581
val accRange = sel.span.focus
7682
val superAcc = clazz.info.decl(superName)
7783
.suchThat(_.signature == superInfo.signature).symbol
@@ -81,6 +87,10 @@ class SuperAccessors(thisPhase: DenotTransformer) {
8187
val acc = newSymbol(
8288
clazz, superName, Artifact | Method | maybeDeferred,
8389
superInfo, coord = accRange).enteredAfter(thisPhase)
90+
if !Denotations.targetNamesMatch(sym.name, sym.erasedName) then
91+
acc.addAnnotation(
92+
Annotation(defn.TargetNameAnnot,
93+
Literal(Constant(superAccessorName(sym.erasedName).toString)).withSpan(sym.span)))
8494
// Diagnostic for SI-7091
8595
if (!accDefs.contains(clazz))
8696
report.error(
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
C1A1A2B1B2C2
2+
C1B3B4C3
3+
IT
4+
AT
5+
ER
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import annotation.targetName
2+
3+
trait A {
4+
@targetName("foo2") def foo = 1
5+
}
6+
7+
trait B {
8+
@targetName("foo2") def foo = 2
9+
}
10+
11+
class C extends A with B {
12+
@targetName("foo2") override def foo = super[A].foo + super[B].foo
13+
}
14+
15+
class Base[A](exp: => Option[A])
16+
17+
object Empty extends Base[Nothing](None)
18+
19+
20+
trait B1 extends C1 { @targetName("f2") override def f() = { super.f(); print("B1") }}
21+
trait B2 extends B1 { @targetName("f2") override def f() = { super.f(); print("B2") }}
22+
trait A1 extends C1 { @targetName("f2") override def f() = { super.f(); print("A1") }}
23+
trait A2 extends A1 { @targetName("f2") override def f() = { super.f(); print("A2") }}
24+
class C1 { @targetName("f2") def f() = print("C1") }
25+
class C2 extends A2 with B2 { @targetName("f2") override def f() = { super.f(); print("C2") }}
26+
27+
28+
trait B3 extends C1 { @targetName("f2") override def f() = { super.f(); print("B3") }}
29+
trait B4 extends C1 { this: B3 => @targetName("f2") override def f() = { super.f(); print("B4") }}
30+
class C3 extends C1 with B3 with B4 { @targetName("f2") override def f() = { super.f(); print("C3") }}
31+
32+
trait DT {
33+
@targetName("f2") def f(): Unit
34+
}
35+
trait IT extends DT {
36+
@targetName("f2") def f() = { println("IT") }
37+
}
38+
abstract class MPT {
39+
}
40+
trait AT extends MPT with DT {
41+
@targetName("f2") abstract override def f() = { super.f(); println("AT") }
42+
}
43+
class ER extends MPT with IT with AT {
44+
@targetName("f2") override def f() = { super.f(); println("ER") }
45+
}
46+
47+
object Test {
48+
def main(args: Array[String]): Unit = {
49+
assert(new C().foo == 3)
50+
new C2().f()
51+
println()
52+
new C3().f()
53+
println()
54+
new ER().f()
55+
Empty
56+
}
57+
}

0 commit comments

Comments
 (0)