Skip to content

Commit 5f9d66b

Browse files
committed
Alternative fix for #2099: Expand param forwarders early
Making param forwarders override the param they forward like we did in the previous commit changes semantics. Instead, we do the same thing that ExpandPrivate previously did, but early in ParamForwarding, so separate compilation still works.
1 parent 11254b3 commit 5f9d66b

File tree

1 file changed

+19
-8
lines changed

1 file changed

+19
-8
lines changed

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

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ package transform
44
import core._
55
import ast.Trees._
66
import Contexts._, Types._, Symbols._, Flags._, TypeUtils._, DenotTransformers._, StdNames._
7+
import Names._, NameOps._
78

89
/** For all parameter accessors
910
*
@@ -32,6 +33,8 @@ class ParamForwarding(thisTransformer: DenotTransformer) {
3233
}
3334
case _ => (Nil, Nil)
3435
}
36+
def findAccessor(cls: Symbol, name: Name): Symbol =
37+
cls.info.decl(name).suchThat(_ is (ParamAccessor, butNot = Mutable)).symbol
3538
def inheritedAccessor(sym: Symbol): Symbol = {
3639
/**
3740
* Dmitry: having it have the same name is needed to maintain correctness in presence of subclassing
@@ -44,9 +47,17 @@ class ParamForwarding(thisTransformer: DenotTransformer) {
4447
* def s = 3
4548
* assert(this.b == 2)
4649
* }
47-
*/
48-
val candidate = sym.owner.asClass.superClass
49-
.info.decl(sym.name).suchThat(_ is (ParamAccessor, butNot = (Mutable | Final))).symbol
50+
*/
51+
val superCls = sym.owner.asClass.superClass
52+
val candidate = {
53+
val candidate0 = findAccessor(superCls, sym.name)
54+
if (candidate0.exists)
55+
candidate0
56+
else
57+
// If a forwarder was private, it will have been name-mangled by `ensureNotPrivate`
58+
findAccessor(superCls, sym.name.expandedName(superCls))
59+
}
60+
5061
if (candidate.isAccessibleFrom(currentClass.thisType, superAccess = true)) candidate
5162
else if (candidate is Method) inheritedAccessor(candidate)
5263
else NoSymbol
@@ -63,10 +74,9 @@ class ParamForwarding(thisTransformer: DenotTransformer) {
6374
val alias = inheritedAccessor(sym)
6475
if (alias.exists) {
6576
def forwarder(implicit ctx: Context) = {
66-
// A private method cannot have the same name as an inherited non-private one,
67-
// so the forwarder should have the same access flags as the alias.
68-
val flags = (sym.flags &~ Private) | (alias.flags & AccessFlags) | Override | Method | Stable
77+
val flags = sym.flags | Method | Stable
6978
sym.copySymDenotation(initFlags = flags, info = sym.info.ensureMethodic)
79+
.ensureNotPrivate
7080
.installAfter(thisTransformer)
7181
val superAcc =
7282
Super(This(currentClass), tpnme.EMPTY, inConstrCall = false).select(alias)
@@ -89,9 +99,10 @@ class ParamForwarding(thisTransformer: DenotTransformer) {
8999
def adaptRef[T <: RefTree](tree: T)(implicit ctx: Context): T = tree.tpe match {
90100
case tpe: TermRefWithSignature
91101
if tpe.sig == Signature.NotAMethod && tpe.symbol.is(Method) =>
92-
// It's a param forwarder; adapt the signature
102+
// It's a param forwarder; adapt the signature and the name
103+
val name = tpe.symbol.asTerm.name
93104
tree.withType(
94-
TermRef.withSig(tpe.prefix, tpe.name, tpe.prefix.memberInfo(tpe.symbol).signature))
105+
TermRef.withSig(tpe.prefix, name, tpe.prefix.memberInfo(tpe.symbol).signature))
95106
.asInstanceOf[T]
96107
case _ =>
97108
tree

0 commit comments

Comments
 (0)