@@ -1020,6 +1020,40 @@ object desugar {
1020
1020
name
1021
1021
}
1022
1022
1023
+ /** Strip parens and empty blocks around the body of `tree`. */
1024
+ def normalizePolyFunction (tree : PolyFunction )(using Context ): PolyFunction =
1025
+ def stripped (body : Tree ): Tree = body match
1026
+ case Parens (body1) =>
1027
+ stripped(body1)
1028
+ case Block (Nil , body1) =>
1029
+ stripped(body1)
1030
+ case _ => body
1031
+ cpy.PolyFunction (tree)(tree.targs, stripped(tree.body)).asInstanceOf [PolyFunction ]
1032
+
1033
+ /** Desugar [T_1, ..., T_M] => (P_1, ..., P_N) => R
1034
+ * Into scala.PolyFunction { def apply[T_1, ..., T_M](x$1: P_1, ..., x$N: P_N): R }
1035
+ */
1036
+ def makePolyFunctionType (tree : PolyFunction )(using Context ): RefinedTypeTree =
1037
+ val PolyFunction (tparams : List [untpd.TypeDef ] @ unchecked, fun @ untpd.Function (vparamTypes, res)) = tree : @ unchecked
1038
+ val funFlags = fun match
1039
+ case fun : FunctionWithMods =>
1040
+ fun.mods.flags
1041
+ case _ => EmptyFlags
1042
+
1043
+ // TODO: make use of this in the desugaring when pureFuns is enabled.
1044
+ // val isImpure = funFlags.is(Impure)
1045
+
1046
+ // Function flags to be propagated to each parameter in the desugared method type.
1047
+ val paramFlags = funFlags.toTermFlags & Given
1048
+ val vparams = vparamTypes.zipWithIndex.map:
1049
+ case (p : ValDef , _) => p.withAddedFlags(paramFlags)
1050
+ case (p, n) => makeSyntheticParameter(n + 1 , p).withAddedFlags(paramFlags)
1051
+
1052
+ RefinedTypeTree (ref(defn.PolyFunctionType ), List (
1053
+ DefDef (nme.apply, tparams :: vparams :: Nil , res, EmptyTree ).withFlags(Synthetic )
1054
+ )).withSpan(tree.span)
1055
+ end makePolyFunctionType
1056
+
1023
1057
/** Invent a name for an anonympus given of type or template `impl`. */
1024
1058
def inventGivenOrExtensionName (impl : Tree )(using Context ): SimpleName =
1025
1059
val str = impl match
@@ -1413,14 +1447,17 @@ object desugar {
1413
1447
}
1414
1448
1415
1449
/** Make closure corresponding to function.
1416
- * params => body
1450
+ * [tparams] => params => body
1417
1451
* ==>
1418
- * def $anonfun(params) = body
1452
+ * def $anonfun[tparams] (params) = body
1419
1453
* Closure($anonfun)
1420
1454
*/
1421
- def makeClosure (params : List [ValDef ], body : Tree , tpt : Tree | Null = null , span : Span )(using Context ): Block =
1455
+ def makeClosure (tparams : List [TypeDef ], vparams : List [ValDef ], body : Tree , tpt : Tree | Null = null , span : Span )(using Context ): Block =
1456
+ val paramss : List [ParamClause ] =
1457
+ if tparams.isEmpty then vparams :: Nil
1458
+ else tparams :: vparams :: Nil
1422
1459
Block (
1423
- DefDef (nme.ANON_FUN , params :: Nil , if (tpt == null ) TypeTree () else tpt, body)
1460
+ DefDef (nme.ANON_FUN , paramss , if (tpt == null ) TypeTree () else tpt, body)
1424
1461
.withSpan(span)
1425
1462
.withMods(synthetic | Artifact ),
1426
1463
Closure (Nil , Ident (nme.ANON_FUN ), EmptyTree ))
@@ -1712,56 +1749,6 @@ object desugar {
1712
1749
}
1713
1750
}
1714
1751
1715
- def makePolyFunction (targs : List [Tree ], body : Tree , pt : Type ): Tree = body match {
1716
- case Parens (body1) =>
1717
- makePolyFunction(targs, body1, pt)
1718
- case Block (Nil , body1) =>
1719
- makePolyFunction(targs, body1, pt)
1720
- case Function (vargs, res) =>
1721
- assert(targs.nonEmpty)
1722
- // TODO: Figure out if we need a `PolyFunctionWithMods` instead.
1723
- val mods = body match {
1724
- case body : FunctionWithMods => body.mods
1725
- case _ => untpd.EmptyModifiers
1726
- }
1727
- val polyFunctionTpt = ref(defn.PolyFunctionType )
1728
- val applyTParams = targs.asInstanceOf [List [TypeDef ]]
1729
- if (ctx.mode.is(Mode .Type )) {
1730
- // Desugar [T_1, ..., T_M] -> (P_1, ..., P_N) => R
1731
- // Into scala.PolyFunction { def apply[T_1, ..., T_M](x$1: P_1, ..., x$N: P_N): R }
1732
-
1733
- val applyVParams = vargs.zipWithIndex.map {
1734
- case (p : ValDef , _) => p.withAddedFlags(mods.flags)
1735
- case (p, n) => makeSyntheticParameter(n + 1 , p).withAddedFlags(mods.flags.toTermFlags)
1736
- }
1737
- RefinedTypeTree (polyFunctionTpt, List (
1738
- DefDef (nme.apply, applyTParams :: applyVParams :: Nil , res, EmptyTree ).withFlags(Synthetic )
1739
- ))
1740
- }
1741
- else {
1742
- // Desugar [T_1, ..., T_M] -> (x_1: P_1, ..., x_N: P_N) => body
1743
- // with pt [S_1, ..., S_M] -> (O_1, ..., O_N) => R
1744
- // Into new scala.PolyFunction { def apply[T_1, ..., T_M](x_1: P_1, ..., x_N: P_N): R2 = body }
1745
- // where R2 is R, with all references to S_1..S_M replaced with T1..T_M.
1746
-
1747
- def typeTree (tp : Type ) = tp match
1748
- case RefinedType (parent, nme.apply, poly @ PolyType (_, mt : MethodType )) if parent.classSymbol eq defn.PolyFunctionClass =>
1749
- untpd.DependentTypeTree ((tsyms, vsyms) =>
1750
- mt.resultType.substParams(mt, vsyms.map(_.termRef)).substParams(poly, tsyms.map(_.typeRef)))
1751
- case _ => TypeTree ()
1752
-
1753
- val applyVParams = vargs.asInstanceOf [List [ValDef ]]
1754
- .map(varg => varg.withAddedFlags(mods.flags | Param ))
1755
- New (Template (emptyConstructor, List (polyFunctionTpt), Nil , EmptyValDef ,
1756
- List (DefDef (nme.apply, applyTParams :: applyVParams :: Nil , typeTree(pt), res))
1757
- ))
1758
- }
1759
- case _ =>
1760
- // may happen for erroneous input. An error will already have been reported.
1761
- assert(ctx.reporter.errorsReported)
1762
- EmptyTree
1763
- }
1764
-
1765
1752
// begin desugar
1766
1753
1767
1754
// Special case for `Parens` desugaring: unlike all the desugarings below,
@@ -1774,8 +1761,6 @@ object desugar {
1774
1761
}
1775
1762
1776
1763
val desugared = tree match {
1777
- case PolyFunction (targs, body) =>
1778
- makePolyFunction(targs, body, pt) orElse tree
1779
1764
case SymbolLit (str) =>
1780
1765
Apply (
1781
1766
ref(defn.ScalaSymbolClass .companionModule.termRef),
0 commit comments