@@ -1036,6 +1036,40 @@ object desugar {
1036
1036
name
1037
1037
}
1038
1038
1039
+ /** Strip parens and empty blocks around the body of `tree`. */
1040
+ def normalizePolyFunction (tree : PolyFunction )(using Context ): PolyFunction =
1041
+ def stripped (body : Tree ): Tree = body match
1042
+ case Parens (body1) =>
1043
+ stripped(body1)
1044
+ case Block (Nil , body1) =>
1045
+ stripped(body1)
1046
+ case _ => body
1047
+ cpy.PolyFunction (tree)(tree.targs, stripped(tree.body)).asInstanceOf [PolyFunction ]
1048
+
1049
+ /** Desugar [T_1, ..., T_M] => (P_1, ..., P_N) => R
1050
+ * Into scala.PolyFunction { def apply[T_1, ..., T_M](x$1: P_1, ..., x$N: P_N): R }
1051
+ */
1052
+ def makePolyFunctionType (tree : PolyFunction )(using Context ): RefinedTypeTree =
1053
+ val PolyFunction (tparams : List [untpd.TypeDef ] @ unchecked, fun @ untpd.Function (vparamTypes, res)) = tree : @ unchecked
1054
+ val funFlags = fun match
1055
+ case fun : FunctionWithMods =>
1056
+ fun.mods.flags
1057
+ case _ => EmptyFlags
1058
+
1059
+ // TODO: make use of this in the desugaring when pureFuns is enabled.
1060
+ // val isImpure = funFlags.is(Impure)
1061
+
1062
+ // Function flags to be propagated to each parameter in the desugared method type.
1063
+ val paramFlags = funFlags.toTermFlags & Given
1064
+ val vparams = vparamTypes.zipWithIndex.map:
1065
+ case (p : ValDef , _) => p.withAddedFlags(paramFlags)
1066
+ case (p, n) => makeSyntheticParameter(n + 1 , p).withAddedFlags(paramFlags)
1067
+
1068
+ RefinedTypeTree (ref(defn.PolyFunctionType ), List (
1069
+ DefDef (nme.apply, tparams :: vparams :: Nil , res, EmptyTree ).withFlags(Synthetic )
1070
+ )).withSpan(tree.span)
1071
+ end makePolyFunctionType
1072
+
1039
1073
/** Invent a name for an anonympus given of type or template `impl`. */
1040
1074
def inventGivenOrExtensionName (impl : Tree )(using Context ): SimpleName =
1041
1075
val str = impl match
@@ -1429,14 +1463,17 @@ object desugar {
1429
1463
}
1430
1464
1431
1465
/** Make closure corresponding to function.
1432
- * params => body
1466
+ * [tparams] => params => body
1433
1467
* ==>
1434
- * def $anonfun(params) = body
1468
+ * def $anonfun[tparams] (params) = body
1435
1469
* Closure($anonfun)
1436
1470
*/
1437
- def makeClosure (params : List [ValDef ], body : Tree , tpt : Tree | Null = null , span : Span )(using Context ): Block =
1471
+ def makeClosure (tparams : List [TypeDef ], vparams : List [ValDef ], body : Tree , tpt : Tree | Null = null , span : Span )(using Context ): Block =
1472
+ val paramss : List [ParamClause ] =
1473
+ if tparams.isEmpty then vparams :: Nil
1474
+ else tparams :: vparams :: Nil
1438
1475
Block (
1439
- DefDef (nme.ANON_FUN , params :: Nil , if (tpt == null ) TypeTree () else tpt, body)
1476
+ DefDef (nme.ANON_FUN , paramss , if (tpt == null ) TypeTree () else tpt, body)
1440
1477
.withSpan(span)
1441
1478
.withMods(synthetic | Artifact ),
1442
1479
Closure (Nil , Ident (nme.ANON_FUN ), EmptyTree ))
@@ -1728,56 +1765,6 @@ object desugar {
1728
1765
}
1729
1766
}
1730
1767
1731
- def makePolyFunction (targs : List [Tree ], body : Tree , pt : Type ): Tree = body match {
1732
- case Parens (body1) =>
1733
- makePolyFunction(targs, body1, pt)
1734
- case Block (Nil , body1) =>
1735
- makePolyFunction(targs, body1, pt)
1736
- case Function (vargs, res) =>
1737
- assert(targs.nonEmpty)
1738
- // TODO: Figure out if we need a `PolyFunctionWithMods` instead.
1739
- val mods = body match {
1740
- case body : FunctionWithMods => body.mods
1741
- case _ => untpd.EmptyModifiers
1742
- }
1743
- val polyFunctionTpt = ref(defn.PolyFunctionType )
1744
- val applyTParams = targs.asInstanceOf [List [TypeDef ]]
1745
- if (ctx.mode.is(Mode .Type )) {
1746
- // Desugar [T_1, ..., T_M] -> (P_1, ..., P_N) => R
1747
- // Into scala.PolyFunction { def apply[T_1, ..., T_M](x$1: P_1, ..., x$N: P_N): R }
1748
-
1749
- val applyVParams = vargs.zipWithIndex.map {
1750
- case (p : ValDef , _) => p.withAddedFlags(mods.flags)
1751
- case (p, n) => makeSyntheticParameter(n + 1 , p).withAddedFlags(mods.flags.toTermFlags)
1752
- }
1753
- RefinedTypeTree (polyFunctionTpt, List (
1754
- DefDef (nme.apply, applyTParams :: applyVParams :: Nil , res, EmptyTree ).withFlags(Synthetic )
1755
- ))
1756
- }
1757
- else {
1758
- // Desugar [T_1, ..., T_M] -> (x_1: P_1, ..., x_N: P_N) => body
1759
- // with pt [S_1, ..., S_M] -> (O_1, ..., O_N) => R
1760
- // Into new scala.PolyFunction { def apply[T_1, ..., T_M](x_1: P_1, ..., x_N: P_N): R2 = body }
1761
- // where R2 is R, with all references to S_1..S_M replaced with T1..T_M.
1762
-
1763
- def typeTree (tp : Type ) = tp match
1764
- case RefinedType (parent, nme.apply, poly @ PolyType (_, mt : MethodType )) if parent.classSymbol eq defn.PolyFunctionClass =>
1765
- untpd.DependentTypeTree ((tsyms, vsyms) =>
1766
- mt.resultType.substParams(mt, vsyms.map(_.termRef)).substParams(poly, tsyms.map(_.typeRef)))
1767
- case _ => TypeTree ()
1768
-
1769
- val applyVParams = vargs.asInstanceOf [List [ValDef ]]
1770
- .map(varg => varg.withAddedFlags(mods.flags | Param ))
1771
- New (Template (emptyConstructor, List (polyFunctionTpt), Nil , EmptyValDef ,
1772
- List (DefDef (nme.apply, applyTParams :: applyVParams :: Nil , typeTree(pt), res))
1773
- ))
1774
- }
1775
- case _ =>
1776
- // may happen for erroneous input. An error will already have been reported.
1777
- assert(ctx.reporter.errorsReported)
1778
- EmptyTree
1779
- }
1780
-
1781
1768
// begin desugar
1782
1769
1783
1770
// Special case for `Parens` desugaring: unlike all the desugarings below,
@@ -1790,8 +1777,6 @@ object desugar {
1790
1777
}
1791
1778
1792
1779
val desugared = tree match {
1793
- case PolyFunction (targs, body) =>
1794
- makePolyFunction(targs, body, pt) orElse tree
1795
1780
case SymbolLit (str) =>
1796
1781
Apply (
1797
1782
ref(defn.ScalaSymbolClass .companionModule.termRef),
0 commit comments