@@ -48,11 +48,7 @@ class MixinOps(cls: ClassSymbol, thisTransform: DenotTransformer)(implicit ctx:
4848 * - there are multiple traits defining method with same signature
4949 */
5050 def needsForwarder (meth : Symbol ): Boolean = {
51- lazy val competingMethods = cls.baseClasses.iterator
52- .filter(_ ne meth.owner)
53- .map(meth.overriddenSymbol)
54- .filter(_.exists)
55- .toList
51+ lazy val competingMethods = competingMethodsIterator(meth).toList
5652
5753 def needsDisambiguation = competingMethods.exists(x=> ! (x is Deferred )) // multiple implementations are available
5854 def hasNonInterfaceDefinition = competingMethods.exists(! _.owner.is(Trait )) // there is a definition originating from class
@@ -61,8 +57,34 @@ class MixinOps(cls: ClassSymbol, thisTransform: DenotTransformer)(implicit ctx:
6157 (needsDisambiguation || hasNonInterfaceDefinition || meth.owner.is(Scala2x ))
6258 }
6359
60+ /** Get `sym` of the method that needs a forwarder
61+ * Method needs a forwarder in those cases:
62+ * - there is a trait that defines a primitive version of implemented polymorphic method.
63+ * - there is a trait that defines a polymorphic version of implemented primitive method.
64+ */
65+ def needsPrimitiveForwarderTo (meth : Symbol ): Option [Symbol ] = {
66+ def hasPrimitiveMissMatch (tp1 : Type , tp2 : Type ): Boolean = (tp1, tp2) match {
67+ case (tp1 : MethodicType , tp2 : MethodicType ) => hasPrimitiveMissMatch(tp1.resultType, tp2.resultType)
68+ case _ => tp1.typeSymbol.isPrimitiveValueClass ^ tp2.typeSymbol.isPrimitiveValueClass
69+ }
70+
71+ def needsPrimitiveForwarder (m : Symbol ): Boolean =
72+ m.owner != cls && ! m.is(Deferred ) && hasPrimitiveMissMatch(meth.info, m.info)
73+
74+ if (! meth.is(Method | Deferred , butNot = PrivateOrAccessor ) || meth.overriddenSymbol(cls).exists || needsForwarder(meth)) None
75+ else competingMethodsIterator(meth).find(needsPrimitiveForwarder)
76+ }
77+
78+ final val PrivateOrAccessor = Private | Accessor
6479 final val PrivateOrAccessorOrDeferred = Private | Accessor | Deferred
6580
6681 def forwarder (target : Symbol ) = (targs : List [Type ]) => (vrefss : List [List [Tree ]]) =>
6782 superRef(target).appliedToTypes(targs).appliedToArgss(vrefss)
83+
84+ private def competingMethodsIterator (meth : Symbol ): Iterator [Symbol ] = {
85+ cls.baseClasses.iterator
86+ .filter(_ ne meth.owner)
87+ .map(meth.overriddenSymbol)
88+ .filter(_.exists)
89+ }
6890}
0 commit comments