@@ -1115,7 +1115,7 @@ class Definitions {
11151115 FunctionType (args.length, isContextual).appliedTo(args ::: resultType :: Nil )
11161116 def unapply (ft : Type )(using Context ): Option [(List [Type ], Type , Boolean )] = {
11171117 ft.dealias match
1118- case RefinedType (parent, nme.apply, mt : MethodType ) if isErasedFunctionType(parent ) =>
1118+ case ErasedFunctionOf (mt ) =>
11191119 Some (mt.paramInfos, mt.resType, mt.isContextualMethod)
11201120 case _ =>
11211121 val tsym = ft.dealias.typeSymbol
@@ -1127,6 +1127,42 @@ class Definitions {
11271127 }
11281128 }
11291129
1130+ object PolyOrErasedFunctionOf {
1131+ /** Matches a refined `PolyFunction` or `ErasedFunction` type and extracts the apply info.
1132+ *
1133+ * Pattern: `(PolyFunction | ErasedFunction) { def apply: $mt }`
1134+ */
1135+ def unapply (ft : Type )(using Context ): Option [MethodicType ] = ft.dealias match
1136+ case RefinedType (parent, nme.apply, mt : MethodicType )
1137+ if parent.derivesFrom(defn.PolyFunctionClass ) || parent.derivesFrom(defn.ErasedFunctionClass ) =>
1138+ Some (mt)
1139+ case _ => None
1140+ }
1141+
1142+ object PolyFunctionOf {
1143+ /** Matches a refined `PolyFunction` type and extracts the apply info.
1144+ *
1145+ * Pattern: `PolyFunction { def apply: $pt }`
1146+ */
1147+ def unapply (ft : Type )(using Context ): Option [PolyType ] = ft.dealias match
1148+ case RefinedType (parent, nme.apply, pt : PolyType )
1149+ if parent.derivesFrom(defn.PolyFunctionClass ) =>
1150+ Some (pt)
1151+ case _ => None
1152+ }
1153+
1154+ object ErasedFunctionOf {
1155+ /** Matches a refined `ErasedFunction` type and extracts the apply info.
1156+ *
1157+ * Pattern: `ErasedFunction { def apply: $mt }`
1158+ */
1159+ def unapply (ft : Type )(using Context ): Option [MethodType ] = ft.dealias match
1160+ case RefinedType (parent, nme.apply, mt : MethodType )
1161+ if parent.derivesFrom(defn.ErasedFunctionClass ) =>
1162+ Some (mt)
1163+ case _ => None
1164+ }
1165+
11301166 object PartialFunctionOf {
11311167 def apply (arg : Type , result : Type )(using Context ): Type =
11321168 PartialFunctionClass .typeRef.appliedTo(arg :: result :: Nil )
@@ -1714,26 +1750,16 @@ class Definitions {
17141750 def isFunctionNType (tp : Type )(using Context ): Boolean =
17151751 isNonRefinedFunction(tp.dropDependentRefinement)
17161752
1717- /** Does `tp` derive from `PolyFunction` or `ErasedFunction`? */
1718- def isPolyOrErasedFunctionType (tp : Type )(using Context ): Boolean =
1719- isPolyFunctionType(tp) || isErasedFunctionType(tp)
1720-
1721- /** Does `tp` derive from `PolyFunction`? */
1722- def isPolyFunctionType (tp : Type )(using Context ): Boolean =
1723- tp.derivesFrom(defn.PolyFunctionClass )
1724-
1725- /** Does `tp` derive from `ErasedFunction`? */
1726- def isErasedFunctionType (tp : Type )(using Context ): Boolean =
1727- tp.derivesFrom(defn.ErasedFunctionClass )
1728-
17291753 /** Returns whether `tp` is an instance or a refined instance of:
17301754 * - scala.FunctionN
17311755 * - scala.ContextFunctionN
17321756 * - ErasedFunction
17331757 * - PolyFunction
17341758 */
17351759 def isFunctionType (tp : Type )(using Context ): Boolean =
1736- isFunctionNType(tp) || isPolyOrErasedFunctionType(tp)
1760+ isFunctionNType(tp)
1761+ || tp.derivesFrom(defn.PolyFunctionClass ) // TODO check for refinement?
1762+ || tp.derivesFrom(defn.ErasedFunctionClass ) // TODO check for refinement?
17371763
17381764 private def withSpecMethods (cls : ClassSymbol , bases : List [Name ], paramTypes : Set [TypeRef ]) =
17391765 if ! ctx.settings.Yscala2Stdlib .value then
@@ -1837,7 +1863,7 @@ class Definitions {
18371863 tp.stripTypeVar.dealias match
18381864 case tp1 : TypeParamRef if ctx.typerState.constraint.contains(tp1) =>
18391865 asContextFunctionType(TypeComparer .bounds(tp1).hiBound)
1840- case tp1 @ RefinedType (parent, nme.apply, mt : MethodType ) if isErasedFunctionType(parent) && mt.isContextualMethod =>
1866+ case tp1 @ ErasedFunctionOf (mt ) if mt.isContextualMethod =>
18411867 tp1
18421868 case tp1 =>
18431869 if tp1.typeSymbol.name.isContextFunction && isFunctionNType(tp1) then tp1
@@ -1857,7 +1883,7 @@ class Definitions {
18571883 atPhase(erasurePhase)(unapply(tp))
18581884 else
18591885 asContextFunctionType(tp) match
1860- case RefinedType (parent, nme.apply, mt : MethodType ) if isErasedFunctionType(parent ) =>
1886+ case ErasedFunctionOf (mt ) =>
18611887 Some ((mt.paramInfos, mt.resType, mt.erasedParams))
18621888 case tp1 if tp1.exists =>
18631889 val args = tp1.functionArgInfos
@@ -1867,7 +1893,7 @@ class Definitions {
18671893
18681894 /* Returns a list of erased booleans marking whether parameters are erased, for a function type. */
18691895 def erasedFunctionParameters (tp : Type )(using Context ): List [Boolean ] = tp.dealias match {
1870- case RefinedType (parent, nme.apply, mt : MethodType ) => mt.erasedParams
1896+ case ErasedFunctionOf (mt ) => mt.erasedParams
18711897 case tp if isFunctionNType(tp) => List .fill(functionArity(tp)) { false }
18721898 case _ => Nil
18731899 }
0 commit comments