Skip to content

Commit 53bbf95

Browse files
committed
Emit a static forwarder when a bridge overrides a non-deferred method
This seems to match the behavior of Scala 2.13 and more importantly it will be needed after the next commit that emits mixin forwarders as bridges, otherwise `extends App` won't work. Also make sure that we never emit a bridge that overrides nothing, this happened for FunctionXXL and lead to NoDenotation errors with the backend changes in this commit.
1 parent 01bebd7 commit 53bbf95

File tree

5 files changed

+15
-4
lines changed

5 files changed

+15
-4
lines changed

compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,8 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters {
388388
}
389389
debuglog(s"Potentially conflicting names for forwarders: $conflictingNames")
390390

391-
for (m <- moduleClass.info.membersBasedOnFlags(ExcludedForwarderFlags, Flag_METHOD)) {
391+
for (m0 <- moduleClass.info.membersBasedOnFlags(ExcludedForwarderFlags, Flag_METHOD)) {
392+
val m = if (m0.isBridge) m0.nextOverriddenSymbol else m0
392393
if (m.isType || m.isDeferred || (m.owner eq ObjectClass) || m.isConstructor || m.isExpanded)
393394
debuglog(s"No forwarder for '$m' from $jclassName to '$moduleClass'")
394395
else if (conflictingNames(m.name))

compiler/src/dotty/tools/backend/jvm/BackendInterface.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,7 @@ abstract class BackendInterface extends BackendInterfaceDefinitions {
537537
def companionSymbol: Symbol
538538
def moduleClass: Symbol
539539
def enclosingClassSym: Symbol
540-
540+
def nextOverriddenSymbol: Symbol
541541

542542

543543
// members

compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
431431
val Flag_METHOD: Flags = Flags.Method.bits
432432
val ExcludedForwarderFlags: Flags = {
433433
Flags.Specialized | Flags.Lifted | Flags.Protected | Flags.JavaStatic |
434-
Flags.Bridge | Flags.Private | Flags.Macro
434+
Flags.Private | Flags.Macro
435435
}.bits
436436

437437
def isQualifierSafeToElide(qual: Tree): Boolean = tpd.isIdempotentExpr(qual)
@@ -765,6 +765,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
765765
}
766766
else sym.enclosingClass(ctx.withPhase(ctx.flattenPhase.prev))
767767
} //todo is handled specially for JavaDefined symbols in scalac
768+
def nextOverriddenSymbol: Symbol = toDenot(sym).nextOverriddenSymbol
768769

769770
// members
770771
def primaryConstructor: Symbol = toDenot(sym).primaryConstructor

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1140,6 +1140,15 @@ object SymDenotations {
11401140
if (!canMatchInheritedSymbols) Iterator.empty
11411141
else overriddenFromType(owner.info)
11421142

1143+
/** Equivalent to `allOverriddenSymbols.headOption.getOrElse(NoSymbol)` but more efficient. */
1144+
final def nextOverriddenSymbol(implicit ctx: Context): Symbol = {
1145+
val overridden = allOverriddenSymbols
1146+
if (overridden.hasNext)
1147+
overridden.next
1148+
else
1149+
NoSymbol
1150+
}
1151+
11431152
/** Returns all matching symbols defined in parents of the selftype. */
11441153
final def extendedOverriddenSymbols(implicit ctx: Context): Iterator[Symbol] =
11451154
if (!canMatchInheritedSymbols) Iterator.empty

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ class Bridges(root: ClassSymbol, thisPhase: DenotTransformer)(implicit ctx: Cont
117117
val opc = new BridgesCursor()(preErasureCtx)
118118
val ectx = ctx.withPhase(thisPhase)
119119
while (opc.hasNext) {
120-
if (!opc.overriding.is(Deferred)) {
120+
if (!opc.overriding.is(Deferred) && root.derivesFrom(opc.overridden.owner)) {
121121
addBridgeIfNeeded(opc.overriding, opc.overridden)
122122

123123
if (needsImplicitShortcut(opc.overriding)(ectx) && needsImplicitShortcut(opc.overridden)(ectx))

0 commit comments

Comments
 (0)