Skip to content

Commit 1a83575

Browse files
committed
Mixin: create less forwarders.
There were two sources of inefficiency in previous scheme: - if symbol was no overriding anything the forwarder was still being created - the class that is will have the forwarder was not considered. Many methods do not require forwarders as JVM will dispatch correctly.
1 parent 474c0a2 commit 1a83575

File tree

1 file changed

+14
-4
lines changed

1 file changed

+14
-4
lines changed

src/dotty/tools/dotc/transform/MixinOps.scala

+14-4
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,21 @@ class MixinOps(cls: ClassSymbol, thisTransform: DenotTransformer)(implicit ctx:
4141
ctx.atPhase(thisTransform) { implicit ctx =>
4242
cls.info.member(sym.name).hasAltWith(_.symbol == sym)
4343
}
44-
44+
45+
/** Does `method` need a forwarder to in class `cls`
46+
* Method needs a forwarder in those cases:
47+
* - there's a class defining a method with same signature
48+
* - there are multiple traits defining method with same signature
49+
*/
4550
def needsForwarder(meth: Symbol): Boolean = {
46-
lazy val overridenSymbols = meth.allOverriddenSymbols
47-
def needsDisambiguation = !overridenSymbols.forall(_ is Deferred)
48-
def hasNonInterfaceDefinition = overridenSymbols.forall(!_.owner.is(Trait))
51+
lazy val competingMethods = cls.baseClasses.iterator
52+
.filter(_ ne meth.owner)
53+
.map(meth.overriddenSymbol)
54+
.filter(_.exists)
55+
.toList
56+
57+
def needsDisambiguation = competingMethods.exists(x=> !(x is Deferred)) // multiple implementations are available
58+
def hasNonInterfaceDefinition = competingMethods.exists(!_.owner.is(Trait)) // there is a definition originating from class
4959
meth.is(Method, butNot = PrivateOrAccessorOrDeferred) &&
5060
isCurrent(meth) &&
5161
(needsDisambiguation || hasNonInterfaceDefinition || meth.owner.is(Scala2x))

0 commit comments

Comments
 (0)