@@ -1061,6 +1061,40 @@ object desugar {
1061
1061
name
1062
1062
}
1063
1063
1064
+ /** Strip parens and empty blocks around the body of `tree`. */
1065
+ def normalizePolyFunction (tree : PolyFunction )(using Context ): PolyFunction =
1066
+ def stripped (body : Tree ): Tree = body match
1067
+ case Parens (body1) =>
1068
+ stripped(body1)
1069
+ case Block (Nil , body1) =>
1070
+ stripped(body1)
1071
+ case _ => body
1072
+ cpy.PolyFunction (tree)(tree.targs, stripped(tree.body)).asInstanceOf [PolyFunction ]
1073
+
1074
+ /** Desugar [T_1, ..., T_M] => (P_1, ..., P_N) => R
1075
+ * Into scala.PolyFunction { def apply[T_1, ..., T_M](x$1: P_1, ..., x$N: P_N): R }
1076
+ */
1077
+ def makePolyFunctionType (tree : PolyFunction )(using Context ): RefinedTypeTree =
1078
+ val PolyFunction (tparams : List [untpd.TypeDef ] @ unchecked, fun @ untpd.Function (vparamTypes, res)) = tree : @ unchecked
1079
+ val funFlags = fun match
1080
+ case fun : FunctionWithMods =>
1081
+ fun.mods.flags
1082
+ case _ => EmptyFlags
1083
+
1084
+ // TODO: make use of this in the desugaring when pureFuns is enabled.
1085
+ // val isImpure = funFlags.is(Impure)
1086
+
1087
+ // Function flags to be propagated to each parameter in the desugared method type.
1088
+ val paramFlags = funFlags.toTermFlags & Given
1089
+ val vparams = vparamTypes.zipWithIndex.map:
1090
+ case (p : ValDef , _) => p.withAddedFlags(paramFlags)
1091
+ case (p, n) => makeSyntheticParameter(n + 1 , p).withAddedFlags(paramFlags)
1092
+
1093
+ RefinedTypeTree (ref(defn.PolyFunctionType ), List (
1094
+ DefDef (nme.apply, tparams :: vparams :: Nil , res, EmptyTree ).withFlags(Synthetic )
1095
+ )).withSpan(tree.span)
1096
+ end makePolyFunctionType
1097
+
1064
1098
/** Invent a name for an anonympus given of type or template `impl`. */
1065
1099
def inventGivenOrExtensionName (impl : Tree )(using Context ): SimpleName =
1066
1100
val str = impl match
@@ -1454,14 +1488,17 @@ object desugar {
1454
1488
}
1455
1489
1456
1490
/** Make closure corresponding to function.
1457
- * params => body
1491
+ * [tparams] => params => body
1458
1492
* ==>
1459
- * def $anonfun(params) = body
1493
+ * def $anonfun[tparams] (params) = body
1460
1494
* Closure($anonfun)
1461
1495
*/
1462
- def makeClosure (params : List [ValDef ], body : Tree , tpt : Tree | Null = null , span : Span )(using Context ): Block =
1496
+ def makeClosure (tparams : List [TypeDef ], vparams : List [ValDef ], body : Tree , tpt : Tree | Null = null , span : Span )(using Context ): Block =
1497
+ val paramss : List [ParamClause ] =
1498
+ if tparams.isEmpty then vparams :: Nil
1499
+ else tparams :: vparams :: Nil
1463
1500
Block (
1464
- DefDef (nme.ANON_FUN , params :: Nil , if (tpt == null ) TypeTree () else tpt, body)
1501
+ DefDef (nme.ANON_FUN , paramss , if (tpt == null ) TypeTree () else tpt, body)
1465
1502
.withSpan(span)
1466
1503
.withMods(synthetic | Artifact ),
1467
1504
Closure (Nil , Ident (nme.ANON_FUN ), EmptyTree ))
@@ -1753,56 +1790,6 @@ object desugar {
1753
1790
}
1754
1791
}
1755
1792
1756
- def makePolyFunction (targs : List [Tree ], body : Tree , pt : Type ): Tree = body match {
1757
- case Parens (body1) =>
1758
- makePolyFunction(targs, body1, pt)
1759
- case Block (Nil , body1) =>
1760
- makePolyFunction(targs, body1, pt)
1761
- case Function (vargs, res) =>
1762
- assert(targs.nonEmpty)
1763
- // TODO: Figure out if we need a `PolyFunctionWithMods` instead.
1764
- val mods = body match {
1765
- case body : FunctionWithMods => body.mods
1766
- case _ => untpd.EmptyModifiers
1767
- }
1768
- val polyFunctionTpt = ref(defn.PolyFunctionType )
1769
- val applyTParams = targs.asInstanceOf [List [TypeDef ]]
1770
- if (ctx.mode.is(Mode .Type )) {
1771
- // Desugar [T_1, ..., T_M] -> (P_1, ..., P_N) => R
1772
- // Into scala.PolyFunction { def apply[T_1, ..., T_M](x$1: P_1, ..., x$N: P_N): R }
1773
-
1774
- val applyVParams = vargs.zipWithIndex.map {
1775
- case (p : ValDef , _) => p.withAddedFlags(mods.flags)
1776
- case (p, n) => makeSyntheticParameter(n + 1 , p).withAddedFlags(mods.flags.toTermFlags)
1777
- }
1778
- RefinedTypeTree (polyFunctionTpt, List (
1779
- DefDef (nme.apply, applyTParams :: applyVParams :: Nil , res, EmptyTree ).withFlags(Synthetic )
1780
- ))
1781
- }
1782
- else {
1783
- // Desugar [T_1, ..., T_M] -> (x_1: P_1, ..., x_N: P_N) => body
1784
- // with pt [S_1, ..., S_M] -> (O_1, ..., O_N) => R
1785
- // Into new scala.PolyFunction { def apply[T_1, ..., T_M](x_1: P_1, ..., x_N: P_N): R2 = body }
1786
- // where R2 is R, with all references to S_1..S_M replaced with T1..T_M.
1787
-
1788
- def typeTree (tp : Type ) = tp match
1789
- case RefinedType (parent, nme.apply, poly @ PolyType (_, mt : MethodType )) if parent.classSymbol eq defn.PolyFunctionClass =>
1790
- untpd.DependentTypeTree ((tsyms, vsyms) =>
1791
- mt.resultType.substParams(mt, vsyms.map(_.termRef)).substParams(poly, tsyms.map(_.typeRef)))
1792
- case _ => TypeTree ()
1793
-
1794
- val applyVParams = vargs.asInstanceOf [List [ValDef ]]
1795
- .map(varg => varg.withAddedFlags(mods.flags | Param ))
1796
- New (Template (emptyConstructor, List (polyFunctionTpt), Nil , EmptyValDef ,
1797
- List (DefDef (nme.apply, applyTParams :: applyVParams :: Nil , typeTree(pt), res))
1798
- ))
1799
- }
1800
- case _ =>
1801
- // may happen for erroneous input. An error will already have been reported.
1802
- assert(ctx.reporter.errorsReported)
1803
- EmptyTree
1804
- }
1805
-
1806
1793
// begin desugar
1807
1794
1808
1795
// Special case for `Parens` desugaring: unlike all the desugarings below,
@@ -1815,8 +1802,6 @@ object desugar {
1815
1802
}
1816
1803
1817
1804
val desugared = tree match {
1818
- case PolyFunction (targs, body) =>
1819
- makePolyFunction(targs, body, pt) orElse tree
1820
1805
case SymbolLit (str) =>
1821
1806
Apply (
1822
1807
ref(defn.ScalaSymbolClass .companionModule.termRef),
0 commit comments