@@ -196,10 +196,27 @@ object TypeErasure {
196196 MethodType (Nil , defn.BoxedUnitType )
197197 else if (sym.isAnonymousFunction && einfo.paramInfos.length > MaxImplementedFunctionArity )
198198 MethodType (nme.ALLARGS :: Nil , JavaArrayType (defn.ObjectType ) :: Nil , einfo.resultType)
199+ else if (sym.name == nme.apply && sym.owner.derivesFrom(defn.PolyFunctionClass )) {
200+ // The erasure of `apply` in subclasses of PolyFunction has to match
201+ // the erasure of FunctionN#apply, since after `ElimPolyFunction` we replace
202+ // a `PolyFunction` parent by a `FunctionN` parent.
203+ einfo.derivedLambdaType(
204+ paramInfos = einfo.paramInfos.map(_ => defn.ObjectType ),
205+ resType = defn.ObjectType
206+ )
207+ }
199208 else
200209 einfo
201210 case einfo =>
202- einfo
211+ // Erase the parameters of `apply` in subclasses of PolyFunction
212+ // Preserve PolyFunction argument types to support PolyFunctions with
213+ // PolyFunction arguments
214+ if (sym.is(TermParam ) && sym.owner.name == nme.apply
215+ && sym.owner.owner.derivesFrom(defn.PolyFunctionClass )
216+ && ! (tp <:< defn.PolyFunctionType )) {
217+ defn.ObjectType
218+ } else
219+ einfo
203220 }
204221 }
205222
@@ -383,6 +400,7 @@ class TypeErasure(isJava: Boolean, semiEraseVCs: Boolean, isConstructor: Boolean
383400 * - otherwise, if T is a type parameter coming from Java, []Object
384401 * - otherwise, Object
385402 * - For a term ref p.x, the type <noprefix> # x.
403+ * - For a refined type scala.PolyFunction { def apply[...](x_1, ..., x_N): R }, scala.FunctionN
386404 * - For a typeref scala.Any, scala.AnyVal, scala.Singleton, scala.Tuple, or scala.*: : |java.lang.Object|
387405 * - For a typeref scala.Unit, |scala.runtime.BoxedUnit|.
388406 * - For a typeref scala.FunctionN, where N > MaxImplementedFunctionArity, scala.FunctionXXL
@@ -429,6 +447,12 @@ class TypeErasure(isJava: Boolean, semiEraseVCs: Boolean, isConstructor: Boolean
429447 SuperType (this (thistpe), this (supertpe))
430448 case ExprType (rt) =>
431449 defn.FunctionType (0 )
450+ case RefinedType (parent, nme.apply, refinedInfo) if parent.typeSymbol eq defn.PolyFunctionClass =>
451+ assert(refinedInfo.isInstanceOf [PolyType ])
452+ val res = refinedInfo.resultType
453+ val paramss = res.paramNamess
454+ assert(paramss.length == 1 )
455+ this (defn.FunctionType (paramss.head.length, isContextual = res.isImplicitMethod, isErased = res.isErasedMethod))
432456 case tp : TypeProxy =>
433457 this (tp.underlying)
434458 case AndType (tp1, tp2) =>
@@ -581,6 +605,11 @@ class TypeErasure(isJava: Boolean, semiEraseVCs: Boolean, isConstructor: Boolean
581605 case tp : TypeVar =>
582606 val inst = tp.instanceOpt
583607 if (inst.exists) sigName(inst) else tpnme.Uninstantiated
608+ case tp @ RefinedType (parent, nme.apply, _) if parent.typeSymbol eq defn.PolyFunctionClass =>
609+ // we need this case rather than falling through to the default
610+ // because RefinedTypes <: TypeProxy and it would be caught by
611+ // the case immediately below
612+ sigName(this (tp))
584613 case tp : TypeProxy =>
585614 sigName(tp.underlying)
586615 case _ : ErrorType | WildcardType | NoType =>
0 commit comments