Skip to content

Commit 6ad49e9

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.
1 parent 01bebd7 commit 6ad49e9

File tree

4 files changed

+17
-4
lines changed

4 files changed

+17
-4
lines changed

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -388,8 +388,11 @@ 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)) {
392-
if (m.isType || m.isDeferred || (m.owner eq ObjectClass) || m.isConstructor || m.isExpanded)
391+
for (m0 <- moduleClass.info.membersBasedOnFlags(ExcludedForwarderFlags, Flag_METHOD)) {
392+
val m = if (m0.isBridge) m0.nextOverriddenSymbol else m0
393+
if (m == NoSymbol)
394+
log(s"$m0 is a bridge method that overrides nothing, something went wrong in a previous phase.")
395+
else if (m.isType || m.isDeferred || (m.owner eq ObjectClass) || m.isConstructor || m.isExpanded)
393396
debuglog(s"No forwarder for '$m' from $jclassName to '$moduleClass'")
394397
else if (conflictingNames(m.name))
395398
log(s"No forwarder for $m due to conflict with ${linkedClass.info.member(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

0 commit comments

Comments
 (0)