Skip to content

Commit 967aefc

Browse files
authored
Refactor function type logic (#18193)
* Rename `isFucntionType` to `isFunctionNType` (tests for FunctionN/ContextFunctionN) * Rename `isFunctionOrPolyType` to `isFunctionType` (tests for FunctionN/ContextFunctionN/PolyFunction/ErasedFunction) * Rename `isRefinedFunctionType` to `isPolyOrErasedFunctionType` (tests for PolyFunction/ErasedFunction) * Define `isPolyFunctionType` * Refactor uses of `isPolyFunctionType`/`isErasedFunctionType`/`isPolyOrErasedFunctionType` * Simplify/generalize erasure of refined function types Followup of dotty-staging@6a349b5#r121364261
2 parents fd8bcea + 21818e7 commit 967aefc

19 files changed

+100
-101
lines changed

compiler/src/dotty/tools/dotc/ast/TreeInfo.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -968,7 +968,7 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
968968
&& tree.isTerm
969969
&& {
970970
val qualType = tree.qualifier.tpe
971-
hasRefinement(qualType) && !defn.isRefinedFunctionType(qualType)
971+
hasRefinement(qualType) && !defn.isPolyOrErasedFunctionType(qualType)
972972
}
973973
def loop(tree: Tree): Boolean = tree match
974974
case TypeApply(fun, _) =>

compiler/src/dotty/tools/dotc/cc/CheckCaptures.scala

+6-6
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ class CheckCaptures extends Recheck, SymTransformer:
187187
capt.println(i"solving $t")
188188
refs.solve()
189189
traverse(parent)
190-
case t @ RefinedType(_, nme.apply, rinfo) if defn.isFunctionOrPolyType(t) =>
190+
case t @ RefinedType(_, nme.apply, rinfo) if defn.isFunctionType(t) =>
191191
traverse(rinfo)
192192
case tp: TypeVar =>
193193
case tp: TypeRef =>
@@ -638,7 +638,7 @@ class CheckCaptures extends Recheck, SymTransformer:
638638
case expected @ CapturingType(eparent, refs) =>
639639
CapturingType(recur(eparent), refs, boxed = expected.isBoxed)
640640
case expected @ defn.FunctionOf(args, resultType, isContextual)
641-
if defn.isNonRefinedFunction(expected) && defn.isFunctionType(actual) && !defn.isNonRefinedFunction(actual) =>
641+
if defn.isNonRefinedFunction(expected) && defn.isFunctionNType(actual) && !defn.isNonRefinedFunction(actual) =>
642642
val expected1 = toDepFun(args, resultType, isContextual)
643643
expected1
644644
case _ =>
@@ -707,7 +707,7 @@ class CheckCaptures extends Recheck, SymTransformer:
707707
val (eargs, eres) = expected.dealias.stripCapturing match
708708
case defn.FunctionOf(eargs, eres, _) => (eargs, eres)
709709
case expected: MethodType => (expected.paramInfos, expected.resType)
710-
case expected @ RefinedType(_, _, rinfo: MethodType) if defn.isFunctionType(expected) => (rinfo.paramInfos, rinfo.resType)
710+
case expected @ RefinedType(_, _, rinfo: MethodType) if defn.isFunctionNType(expected) => (rinfo.paramInfos, rinfo.resType)
711711
case _ => (aargs.map(_ => WildcardType), WildcardType)
712712
val aargs1 = aargs.zipWithConserve(eargs) { (aarg, earg) => adapt(aarg, earg, !covariant) }
713713
val ares1 = adapt(ares, eres, covariant)
@@ -769,7 +769,7 @@ class CheckCaptures extends Recheck, SymTransformer:
769769
case actual @ AppliedType(tycon, args) if defn.isNonRefinedFunction(actual) =>
770770
adaptFun(actual, args.init, args.last, expected, covariant, insertBox,
771771
(aargs1, ares1) => actual.derivedAppliedType(tycon, aargs1 :+ ares1))
772-
case actual @ RefinedType(_, _, rinfo: MethodType) if defn.isFunctionOrPolyType(actual) =>
772+
case actual @ RefinedType(_, _, rinfo: MethodType) if defn.isFunctionType(actual) =>
773773
// TODO Find a way to combine handling of generic and dependent function types (here and elsewhere)
774774
adaptFun(actual, rinfo.paramInfos, rinfo.resType, expected, covariant, insertBox,
775775
(aargs1, ares1) =>
@@ -779,7 +779,7 @@ class CheckCaptures extends Recheck, SymTransformer:
779779
adaptFun(actual, actual.paramInfos, actual.resType, expected, covariant, insertBox,
780780
(aargs1, ares1) =>
781781
actual.derivedLambdaType(paramInfos = aargs1, resType = ares1))
782-
case actual @ RefinedType(p, nme, rinfo: PolyType) if defn.isFunctionOrPolyType(actual) =>
782+
case actual @ RefinedType(p, nme, rinfo: PolyType) if defn.isFunctionType(actual) =>
783783
adaptTypeFun(actual, rinfo.resType, expected, covariant, insertBox,
784784
ares1 =>
785785
val rinfo1 = rinfo.derivedLambdaType(rinfo.paramNames, rinfo.paramInfos, ares1)
@@ -996,7 +996,7 @@ class CheckCaptures extends Recheck, SymTransformer:
996996
case CapturingType(parent, refs) =>
997997
healCaptureSet(refs)
998998
traverse(parent)
999-
case tp @ RefinedType(parent, rname, rinfo: MethodType) if defn.isFunctionOrPolyType(tp) =>
999+
case tp @ RefinedType(parent, rname, rinfo: MethodType) if defn.isFunctionType(tp) =>
10001000
traverse(rinfo)
10011001
case tp: TermLambda =>
10021002
val saved = allowed

compiler/src/dotty/tools/dotc/cc/Setup.scala

+3-3
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ extends tpd.TreeTraverser:
5454
val boxedRes = recur(res)
5555
if boxedRes eq res then tp
5656
else tp1.derivedAppliedType(tycon, args.init :+ boxedRes)
57-
case tp1 @ RefinedType(_, _, rinfo: MethodType) if defn.isFunctionOrPolyType(tp1) =>
57+
case tp1 @ RefinedType(_, _, rinfo: MethodType) if defn.isFunctionType(tp1) =>
5858
val boxedRinfo = recur(rinfo)
5959
if boxedRinfo eq rinfo then tp
6060
else boxedRinfo.toFunctionType(isJava = false, alwaysDependent = true)
@@ -231,7 +231,7 @@ extends tpd.TreeTraverser:
231231
tp.derivedAppliedType(tycon1, args1 :+ res1)
232232
else
233233
tp.derivedAppliedType(tycon1, args.mapConserve(arg => this(arg)))
234-
case tp @ RefinedType(core, rname, rinfo: MethodType) if defn.isFunctionOrPolyType(tp) =>
234+
case tp @ RefinedType(core, rname, rinfo: MethodType) if defn.isFunctionType(tp) =>
235235
val rinfo1 = apply(rinfo)
236236
if rinfo1 ne rinfo then rinfo1.toFunctionType(isJava = false, alwaysDependent = true)
237237
else tp
@@ -329,7 +329,7 @@ extends tpd.TreeTraverser:
329329
args.last, CaptureSet.empty, currentCs ++ outerCs)
330330
tp.derivedAppliedType(tycon1, args1 :+ resType1)
331331
tp1.capturing(outerCs)
332-
case tp @ RefinedType(parent, nme.apply, rinfo: MethodType) if defn.isFunctionOrPolyType(tp) =>
332+
case tp @ RefinedType(parent, nme.apply, rinfo: MethodType) if defn.isFunctionType(tp) =>
333333
propagateDepFunctionResult(mapOver(tp), currentCs ++ outerCs)
334334
.capturing(outerCs)
335335
case _ =>

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

+17-11
Original file line numberDiff line numberDiff line change
@@ -1475,6 +1475,7 @@ class Definitions {
14751475
def PolyFunctionType = PolyFunctionClass.typeRef
14761476

14771477
lazy val ErasedFunctionClass = requiredClass("scala.runtime.ErasedFunction")
1478+
def ErasedFunctionType = ErasedFunctionClass.typeRef
14781479

14791480
/** If `cls` is a class in the scala package, its name, otherwise EmptyTypeName */
14801481
def scalaClassName(cls: Symbol)(using Context): TypeName = cls.denot match
@@ -1709,21 +1710,29 @@ class Definitions {
17091710
* - scala.FunctionN
17101711
* - scala.ContextFunctionN
17111712
*/
1712-
def isFunctionType(tp: Type)(using Context): Boolean =
1713+
def isFunctionNType(tp: Type)(using Context): Boolean =
17131714
isNonRefinedFunction(tp.dropDependentRefinement)
17141715

1715-
/** Is `tp` a specialized, refined function type? Either an `ErasedFunction` or a `PolyFunction`. */
1716-
def isRefinedFunctionType(tp: Type)(using Context): Boolean =
1717-
tp.derivesFrom(defn.PolyFunctionClass) || isErasedFunctionType(tp)
1716+
/** Does `tp` derive from `PolyFunction` or `ErasedFunction`? */
1717+
def isPolyOrErasedFunctionType(tp: Type)(using Context): Boolean =
1718+
isPolyFunctionType(tp) || isErasedFunctionType(tp)
1719+
1720+
/** Does `tp` derive from `PolyFunction`? */
1721+
def isPolyFunctionType(tp: Type)(using Context): Boolean =
1722+
tp.derivesFrom(defn.PolyFunctionClass)
1723+
1724+
/** Does `tp` derive from `ErasedFunction`? */
1725+
def isErasedFunctionType(tp: Type)(using Context): Boolean =
1726+
tp.derivesFrom(defn.ErasedFunctionClass)
17181727

17191728
/** Returns whether `tp` is an instance or a refined instance of:
17201729
* - scala.FunctionN
17211730
* - scala.ContextFunctionN
17221731
* - ErasedFunction
17231732
* - PolyFunction
17241733
*/
1725-
def isFunctionOrPolyType(tp: Type)(using Context): Boolean =
1726-
isFunctionType(tp) || isRefinedFunctionType(tp)
1734+
def isFunctionType(tp: Type)(using Context): Boolean =
1735+
isFunctionNType(tp) || isPolyOrErasedFunctionType(tp)
17271736

17281737
private def withSpecMethods(cls: ClassSymbol, bases: List[Name], paramTypes: Set[TypeRef]) =
17291738
if !ctx.settings.Yscala2Stdlib.value then
@@ -1830,7 +1839,7 @@ class Definitions {
18301839
case tp1 @ RefinedType(parent, nme.apply, mt: MethodType) if isErasedFunctionType(parent) && mt.isContextualMethod =>
18311840
tp1
18321841
case tp1 =>
1833-
if tp1.typeSymbol.name.isContextFunction && isFunctionType(tp1) then tp1
1842+
if tp1.typeSymbol.name.isContextFunction && isFunctionNType(tp1) then tp1
18341843
else NoType
18351844

18361845
/** Is `tp` an context function type? */
@@ -1858,13 +1867,10 @@ class Definitions {
18581867
/* Returns a list of erased booleans marking whether parameters are erased, for a function type. */
18591868
def erasedFunctionParameters(tp: Type)(using Context): List[Boolean] = tp.dealias match {
18601869
case RefinedType(parent, nme.apply, mt: MethodType) => mt.erasedParams
1861-
case tp if isFunctionType(tp) => List.fill(functionArity(tp)) { false }
1870+
case tp if isFunctionNType(tp) => List.fill(functionArity(tp)) { false }
18621871
case _ => Nil
18631872
}
18641873

1865-
def isErasedFunctionType(tp: Type)(using Context): Boolean =
1866-
tp.derivesFrom(defn.ErasedFunctionClass)
1867-
18681874
/** A whitelist of Scala-2 classes that are known to be pure */
18691875
def isAssuredNoInits(sym: Symbol): Boolean =
18701876
(sym `eq` SomeClass) || isTupleClass(sym)

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

+1-2
Original file line numberDiff line numberDiff line change
@@ -509,8 +509,7 @@ class TypeApplications(val self: Type) extends AnyVal {
509509
* Handles `ErasedFunction`s and poly functions gracefully.
510510
*/
511511
final def functionArgInfos(using Context): List[Type] = self.dealias match
512-
case RefinedType(parent, nme.apply, mt: MethodType) if defn.isErasedFunctionType(parent) => (mt.paramInfos :+ mt.resultType)
513-
case RefinedType(parent, nme.apply, mt: MethodType) if parent.typeSymbol eq defn.PolyFunctionClass => (mt.paramInfos :+ mt.resultType)
512+
case RefinedType(parent, nme.apply, mt: MethodType) if defn.isPolyOrErasedFunctionType(parent) => (mt.paramInfos :+ mt.resultType)
514513
case _ => self.dropDependentRefinement.dealias.argInfos
515514

516515
/** Argument types where existential types in arguments are disallowed */

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

+11-9
Original file line numberDiff line numberDiff line change
@@ -666,15 +666,17 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
666666
isSubType(info1, info2)
667667

668668
if defn.isFunctionType(tp2) then
669-
tp1w.widenDealias match
670-
case tp1: RefinedType =>
671-
return isSubInfo(tp1.refinedInfo, tp2.refinedInfo)
672-
case _ =>
673-
else if tp2.parent.typeSymbol == defn.PolyFunctionClass then
674-
tp1.member(nme.apply).info match
675-
case info1: PolyType =>
676-
return isSubInfo(info1, tp2.refinedInfo)
677-
case _ =>
669+
if defn.isPolyFunctionType(tp2) then
670+
// TODO should we handle ErasedFunction is this same way?
671+
tp1.member(nme.apply).info match
672+
case info1: PolyType =>
673+
return isSubInfo(info1, tp2.refinedInfo)
674+
case _ =>
675+
else
676+
tp1w.widenDealias match
677+
case tp1: RefinedType =>
678+
return isSubInfo(tp1.refinedInfo, tp2.refinedInfo)
679+
case _ =>
678680

679681
val skipped2 = skipMatching(tp1w, tp2)
680682
if (skipped2 eq tp2) || !Config.fastPathForRefinedSubtype then

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

+14-23
Original file line numberDiff line numberDiff line change
@@ -560,21 +560,16 @@ object TypeErasure {
560560
case _ => false
561561
}
562562

563-
/** The erasure of `PolyFunction { def apply: $applyInfo }` */
564-
def erasePolyFunctionApply(applyInfo: Type)(using Context): Type =
565-
assert(applyInfo.isInstanceOf[PolyType])
566-
val res = applyInfo.resultType
567-
val paramss = res.paramNamess
568-
assert(paramss.length == 1)
569-
erasure(defn.FunctionType(paramss.head.length,
570-
isContextual = res.isImplicitMethod))
571-
572-
def eraseErasedFunctionApply(erasedFn: MethodType)(using Context): Type =
573-
val fnType = defn.FunctionType(
574-
n = erasedFn.erasedParams.count(_ == false),
575-
isContextual = erasedFn.isContextualMethod,
576-
)
577-
erasure(fnType)
563+
/** The erasure of `(PolyFunction | ErasedFunction) { def apply: $applyInfo }` */
564+
def eraseRefinedFunctionApply(applyInfo: Type)(using Context): Type =
565+
def functionType(info: Type): Type = info match {
566+
case info: PolyType =>
567+
functionType(info.resultType)
568+
case info: MethodType =>
569+
assert(!info.resultType.isInstanceOf[MethodicType])
570+
defn.FunctionType(n = info.erasedParams.count(_ == false))
571+
}
572+
erasure(functionType(applyInfo))
578573
}
579574

580575
import TypeErasure._
@@ -592,7 +587,7 @@ import TypeErasure._
592587
*/
593588
class TypeErasure(sourceLanguage: SourceLanguage, semiEraseVCs: Boolean, isConstructor: Boolean, isSymbol: Boolean, inSigName: Boolean) {
594589

595-
/** The erasure |T| of a type T.
590+
/** The erasure |T| of a type T.
596591
*
597592
* If computing the erasure of T requires erasing a WildcardType or an
598593
* uninstantiated type variable, then an exception signaling an internal
@@ -659,10 +654,8 @@ class TypeErasure(sourceLanguage: SourceLanguage, semiEraseVCs: Boolean, isConst
659654
else SuperType(eThis, eSuper)
660655
case ExprType(rt) =>
661656
defn.FunctionType(0)
662-
case RefinedType(parent, nme.apply, refinedInfo) if parent.typeSymbol eq defn.PolyFunctionClass =>
663-
erasePolyFunctionApply(refinedInfo)
664-
case RefinedType(parent, nme.apply, refinedInfo: MethodType) if defn.isErasedFunctionType(parent) =>
665-
eraseErasedFunctionApply(refinedInfo)
657+
case RefinedType(parent, nme.apply, refinedInfo) if defn.isPolyOrErasedFunctionType(parent) =>
658+
eraseRefinedFunctionApply(refinedInfo)
666659
case tp: TypeVar if !tp.isInstantiated =>
667660
assert(inSigName, i"Cannot erase uninstantiated type variable $tp")
668661
WildcardType
@@ -943,13 +936,11 @@ class TypeErasure(sourceLanguage: SourceLanguage, semiEraseVCs: Boolean, isConst
943936
sigName(defn.FunctionOf(Nil, rt))
944937
case tp: TypeVar if !tp.isInstantiated =>
945938
tpnme.Uninstantiated
946-
case tp @ RefinedType(parent, nme.apply, _) if parent.typeSymbol eq defn.PolyFunctionClass =>
939+
case tp @ RefinedType(parent, nme.apply, _) if defn.isPolyOrErasedFunctionType(parent) =>
947940
// we need this case rather than falling through to the default
948941
// because RefinedTypes <: TypeProxy and it would be caught by
949942
// the case immediately below
950943
sigName(this(tp))
951-
case tp @ RefinedType(parent, nme.apply, refinedInfo) if defn.isErasedFunctionType(parent) =>
952-
sigName(this(tp))
953944
case tp: TypeProxy =>
954945
sigName(tp.underlying)
955946
case tp: WildcardType =>

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

+22-17
Original file line numberDiff line numberDiff line change
@@ -708,7 +708,7 @@ object Types {
708708
}
709709
findMember(name, pre, required, excluded)
710710
}
711-
711+
712712
/** The implicit members with given name. If there are none and the denotation
713713
* contains private members, also look for shadowed non-private implicits.
714714
*/
@@ -1875,20 +1875,25 @@ object Types {
18751875
* @param alwaysDependent if true, always create a dependent function type.
18761876
*/
18771877
def toFunctionType(isJava: Boolean, dropLast: Int = 0, alwaysDependent: Boolean = false)(using Context): Type = this match {
1878-
case mt: MethodType if !mt.isParamDependent =>
1879-
val formals1 = if (dropLast == 0) mt.paramInfos else mt.paramInfos dropRight dropLast
1880-
val isContextual = mt.isContextualMethod && !ctx.erasedTypes
1881-
val result1 = mt.nonDependentResultApprox match {
1882-
case res: MethodType => res.toFunctionType(isJava)
1883-
case res => res
1884-
}
1885-
val funType = defn.FunctionOf(
1886-
formals1 mapConserve (_.translateFromRepeated(toArray = isJava)),
1887-
result1, isContextual)
1888-
if alwaysDependent || mt.isResultDependent then
1889-
RefinedType(funType, nme.apply, mt)
1890-
else funType
1891-
case poly @ PolyType(_, mt: MethodType) if !mt.isParamDependent =>
1878+
case mt: MethodType =>
1879+
assert(!mt.isParamDependent)
1880+
def nonDependentFunType =
1881+
val formals1 = if (dropLast == 0) mt.paramInfos else mt.paramInfos dropRight dropLast
1882+
val isContextual = mt.isContextualMethod && !ctx.erasedTypes
1883+
val result1 = mt.nonDependentResultApprox match {
1884+
case res: MethodType => res.toFunctionType(isJava)
1885+
case res => res
1886+
}
1887+
defn.FunctionOf(
1888+
formals1 mapConserve (_.translateFromRepeated(toArray = isJava)),
1889+
result1, isContextual)
1890+
if mt.hasErasedParams then
1891+
RefinedType(defn.ErasedFunctionType, nme.apply, mt)
1892+
else if alwaysDependent || mt.isResultDependent then
1893+
RefinedType(nonDependentFunType, nme.apply, mt)
1894+
else nonDependentFunType
1895+
case poly @ PolyType(_, mt: MethodType) =>
1896+
assert(!mt.isParamDependent)
18921897
RefinedType(defn.PolyFunctionType, nme.apply, poly)
18931898
}
18941899

@@ -4071,9 +4076,9 @@ object Types {
40714076
def addInto(tp: Type): Type = tp match
40724077
case tp @ AppliedType(tycon, args) if tycon.typeSymbol == defn.RepeatedParamClass =>
40734078
tp.derivedAppliedType(tycon, addInto(args.head) :: Nil)
4074-
case tp @ AppliedType(tycon, args) if defn.isFunctionType(tp) =>
4079+
case tp @ AppliedType(tycon, args) if defn.isFunctionNType(tp) =>
40754080
wrapConvertible(tp.derivedAppliedType(tycon, args.init :+ addInto(args.last)))
4076-
case tp @ RefinedType(parent, rname, rinfo) if defn.isFunctionOrPolyType(tp) =>
4081+
case tp @ RefinedType(parent, rname, rinfo) if defn.isFunctionType(tp) =>
40774082
wrapConvertible(tp.derivedRefinedType(parent, rname, addInto(rinfo)))
40784083
case tp: MethodOrPoly =>
40794084
tp.derivedLambdaType(resType = addInto(tp.resType))

compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
266266
if !printDebug && appliedText(tp.asInstanceOf[HKLambda].resType).isEmpty =>
267267
// don't eta contract if the application would be printed specially
268268
toText(tycon)
269-
case tp: RefinedType if defn.isFunctionOrPolyType(tp) && !printDebug =>
269+
case tp: RefinedType if defn.isFunctionType(tp) && !printDebug =>
270270
toTextMethodAsFunction(tp.refinedInfo,
271271
isPure = Feature.pureFunsEnabled && !tp.typeSymbol.name.isImpureFunction)
272272
case tp: TypeRef =>
@@ -771,7 +771,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
771771
override protected def toTextCapturing(tp: Type, refsText: Text, boxText: Text): Text = tp match
772772
case tp: AppliedType if defn.isFunctionSymbol(tp.typeSymbol) && !printDebug =>
773773
boxText ~ toTextFunction(tp, refsText)
774-
case tp: RefinedType if defn.isFunctionOrPolyType(tp) && !printDebug =>
774+
case tp: RefinedType if defn.isFunctionType(tp) && !printDebug =>
775775
boxText ~ toTextMethodAsFunction(tp.refinedInfo, isPure = !tp.typeSymbol.name.isImpureFunction, refsText)
776776
case _ =>
777777
super.toTextCapturing(tp, refsText, boxText)

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ object BetaReduce:
9090
recur(expr, argss)
9191
case _ => None
9292
tree match
93-
case Apply(Select(fn, nme.apply), args) if defn.isFunctionType(fn.tpe) =>
93+
case Apply(Select(fn, nme.apply), args) if defn.isFunctionNType(fn.tpe) =>
9494
recur(fn, List(args)) match
9595
case Some(reduced) =>
9696
seq(bindingsBuf.result(), reduced).withSpan(tree.span)

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

+2-4
Original file line numberDiff line numberDiff line change
@@ -679,10 +679,8 @@ object Erasure {
679679
// Instead, we manually lookup the type of `apply` in the qualifier.
680680
inContext(preErasureCtx) {
681681
val qualTp = tree.qualifier.typeOpt.widen
682-
if qualTp.derivesFrom(defn.PolyFunctionClass) then
683-
erasePolyFunctionApply(qualTp.select(nme.apply).widen).classSymbol
684-
else if defn.isErasedFunctionType(qualTp) then
685-
eraseErasedFunctionApply(qualTp.select(nme.apply).widen.asInstanceOf[MethodType]).classSymbol
682+
if defn.isPolyOrErasedFunctionType(qualTp) then
683+
eraseRefinedFunctionApply(qualTp.select(nme.apply).widen).classSymbol
686684
else
687685
NoSymbol
688686
}

0 commit comments

Comments
 (0)