@@ -1114,7 +1114,7 @@ class Definitions {
11141114 FunctionType (args.length, isContextual).appliedTo(args ::: resultType :: Nil )
11151115 def unapply (ft : Type )(using Context ): Option [(List [Type ], Type , Boolean )] = {
11161116 ft.dealias match
1117- case RefinedType (parent, nme.apply, mt : MethodType ) if isErasedFunctionType(parent ) =>
1117+ case ErasedFunctionOf (mt ) =>
11181118 Some (mt.paramInfos, mt.resType, mt.isContextualMethod)
11191119 case _ =>
11201120 val tsym = ft.dealias.typeSymbol
@@ -1126,6 +1126,42 @@ class Definitions {
11261126 }
11271127 }
11281128
1129+ object PolyOrErasedFunctionOf {
1130+ /** Matches a refined `PolyFunction` or `ErasedFunction` type and extracts the apply info.
1131+ *
1132+ * Pattern: `(PolyFunction | ErasedFunction) { def apply: $mt }`
1133+ */
1134+ def unapply (ft : Type )(using Context ): Option [MethodicType ] = ft.dealias match
1135+ case RefinedType (parent, nme.apply, mt : MethodicType )
1136+ if parent.derivesFrom(defn.PolyFunctionClass ) || parent.derivesFrom(defn.ErasedFunctionClass ) =>
1137+ Some (mt)
1138+ case _ => None
1139+ }
1140+
1141+ object PolyFunctionOf {
1142+ /** Matches a refined `PolyFunction` type and extracts the apply info.
1143+ *
1144+ * Pattern: `PolyFunction { def apply: $pt }`
1145+ */
1146+ def unapply (ft : Type )(using Context ): Option [PolyType ] = ft.dealias match
1147+ case RefinedType (parent, nme.apply, pt : PolyType )
1148+ if parent.derivesFrom(defn.PolyFunctionClass ) =>
1149+ Some (pt)
1150+ case _ => None
1151+ }
1152+
1153+ object ErasedFunctionOf {
1154+ /** Matches a refined `ErasedFunction` type and extracts the apply info.
1155+ *
1156+ * Pattern: `ErasedFunction { def apply: $mt }`
1157+ */
1158+ def unapply (ft : Type )(using Context ): Option [MethodType ] = ft.dealias match
1159+ case RefinedType (parent, nme.apply, mt : MethodType )
1160+ if parent.derivesFrom(defn.ErasedFunctionClass ) =>
1161+ Some (mt)
1162+ case _ => None
1163+ }
1164+
11291165 object PartialFunctionOf {
11301166 def apply (arg : Type , result : Type )(using Context ): Type =
11311167 PartialFunctionClass .typeRef.appliedTo(arg :: result :: Nil )
@@ -1713,26 +1749,16 @@ class Definitions {
17131749 def isFunctionNType (tp : Type )(using Context ): Boolean =
17141750 isNonRefinedFunction(tp.dropDependentRefinement)
17151751
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 )
1727-
17281752 /** Returns whether `tp` is an instance or a refined instance of:
17291753 * - scala.FunctionN
17301754 * - scala.ContextFunctionN
17311755 * - ErasedFunction
17321756 * - PolyFunction
17331757 */
17341758 def isFunctionType (tp : Type )(using Context ): Boolean =
1735- isFunctionNType(tp) || isPolyOrErasedFunctionType(tp)
1759+ isFunctionNType(tp)
1760+ || tp.derivesFrom(defn.PolyFunctionClass ) // TODO check for refinement?
1761+ || tp.derivesFrom(defn.ErasedFunctionClass ) // TODO check for refinement?
17361762
17371763 private def withSpecMethods (cls : ClassSymbol , bases : List [Name ], paramTypes : Set [TypeRef ]) =
17381764 if ! ctx.settings.Yscala2Stdlib .value then
@@ -1836,7 +1862,7 @@ class Definitions {
18361862 tp.stripTypeVar.dealias match
18371863 case tp1 : TypeParamRef if ctx.typerState.constraint.contains(tp1) =>
18381864 asContextFunctionType(TypeComparer .bounds(tp1).hiBound)
1839- case tp1 @ RefinedType (parent, nme.apply, mt : MethodType ) if isErasedFunctionType(parent) && mt.isContextualMethod =>
1865+ case tp1 @ ErasedFunctionOf (mt ) if mt.isContextualMethod =>
18401866 tp1
18411867 case tp1 =>
18421868 if tp1.typeSymbol.name.isContextFunction && isFunctionNType(tp1) then tp1
@@ -1856,7 +1882,7 @@ class Definitions {
18561882 atPhase(erasurePhase)(unapply(tp))
18571883 else
18581884 asContextFunctionType(tp) match
1859- case RefinedType (parent, nme.apply, mt : MethodType ) if isErasedFunctionType(parent ) =>
1885+ case ErasedFunctionOf (mt ) =>
18601886 Some ((mt.paramInfos, mt.resType, mt.erasedParams))
18611887 case tp1 if tp1.exists =>
18621888 val args = tp1.functionArgInfos
@@ -1866,7 +1892,7 @@ class Definitions {
18661892
18671893 /* Returns a list of erased booleans marking whether parameters are erased, for a function type. */
18681894 def erasedFunctionParameters (tp : Type )(using Context ): List [Boolean ] = tp.dealias match {
1869- case RefinedType (parent, nme.apply, mt : MethodType ) => mt.erasedParams
1895+ case ErasedFunctionOf (mt ) => mt.erasedParams
18701896 case tp if isFunctionNType(tp) => List .fill(functionArity(tp)) { false }
18711897 case _ => Nil
18721898 }
0 commit comments