@@ -1108,7 +1108,7 @@ class Definitions {
11081108 FunctionType (args.length, isContextual).appliedTo(args ::: resultType :: Nil )
11091109 def unapply (ft : Type )(using Context ): Option [(List [Type ], Type , Boolean )] = {
11101110 ft.dealias match
1111- case RefinedType (parent, nme.apply, mt : MethodType ) if isErasedFunctionType(parent ) =>
1111+ case ErasedFunctionOf (mt ) =>
11121112 Some (mt.paramInfos, mt.resType, mt.isContextualMethod)
11131113 case _ =>
11141114 val tsym = ft.dealias.typeSymbol
@@ -1120,6 +1120,42 @@ class Definitions {
11201120 }
11211121 }
11221122
1123+ object PolyOrErasedFunctionOf {
1124+ /** Matches a refined `PolyFunction` or `ErasedFunction` type and extracts the apply info.
1125+ *
1126+ * Pattern: `(PolyFunction | ErasedFunction) { def apply: $mt }`
1127+ */
1128+ def unapply (ft : Type )(using Context ): Option [MethodicType ] = ft.dealias match
1129+ case RefinedType (parent, nme.apply, mt : MethodicType )
1130+ if parent.derivesFrom(defn.PolyFunctionClass ) || parent.derivesFrom(defn.ErasedFunctionClass ) =>
1131+ Some (mt)
1132+ case _ => None
1133+ }
1134+
1135+ object PolyFunctionOf {
1136+ /** Matches a refined `PolyFunction` type and extracts the apply info.
1137+ *
1138+ * Pattern: `PolyFunction { def apply: $pt }`
1139+ */
1140+ def unapply (ft : Type )(using Context ): Option [PolyType ] = ft.dealias match
1141+ case RefinedType (parent, nme.apply, pt : PolyType )
1142+ if parent.derivesFrom(defn.PolyFunctionClass ) =>
1143+ Some (pt)
1144+ case _ => None
1145+ }
1146+
1147+ object ErasedFunctionOf {
1148+ /** Matches a refined `ErasedFunction` type and extracts the apply info.
1149+ *
1150+ * Pattern: `ErasedFunction { def apply: $mt }`
1151+ */
1152+ def unapply (ft : Type )(using Context ): Option [MethodType ] = ft.dealias match
1153+ case RefinedType (parent, nme.apply, mt : MethodType )
1154+ if parent.derivesFrom(defn.ErasedFunctionClass ) =>
1155+ Some (mt)
1156+ case _ => None
1157+ }
1158+
11231159 object PartialFunctionOf {
11241160 def apply (arg : Type , result : Type )(using Context ): Type =
11251161 PartialFunctionClass .typeRef.appliedTo(arg :: result :: Nil )
@@ -1705,26 +1741,16 @@ class Definitions {
17051741 def isFunctionNType (tp : Type )(using Context ): Boolean =
17061742 isNonRefinedFunction(tp.dropDependentRefinement)
17071743
1708- /** Does `tp` derive from `PolyFunction` or `ErasedFunction`? */
1709- def isPolyOrErasedFunctionType (tp : Type )(using Context ): Boolean =
1710- isPolyFunctionType(tp) || isErasedFunctionType(tp)
1711-
1712- /** Does `tp` derive from `PolyFunction`? */
1713- def isPolyFunctionType (tp : Type )(using Context ): Boolean =
1714- tp.derivesFrom(defn.PolyFunctionClass )
1715-
1716- /** Does `tp` derive from `ErasedFunction`? */
1717- def isErasedFunctionType (tp : Type )(using Context ): Boolean =
1718- tp.derivesFrom(defn.ErasedFunctionClass )
1719-
17201744 /** Returns whether `tp` is an instance or a refined instance of:
17211745 * - scala.FunctionN
17221746 * - scala.ContextFunctionN
17231747 * - ErasedFunction
17241748 * - PolyFunction
17251749 */
17261750 def isFunctionType (tp : Type )(using Context ): Boolean =
1727- isFunctionNType(tp) || isPolyOrErasedFunctionType(tp)
1751+ isFunctionNType(tp)
1752+ || tp.derivesFrom(defn.PolyFunctionClass ) // TODO check for refinement?
1753+ || tp.derivesFrom(defn.ErasedFunctionClass ) // TODO check for refinement?
17281754
17291755 private def withSpecMethods (cls : ClassSymbol , bases : List [Name ], paramTypes : Set [TypeRef ]) =
17301756 for base <- bases; tp <- paramTypes do
@@ -1825,7 +1851,7 @@ class Definitions {
18251851 tp.stripTypeVar.dealias match
18261852 case tp1 : TypeParamRef if ctx.typerState.constraint.contains(tp1) =>
18271853 asContextFunctionType(TypeComparer .bounds(tp1).hiBound)
1828- case tp1 @ RefinedType (parent, nme.apply, mt : MethodType ) if isErasedFunctionType(parent) && mt.isContextualMethod =>
1854+ case tp1 @ ErasedFunctionOf (mt ) if mt.isContextualMethod =>
18291855 tp1
18301856 case tp1 =>
18311857 if tp1.typeSymbol.name.isContextFunction && isFunctionNType(tp1) then tp1
@@ -1845,7 +1871,7 @@ class Definitions {
18451871 atPhase(erasurePhase)(unapply(tp))
18461872 else
18471873 asContextFunctionType(tp) match
1848- case RefinedType (parent, nme.apply, mt : MethodType ) if isErasedFunctionType(parent ) =>
1874+ case ErasedFunctionOf (mt ) =>
18491875 Some ((mt.paramInfos, mt.resType, mt.erasedParams))
18501876 case tp1 if tp1.exists =>
18511877 val args = tp1.functionArgInfos
@@ -1855,7 +1881,7 @@ class Definitions {
18551881
18561882 /* Returns a list of erased booleans marking whether parameters are erased, for a function type. */
18571883 def erasedFunctionParameters (tp : Type )(using Context ): List [Boolean ] = tp.dealias match {
1858- case RefinedType (parent, nme.apply, mt : MethodType ) => mt.erasedParams
1884+ case ErasedFunctionOf (mt ) => mt.erasedParams
18591885 case tp if isFunctionNType(tp) => List .fill(functionArity(tp)) { false }
18601886 case _ => Nil
18611887 }
0 commit comments